| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Copyright 2018 Google Inc. All rights reserved. | 
					
						
							|  |  |  |  * Modifications copyright (c) Microsoft Corporation. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *     http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-08-19 21:32:12 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-26 10:59:27 -07:00
										 |  |  | import { it, expect } from './fixtures'; | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should work with css selector', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<section id="testAttribute">43543</section>'); | 
					
						
							|  |  |  |   const idAttribute = await page.$eval('css=section', e => e.id); | 
					
						
							|  |  |  |   expect(idAttribute).toBe('testAttribute'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should work with id selector', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<section id="testAttribute">43543</section>'); | 
					
						
							|  |  |  |   const idAttribute = await page.$eval('id=testAttribute', e => e.id); | 
					
						
							|  |  |  |   expect(idAttribute).toBe('testAttribute'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should work with data-test selector', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<section data-test=foo id="testAttribute">43543</section>'); | 
					
						
							|  |  |  |   const idAttribute = await page.$eval('data-test=foo', e => e.id); | 
					
						
							|  |  |  |   expect(idAttribute).toBe('testAttribute'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should work with data-testid selector', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<section data-testid=foo id="testAttribute">43543</section>'); | 
					
						
							|  |  |  |   const idAttribute = await page.$eval('data-testid=foo', e => e.id); | 
					
						
							|  |  |  |   expect(idAttribute).toBe('testAttribute'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should work with data-test-id selector', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<section data-test-id=foo id="testAttribute">43543</section>'); | 
					
						
							|  |  |  |   const idAttribute = await page.$eval('data-test-id=foo', e => e.id); | 
					
						
							|  |  |  |   expect(idAttribute).toBe('testAttribute'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should work with text selector', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<section id="testAttribute">43543</section>'); | 
					
						
							|  |  |  |   const idAttribute = await page.$eval('text="43543"', e => e.id); | 
					
						
							|  |  |  |   expect(idAttribute).toBe('testAttribute'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should work with xpath selector', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<section id="testAttribute">43543</section>'); | 
					
						
							|  |  |  |   const idAttribute = await page.$eval('xpath=/html/body/section', e => e.id); | 
					
						
							|  |  |  |   expect(idAttribute).toBe('testAttribute'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should work with text selector', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<section id="testAttribute">43543</section>'); | 
					
						
							|  |  |  |   const idAttribute = await page.$eval('text=43543', e => e.id); | 
					
						
							|  |  |  |   expect(idAttribute).toBe('testAttribute'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should auto-detect css selector', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<section id="testAttribute">43543</section>'); | 
					
						
							|  |  |  |   const idAttribute = await page.$eval('section', e => e.id); | 
					
						
							|  |  |  |   expect(idAttribute).toBe('testAttribute'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should auto-detect css selector with attributes', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<section id="testAttribute">43543</section>'); | 
					
						
							|  |  |  |   const idAttribute = await page.$eval('section[id="testAttribute"]', e => e.id); | 
					
						
							|  |  |  |   expect(idAttribute).toBe('testAttribute'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should auto-detect nested selectors', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<div foo=bar><section>43543<span>Hello<div id=target></div></span></section></div>'); | 
					
						
							|  |  |  |   const idAttribute = await page.$eval('div[foo=bar] > section >> "Hello" >> div', e => e.id); | 
					
						
							|  |  |  |   expect(idAttribute).toBe('target'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should accept arguments', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<section>hello</section>'); | 
					
						
							|  |  |  |   const text = await page.$eval('section', (e, suffix) => e.textContent + suffix, ' world!'); | 
					
						
							|  |  |  |   expect(text).toBe('hello world!'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should accept ElementHandles as arguments', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<section>hello</section><div> world</div>'); | 
					
						
							|  |  |  |   const divHandle = await page.$('div'); | 
					
						
							|  |  |  |   const text = await page.$eval('section', (e, div) => e.textContent + div.textContent, divHandle); | 
					
						
							|  |  |  |   expect(text).toBe('hello world'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should throw error if no element is found', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   let error = null; | 
					
						
							|  |  |  |   await page.$eval('section', e => e.id).catch(e => error = e); | 
					
						
							|  |  |  |   expect(error.message).toContain('failed to find element matching selector "section"'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should support >> syntax', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<section><div>hello</div></section>'); | 
					
						
							|  |  |  |   const text = await page.$eval('css=section >> css=div', (e, suffix) => e.textContent + suffix, ' world!'); | 
					
						
							|  |  |  |   expect(text).toBe('hello world!'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should support >> syntax with different engines', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<section><div><span>hello</span></div></section>'); | 
					
						
							|  |  |  |   const text = await page.$eval('xpath=/html/body/section >> css=div >> text="hello"', (e, suffix) => e.textContent + suffix, ' world!'); | 
					
						
							|  |  |  |   expect(text).toBe('hello world!'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should support spaces with >> syntax', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.goto(server.PREFIX + '/deep-shadow.html'); | 
					
						
							|  |  |  |   const text = await page.$eval(' css = div >>css=div>>css   = span  ', e => e.textContent); | 
					
						
							|  |  |  |   expect(text).toBe('Hello from root2'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should not stop at first failure with >> syntax', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<div><span>Next</span><button>Previous</button><button>Next</button></div>'); | 
					
						
							|  |  |  |   const html = await page.$eval('button >> "Next"', e => e.outerHTML); | 
					
						
							|  |  |  |   expect(html).toBe('<button>Next</button>'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should support * capture', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<section><div><span>a</span></div></section><section><div><span>b</span></div></section>'); | 
					
						
							|  |  |  |   expect(await page.$eval('*css=div >> "b"', e => e.outerHTML)).toBe('<div><span>b</span></div>'); | 
					
						
							|  |  |  |   expect(await page.$eval('section >> *css=div >> "b"', e => e.outerHTML)).toBe('<div><span>b</span></div>'); | 
					
						
							|  |  |  |   expect(await page.$eval('css=div >> *text="b"', e => e.outerHTML)).toBe('<span>b</span>'); | 
					
						
							|  |  |  |   expect(await page.$('*')).toBeTruthy(); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should throw on multiple * captures', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const error = await page.$eval('*css=div >> *css=span', e => e.outerHTML).catch(e => e); | 
					
						
							|  |  |  |   expect(error.message).toContain('Only one of the selectors can capture using * modifier'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should throw on malformed * capture', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const error = await page.$eval('*=div', e => e.outerHTML).catch(e => e); | 
					
						
							|  |  |  |   expect(error.message).toContain('Unknown engine "" while parsing selector *=div'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should work with spaces in css attributes', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<div><input placeholder="Select date"></div>'); | 
					
						
							|  |  |  |   expect(await page.waitForSelector(`[placeholder="Select date"]`)).toBeTruthy(); | 
					
						
							|  |  |  |   expect(await page.waitForSelector(`[placeholder='Select date']`)).toBeTruthy(); | 
					
						
							|  |  |  |   expect(await page.waitForSelector(`input[placeholder="Select date"]`)).toBeTruthy(); | 
					
						
							|  |  |  |   expect(await page.waitForSelector(`input[placeholder='Select date']`)).toBeTruthy(); | 
					
						
							|  |  |  |   expect(await page.$(`[placeholder="Select date"]`)).toBeTruthy(); | 
					
						
							|  |  |  |   expect(await page.$(`[placeholder='Select date']`)).toBeTruthy(); | 
					
						
							|  |  |  |   expect(await page.$(`input[placeholder="Select date"]`)).toBeTruthy(); | 
					
						
							|  |  |  |   expect(await page.$(`input[placeholder='Select date']`)).toBeTruthy(); | 
					
						
							|  |  |  |   expect(await page.$eval(`[placeholder="Select date"]`, e => e.outerHTML)).toBe('<input placeholder="Select date">'); | 
					
						
							|  |  |  |   expect(await page.$eval(`[placeholder='Select date']`, e => e.outerHTML)).toBe('<input placeholder="Select date">'); | 
					
						
							|  |  |  |   expect(await page.$eval(`input[placeholder="Select date"]`, e => e.outerHTML)).toBe('<input placeholder="Select date">'); | 
					
						
							|  |  |  |   expect(await page.$eval(`input[placeholder='Select date']`, e => e.outerHTML)).toBe('<input placeholder="Select date">'); | 
					
						
							|  |  |  |   expect(await page.$eval(`css=[placeholder="Select date"]`, e => e.outerHTML)).toBe('<input placeholder="Select date">'); | 
					
						
							|  |  |  |   expect(await page.$eval(`css=[placeholder='Select date']`, e => e.outerHTML)).toBe('<input placeholder="Select date">'); | 
					
						
							|  |  |  |   expect(await page.$eval(`css=input[placeholder="Select date"]`, e => e.outerHTML)).toBe('<input placeholder="Select date">'); | 
					
						
							|  |  |  |   expect(await page.$eval(`css=input[placeholder='Select date']`, e => e.outerHTML)).toBe('<input placeholder="Select date">'); | 
					
						
							|  |  |  |   expect(await page.$eval(`div >> [placeholder="Select date"]`, e => e.outerHTML)).toBe('<input placeholder="Select date">'); | 
					
						
							|  |  |  |   expect(await page.$eval(`div >> [placeholder='Select date']`, e => e.outerHTML)).toBe('<input placeholder="Select date">'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should work with quotes in css attributes', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<div><input placeholder="Select"date"></div>'); | 
					
						
							|  |  |  |   expect(await page.$(`[placeholder="Select\\"date"]`)).toBeTruthy(); | 
					
						
							|  |  |  |   expect(await page.$(`[placeholder='Select"date']`)).toBeTruthy(); | 
					
						
							|  |  |  |   await page.setContent('<div><input placeholder="Select " date"></div>'); | 
					
						
							|  |  |  |   expect(await page.$(`[placeholder="Select \\" date"]`)).toBeTruthy(); | 
					
						
							|  |  |  |   expect(await page.$(`[placeholder='Select " date']`)).toBeTruthy(); | 
					
						
							|  |  |  |   await page.setContent('<div><input placeholder="Select'date"></div>'); | 
					
						
							|  |  |  |   expect(await page.$(`[placeholder="Select'date"]`)).toBeTruthy(); | 
					
						
							|  |  |  |   expect(await page.$(`[placeholder='Select\\'date']`)).toBeTruthy(); | 
					
						
							|  |  |  |   await page.setContent('<div><input placeholder="Select ' date"></div>'); | 
					
						
							|  |  |  |   expect(await page.$(`[placeholder="Select ' date"]`)).toBeTruthy(); | 
					
						
							|  |  |  |   expect(await page.$(`[placeholder='Select \\' date']`)).toBeTruthy(); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should work with spaces in css attributes when missing', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const inputPromise = page.waitForSelector(`[placeholder="Select date"]`); | 
					
						
							|  |  |  |   expect(await page.$(`[placeholder="Select date"]`)).toBe(null); | 
					
						
							|  |  |  |   await page.setContent('<div><input placeholder="Select date"></div>'); | 
					
						
							|  |  |  |   await inputPromise; | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should work with quotes in css attributes when missing', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const inputPromise = page.waitForSelector(`[placeholder="Select\\"date"]`); | 
					
						
							|  |  |  |   expect(await page.$(`[placeholder="Select\\"date"]`)).toBe(null); | 
					
						
							|  |  |  |   await page.setContent('<div><input placeholder="Select"date"></div>'); | 
					
						
							|  |  |  |   await inputPromise; | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should return complex values', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<section id="testAttribute">43543</section>'); | 
					
						
							|  |  |  |   const idAttribute = await page.$eval('css=section', e => [{ id: e.id }]); | 
					
						
							|  |  |  |   expect(idAttribute).toEqual([{ id: 'testAttribute' }]); | 
					
						
							|  |  |  | }); |