2022-10-12 03:50:41 +03:00
/ * *
* Copyright ( c ) Microsoft Corporation . All rights reserved .
*
* 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 .
* /
import { contextTest as it , expect } from '../config/browserTest' ;
2023-05-16 05:42:51 +03:00
import { asLocator , asLocators } from '../../packages/playwright-core/lib/utils/isomorphic/locatorGenerators' ;
2023-03-07 05:49:14 +03:00
import { locatorOrSelectorAsSelector as parseLocator } from '../../packages/playwright-core/lib/utils/isomorphic/locatorParser' ;
2022-11-09 04:08:08 +03:00
import type { Page , Frame , Locator , FrameLocator } from 'playwright-core' ;
2022-10-12 03:50:41 +03:00
2022-11-04 01:17:08 +03:00
it . skip ( ( { mode } ) = > mode !== 'default' ) ;
2022-11-09 04:08:08 +03:00
function generate ( locator : Locator | FrameLocator ) {
return generateForSelector ( ( locator as any ) . _selector || ( locator as any ) . _frameSelector ) ;
2022-10-31 22:55:35 +03:00
}
function generateForSelector ( selector : string ) {
2022-10-12 03:50:41 +03:00
const result : any = { } ;
2022-10-31 22:55:35 +03:00
for ( const lang of [ 'javascript' , 'python' , 'java' , 'csharp' ] ) {
const locatorString = asLocator ( lang , selector , false ) ;
2022-11-08 23:04:43 +03:00
expect . soft ( parseLocator ( lang , locatorString , 'data-testid' ) , lang + ' mismatch' ) . toBe ( selector ) ;
2022-10-31 22:55:35 +03:00
result [ lang ] = locatorString ;
}
2022-10-12 03:50:41 +03:00
return result ;
}
2022-10-18 23:09:54 +03:00
async function generateForNode ( pageOrFrame : Page | Frame , target : string ) : Promise < string > {
const selector = await pageOrFrame . locator ( target ) . evaluate ( e = > ( window as any ) . playwright . selector ( e ) ) ;
const result : any = { } ;
2022-10-31 22:55:35 +03:00
for ( const lang of [ 'javascript' , 'python' , 'java' , 'csharp' ] ) {
const locatorString = asLocator ( lang , selector , false ) ;
2022-11-04 01:17:08 +03:00
expect . soft ( parseLocator ( lang , locatorString ) ) . toBe ( selector ) ;
2022-10-31 22:55:35 +03:00
result [ lang ] = locatorString ;
}
2022-10-18 23:09:54 +03:00
return result ;
}
2022-10-12 03:50:41 +03:00
it ( 'reverse engineer locators' , async ( { page } ) = > {
expect . soft ( generate ( page . getByTestId ( 'Hello' ) ) ) . toEqual ( {
javascript : "getByTestId('Hello')" ,
python : 'get_by_test_id("Hello")' ,
java : 'getByTestId("Hello")' ,
csharp : 'GetByTestId("Hello")'
} ) ;
expect . soft ( generate ( page . getByTestId ( 'He"llo' ) ) ) . toEqual ( {
javascript : 'getByTestId(\'He"llo\')' ,
2022-10-31 22:55:35 +03:00
python : 'get_by_test_id("He\\"llo")' ,
java : 'getByTestId("He\\"llo")' ,
csharp : 'GetByTestId("He\\"llo")'
2022-10-12 03:50:41 +03:00
} ) ;
2023-05-30 18:45:48 +03:00
expect . soft ( generate ( page . getByTestId ( /He"llo/ ) ) ) . toEqual ( {
javascript : 'getByTestId(/He"llo/)' ,
python : 'get_by_test_id(re.compile(r"He\\"llo"))' ,
java : 'getByTestId(Pattern.compile("He\\"llo"))' ,
csharp : 'GetByTestId(new Regex("He\\"llo"))'
} ) ;
2022-10-12 03:50:41 +03:00
expect . soft ( generate ( page . getByText ( 'Hello' , { exact : true } ) ) ) . toEqual ( {
2022-11-09 08:48:01 +03:00
csharp : 'GetByText("Hello", new() { Exact = true })' ,
2022-10-31 22:55:35 +03:00
java : 'getByText("Hello", new Page.GetByTextOptions().setExact(true))' ,
2022-10-12 03:50:41 +03:00
javascript : 'getByText(\'Hello\', { exact: true })' ,
2022-11-09 04:08:08 +03:00
python : 'get_by_text("Hello", exact=True)' ,
2022-10-12 03:50:41 +03:00
} ) ;
expect . soft ( generate ( page . getByText ( 'Hello' ) ) ) . toEqual ( {
csharp : 'GetByText("Hello")' ,
java : 'getByText("Hello")' ,
javascript : 'getByText(\'Hello\')' ,
python : 'get_by_text("Hello")' ,
} ) ;
expect . soft ( generate ( page . getByText ( /Hello/ ) ) ) . toEqual ( {
csharp : 'GetByText(new Regex("Hello"))' ,
java : 'getByText(Pattern.compile("Hello"))' ,
javascript : 'getByText(/Hello/)' ,
python : 'get_by_text(re.compile(r"Hello"))' ,
} ) ;
expect . soft ( generate ( page . getByLabel ( 'Name' ) ) ) . toEqual ( {
csharp : 'GetByLabel("Name")' ,
java : 'getByLabel("Name")' ,
javascript : 'getByLabel(\'Name\')' ,
python : 'get_by_label("Name")' ,
} ) ;
expect . soft ( generate ( page . getByLabel ( 'Last Name' , { exact : true } ) ) ) . toEqual ( {
2022-11-09 08:48:01 +03:00
csharp : 'GetByLabel("Last Name", new() { Exact = true })' ,
2022-10-31 22:55:35 +03:00
java : 'getByLabel("Last Name", new Page.GetByLabelOptions().setExact(true))' ,
2022-10-12 03:50:41 +03:00
javascript : 'getByLabel(\'Last Name\', { exact: true })' ,
2022-11-09 04:08:08 +03:00
python : 'get_by_label("Last Name", exact=True)' ,
2022-10-12 03:50:41 +03:00
} ) ;
expect . soft ( generate ( page . getByLabel ( /Last\s+name/i ) ) ) . toEqual ( {
csharp : 'GetByLabel(new Regex("Last\\\\s+name", RegexOptions.IgnoreCase))' ,
java : 'getByLabel(Pattern.compile("Last\\\\s+name", Pattern.CASE_INSENSITIVE))' ,
javascript : 'getByLabel(/Last\\s+name/i)' ,
2022-10-31 22:55:35 +03:00
python : 'get_by_label(re.compile(r"Last\\s+name", re.IGNORECASE))' ,
2022-10-12 03:50:41 +03:00
} ) ;
expect . soft ( generate ( page . getByPlaceholder ( 'hello' ) ) ) . toEqual ( {
csharp : 'GetByPlaceholder("hello")' ,
java : 'getByPlaceholder("hello")' ,
javascript : 'getByPlaceholder(\'hello\')' ,
python : 'get_by_placeholder("hello")' ,
} ) ;
expect . soft ( generate ( page . getByPlaceholder ( 'Hello' , { exact : true } ) ) ) . toEqual ( {
2022-11-09 08:48:01 +03:00
csharp : 'GetByPlaceholder("Hello", new() { Exact = true })' ,
2022-10-31 22:55:35 +03:00
java : 'getByPlaceholder("Hello", new Page.GetByPlaceholderOptions().setExact(true))' ,
2022-10-12 03:50:41 +03:00
javascript : 'getByPlaceholder(\'Hello\', { exact: true })' ,
2022-11-09 04:08:08 +03:00
python : 'get_by_placeholder("Hello", exact=True)' ,
2022-10-12 03:50:41 +03:00
} ) ;
expect . soft ( generate ( page . getByPlaceholder ( /wor/i ) ) ) . toEqual ( {
csharp : 'GetByPlaceholder(new Regex("wor", RegexOptions.IgnoreCase))' ,
java : 'getByPlaceholder(Pattern.compile("wor", Pattern.CASE_INSENSITIVE))' ,
javascript : 'getByPlaceholder(/wor/i)' ,
python : 'get_by_placeholder(re.compile(r"wor", re.IGNORECASE))' ,
} ) ;
expect . soft ( generate ( page . getByAltText ( 'hello' ) ) ) . toEqual ( {
csharp : 'GetByAltText("hello")' ,
java : 'getByAltText("hello")' ,
javascript : 'getByAltText(\'hello\')' ,
python : 'get_by_alt_text("hello")' ,
} ) ;
expect . soft ( generate ( page . getByAltText ( 'Hello' , { exact : true } ) ) ) . toEqual ( {
2022-11-09 08:48:01 +03:00
csharp : 'GetByAltText("Hello", new() { Exact = true })' ,
2022-10-31 22:55:35 +03:00
java : 'getByAltText("Hello", new Page.GetByAltTextOptions().setExact(true))' ,
2022-10-12 03:50:41 +03:00
javascript : 'getByAltText(\'Hello\', { exact: true })' ,
2022-11-09 04:08:08 +03:00
python : 'get_by_alt_text("Hello", exact=True)' ,
2022-10-12 03:50:41 +03:00
} ) ;
expect . soft ( generate ( page . getByAltText ( /wor/i ) ) ) . toEqual ( {
csharp : 'GetByAltText(new Regex("wor", RegexOptions.IgnoreCase))' ,
java : 'getByAltText(Pattern.compile("wor", Pattern.CASE_INSENSITIVE))' ,
javascript : 'getByAltText(/wor/i)' ,
python : 'get_by_alt_text(re.compile(r"wor", re.IGNORECASE))' ,
} ) ;
expect . soft ( generate ( page . getByTitle ( 'hello' ) ) ) . toEqual ( {
csharp : 'GetByTitle("hello")' ,
java : 'getByTitle("hello")' ,
javascript : 'getByTitle(\'hello\')' ,
python : 'get_by_title("hello")' ,
} ) ;
expect . soft ( generate ( page . getByTitle ( 'Hello' , { exact : true } ) ) ) . toEqual ( {
2022-11-09 08:48:01 +03:00
csharp : 'GetByTitle("Hello", new() { Exact = true })' ,
2022-10-31 22:55:35 +03:00
java : 'getByTitle("Hello", new Page.GetByTitleOptions().setExact(true))' ,
2022-10-12 03:50:41 +03:00
javascript : 'getByTitle(\'Hello\', { exact: true })' ,
2022-11-09 04:08:08 +03:00
python : 'get_by_title("Hello", exact=True)' ,
2022-10-12 03:50:41 +03:00
} ) ;
expect . soft ( generate ( page . getByTitle ( /wor/i ) ) ) . toEqual ( {
csharp : 'GetByTitle(new Regex("wor", RegexOptions.IgnoreCase))' ,
java : 'getByTitle(Pattern.compile("wor", Pattern.CASE_INSENSITIVE))' ,
javascript : 'getByTitle(/wor/i)' ,
python : 'get_by_title(re.compile(r"wor", re.IGNORECASE))' ,
} ) ;
2022-10-18 23:09:54 +03:00
expect . soft ( generate ( page . getByPlaceholder ( 'hello my\nwo"rld' ) ) ) . toEqual ( {
csharp : 'GetByPlaceholder("hello my\\nwo\\"rld")' ,
java : 'getByPlaceholder("hello my\\nwo\\"rld")' ,
javascript : 'getByPlaceholder(\'hello my\\nwo"rld\')' ,
python : 'get_by_placeholder("hello my\\nwo\\"rld")' ,
} ) ;
expect . soft ( generate ( page . getByAltText ( 'hello my\nwo"rld' ) ) ) . toEqual ( {
csharp : 'GetByAltText("hello my\\nwo\\"rld")' ,
java : 'getByAltText("hello my\\nwo\\"rld")' ,
javascript : 'getByAltText(\'hello my\\nwo"rld\')' ,
python : 'get_by_alt_text("hello my\\nwo\\"rld")' ,
} ) ;
expect . soft ( generate ( page . getByTitle ( 'hello my\nwo"rld' ) ) ) . toEqual ( {
csharp : 'GetByTitle("hello my\\nwo\\"rld")' ,
java : 'getByTitle("hello my\\nwo\\"rld")' ,
javascript : 'getByTitle(\'hello my\\nwo"rld\')' ,
python : 'get_by_title("hello my\\nwo\\"rld")' ,
} ) ;
} ) ;
2022-11-12 02:58:36 +03:00
it ( 'reverse engineer getByRole' , async ( { page } ) = > {
expect . soft ( generate ( page . getByRole ( 'button' ) ) ) . toEqual ( {
javascript : ` getByRole('button') ` ,
python : ` get_by_role("button") ` ,
java : ` getByRole(AriaRole.BUTTON) ` ,
csharp : ` GetByRole(AriaRole.Button) ` ,
} ) ;
expect . soft ( generate ( page . getByRole ( 'button' , { name : 'Hello' } ) ) ) . toEqual ( {
javascript : ` getByRole('button', { name: 'Hello' }) ` ,
python : ` get_by_role("button", name="Hello") ` ,
java : ` getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Hello")) ` ,
2022-11-30 07:56:18 +03:00
csharp : ` GetByRole(AriaRole.Button, new() { Name = "Hello" }) ` ,
2022-11-12 02:58:36 +03:00
} ) ;
expect . soft ( generate ( page . getByRole ( 'button' , { name : /Hello/ } ) ) ) . toEqual ( {
javascript : ` getByRole('button', { name: /Hello/ }) ` ,
python : ` get_by_role("button", name=re.compile(r"Hello")) ` ,
java : ` getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName(Pattern.compile("Hello"))) ` ,
csharp : ` GetByRole(AriaRole.Button, new() { NameRegex = new Regex("Hello") }) ` ,
} ) ;
expect . soft ( generate ( page . getByRole ( 'button' , { name : 'He"llo' , exact : true } ) ) ) . toEqual ( {
javascript : ` getByRole('button', { name: 'He"llo', exact: true }) ` ,
python : ` get_by_role("button", name="He \\ "llo", exact=True) ` ,
java : ` getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("He \\ "llo").setExact(true)) ` ,
2022-11-30 07:56:18 +03:00
csharp : ` GetByRole(AriaRole.Button, new() { Name = "He \\ "llo", Exact = true }) ` ,
2022-11-12 02:58:36 +03:00
} ) ;
expect . soft ( generate ( page . getByRole ( 'button' , { checked : true , pressed : false , level : 3 } ) ) ) . toEqual ( {
javascript : ` getByRole('button', { checked: true, level: 3, pressed: false }) ` ,
python : ` get_by_role("button", checked=True, level=3, pressed=False) ` ,
java : ` getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setChecked(true).setLevel(3).setPressed(false)) ` ,
csharp : ` GetByRole(AriaRole.Button, new() { Checked = true, Level = 3, Pressed = false }) ` ,
} ) ;
} ) ;
2022-10-18 23:09:54 +03:00
it ( 'reverse engineer ignore-case locators' , async ( { page } ) = > {
expect . soft ( generate ( page . getByText ( 'hello my\nwo"rld' ) ) ) . toEqual ( {
csharp : 'GetByText("hello my\\nwo\\"rld")' ,
java : 'getByText("hello my\\nwo\\"rld")' ,
javascript : 'getByText(\'hello my\\nwo"rld\')' ,
python : 'get_by_text("hello my\\nwo\\"rld")' ,
} ) ;
expect . soft ( generate ( page . getByText ( 'hello my wo"rld' ) ) ) . toEqual ( {
csharp : 'GetByText("hello my wo\\"rld")' ,
java : 'getByText("hello my wo\\"rld")' ,
javascript : 'getByText(\'hello my wo"rld\')' ,
python : 'get_by_text("hello my wo\\"rld")' ,
} ) ;
expect . soft ( generate ( page . getByLabel ( 'hello my\nwo"rld' ) ) ) . toEqual ( {
csharp : 'GetByLabel("hello my\\nwo\\"rld")' ,
java : 'getByLabel("hello my\\nwo\\"rld")' ,
javascript : 'getByLabel(\'hello my\\nwo"rld\')' ,
python : 'get_by_label("hello my\\nwo\\"rld")' ,
} ) ;
} ) ;
2022-10-12 03:50:41 +03:00
2022-10-31 22:55:35 +03:00
it ( 'reverse engineer ordered locators' , async ( { page } ) = > {
expect . soft ( generate ( page . locator ( 'div' ) . nth ( 3 ) . first ( ) . last ( ) ) ) . toEqual ( {
csharp : ` Locator( \ "div \ ").Nth(3).First.Last ` ,
java : ` locator( \ "div \ ").nth(3).first().last() ` ,
javascript : ` locator('div').nth(3).first().last() ` ,
python : ` locator( \ "div \ ").nth(3).first.last ` ,
} ) ;
} ) ;
it ( 'reverse engineer locators with regex' , async ( { page } ) = > {
expect . soft ( generate ( page . getByText ( /he\/\sl\nlo/ ) ) ) . toEqual ( {
csharp : ` GetByText(new Regex( \ "he \\ \\ / \\ \\ sl \\ \\ nlo \ ")) ` ,
java : ` getByText(Pattern.compile( \ "he \\ \\ / \\ \\ sl \\ \\ nlo \ ")) ` ,
javascript : ` getByText(/he \\ / \\ sl \\ nlo/) ` ,
python : ` get_by_text(re.compile(r"he/ \\ sl \\ nlo")) ` ,
} ) ;
expect . soft ( generate ( page . getByPlaceholder ( /he\/\sl\nlo/ ) ) ) . toEqual ( {
csharp : ` GetByPlaceholder(new Regex( \ "he \\ \\ / \\ \\ sl \\ \\ nlo \ ")) ` ,
java : ` getByPlaceholder(Pattern.compile( \ "he \\ \\ / \\ \\ sl \\ \\ nlo \ ")) ` ,
javascript : ` getByPlaceholder(/he \\ / \\ sl \\ nlo/) ` ,
python : ` get_by_placeholder(re.compile(r"he/ \\ sl \\ nlo")) ` ,
} ) ;
expect . soft ( generate ( page . getByText ( /hel"lo/ ) ) ) . toEqual ( {
csharp : ` GetByText(new Regex("hel \\ "lo")) ` ,
java : ` getByText(Pattern.compile("hel \\ "lo")) ` ,
javascript : ` getByText(/hel \ "lo/) ` ,
python : ` get_by_text(re.compile(r"hel \\ "lo")) ` ,
} ) ;
expect . soft ( generate ( page . getByPlaceholder ( /hel"lo/ ) ) ) . toEqual ( {
csharp : ` GetByPlaceholder(new Regex("hel \\ "lo")) ` ,
java : ` getByPlaceholder(Pattern.compile("hel \\ "lo")) ` ,
javascript : ` getByPlaceholder(/hel"lo/) ` ,
python : ` get_by_placeholder(re.compile(r"hel \\ "lo")) ` ,
} ) ;
} ) ;
it ( 'reverse engineer hasText' , async ( { page } ) = > {
expect . soft ( generate ( page . getByText ( 'Hello' ) . filter ( { hasText : 'wo"rld\n' } ) ) ) . toEqual ( {
2022-11-30 07:56:18 +03:00
csharp : ` GetByText("Hello").Filter(new() { HasText = "wo \\ "rld \\ n" }) ` ,
2022-12-28 20:13:06 +03:00
java : ` getByText("Hello").filter(new Locator.FilterOptions().setHasText("wo \\ "rld \\ n")) ` ,
2022-10-31 22:55:35 +03:00
javascript : ` getByText('Hello').filter({ hasText: 'wo"rld \\ n' }) ` ,
python : ` get_by_text("Hello").filter(has_text="wo \\ "rld \\ n") ` ,
} ) ;
expect . soft ( generate ( page . getByText ( 'Hello' ) . filter ( { hasText : /wo\/\srld\n/ } ) ) ) . toEqual ( {
2022-11-12 02:58:36 +03:00
csharp : ` GetByText("Hello").Filter(new() { HasTextRegex = new Regex("wo \\ \\ / \\ \\ srld \\ \\ n") }) ` ,
2022-12-28 20:13:06 +03:00
java : ` getByText("Hello").filter(new Locator.FilterOptions().setHasText(Pattern.compile("wo \\ \\ / \\ \\ srld \\ \\ n"))) ` ,
2022-10-31 22:55:35 +03:00
javascript : ` getByText('Hello').filter({ hasText: /wo \\ / \\ srld \\ n/ }) ` ,
python : ` get_by_text("Hello").filter(has_text=re.compile(r"wo/ \\ srld \\ n")) ` ,
} ) ;
expect . soft ( generate ( page . getByText ( 'Hello' ) . filter ( { hasText : /wor"ld/ } ) ) ) . toEqual ( {
2022-11-12 02:58:36 +03:00
csharp : ` GetByText("Hello").Filter(new() { HasTextRegex = new Regex("wor \\ "ld") }) ` ,
2022-12-28 20:13:06 +03:00
java : ` getByText("Hello").filter(new Locator.FilterOptions().setHasText(Pattern.compile("wor \\ "ld"))) ` ,
2022-10-31 22:55:35 +03:00
javascript : ` getByText('Hello').filter({ hasText: /wor"ld/ }) ` ,
python : ` get_by_text("Hello").filter(has_text=re.compile(r"wor \\ "ld")) ` ,
} ) ;
} ) ;
2023-04-06 00:13:28 +03:00
it ( 'reverse engineer hasNotText' , async ( { page } ) = > {
expect . soft ( generate ( page . getByText ( 'Hello' ) . filter ( { hasNotText : 'wo"rld\n' } ) ) ) . toEqual ( {
csharp : ` GetByText("Hello").Filter(new() { HasNotText = "wo \\ "rld \\ n" }) ` ,
java : ` getByText("Hello").filter(new Locator.FilterOptions().setHasNotText("wo \\ "rld \\ n")) ` ,
javascript : ` getByText('Hello').filter({ hasNotText: 'wo"rld \\ n' }) ` ,
python : ` get_by_text("Hello").filter(has_not_text="wo \\ "rld \\ n") ` ,
} ) ;
} ) ;
2022-11-08 19:47:02 +03:00
it ( 'reverse engineer has' , async ( { page } ) = > {
expect . soft ( generate ( page . getByText ( 'Hello' ) . filter ( { has : page.locator ( 'div' ) . getByText ( 'bye' ) } ) ) ) . toEqual ( {
2022-11-09 08:48:01 +03:00
csharp : ` GetByText("Hello").Filter(new() { Has = Locator("div").GetByText("bye") }) ` ,
2022-12-28 20:13:06 +03:00
java : ` getByText("Hello").filter(new Locator.FilterOptions().setHas(locator("div").getByText("bye"))) ` ,
2022-11-08 19:47:02 +03:00
javascript : ` getByText('Hello').filter({ has: locator('div').getByText('bye') }) ` ,
python : ` get_by_text("Hello").filter(has=locator("div").get_by_text("bye")) ` ,
} ) ;
const locator = page
. locator ( 'section' )
. filter ( { has : page.locator ( 'div' ) . filter ( { has : page.locator ( 'span' ) } ) } )
. filter ( { hasText : 'foo' } )
. filter ( { has : page.locator ( 'a' ) } ) ;
expect . soft ( generate ( locator ) ) . toEqual ( {
2022-11-30 07:56:18 +03:00
csharp : ` Locator("section").Filter(new() { Has = Locator("div").Filter(new() { Has = Locator("span") }) }).Filter(new() { HasText = "foo" }).Filter(new() { Has = Locator("a") }) ` ,
2022-12-28 20:13:06 +03:00
java : ` locator("section").filter(new Locator.FilterOptions().setHas(locator("div").filter(new Locator.FilterOptions().setHas(locator("span"))))).filter(new Locator.FilterOptions().setHasText("foo")).filter(new Locator.FilterOptions().setHas(locator("a"))) ` ,
2022-11-08 19:47:02 +03:00
javascript : ` locator('section').filter({ has: locator('div').filter({ has: locator('span') }) }).filter({ hasText: 'foo' }).filter({ has: locator('a') }) ` ,
python : ` locator("section").filter(has=locator("div").filter(has=locator("span"))).filter(has_text="foo").filter(has=locator("a")) ` ,
} ) ;
} ) ;
2023-04-05 22:45:46 +03:00
it ( 'reverse engineer hasNot' , async ( { page } ) = > {
expect . soft ( generate ( page . getByText ( 'Hello' ) . filter ( { hasNot : page.locator ( 'div' ) . getByText ( 'bye' ) } ) ) ) . toEqual ( {
csharp : ` GetByText("Hello").Filter(new() { HasNot = Locator("div").GetByText("bye") }) ` ,
java : ` getByText("Hello").filter(new Locator.FilterOptions().setHasNot(locator("div").getByText("bye"))) ` ,
javascript : ` getByText('Hello').filter({ hasNot: locator('div').getByText('bye') }) ` ,
python : ` get_by_text("Hello").filter(has_not=locator("div").get_by_text("bye")) ` ,
} ) ;
const locator = page
. locator ( 'section' )
. filter ( { has : page.locator ( 'div' ) . filter ( { hasNot : page.locator ( 'span' ) } ) } )
. filter ( { hasText : 'foo' } )
. filter ( { hasNot : page.locator ( 'a' ) } ) ;
expect . soft ( generate ( locator ) ) . toEqual ( {
csharp : ` Locator("section").Filter(new() { Has = Locator("div").Filter(new() { HasNot = Locator("span") }) }).Filter(new() { HasText = "foo" }).Filter(new() { HasNot = Locator("a") }) ` ,
java : ` locator("section").filter(new Locator.FilterOptions().setHas(locator("div").filter(new Locator.FilterOptions().setHasNot(locator("span"))))).filter(new Locator.FilterOptions().setHasText("foo")).filter(new Locator.FilterOptions().setHasNot(locator("a"))) ` ,
javascript : ` locator('section').filter({ has: locator('div').filter({ hasNot: locator('span') }) }).filter({ hasText: 'foo' }).filter({ hasNot: locator('a') }) ` ,
python : ` locator("section").filter(has=locator("div").filter(has_not=locator("span"))).filter(has_text="foo").filter(has_not=locator("a")) ` ,
} ) ;
} ) ;
2022-11-09 04:08:08 +03:00
it ( 'reverse engineer frameLocator' , async ( { page } ) = > {
const locator = page
. frameLocator ( 'iframe' )
. getByText ( 'foo' , { exact : true } )
2022-11-15 21:50:46 +03:00
. frameLocator ( 'frame' ) . first ( )
2022-11-09 04:08:08 +03:00
. frameLocator ( 'iframe' )
. locator ( 'span' ) ;
expect . soft ( generate ( locator ) ) . toEqual ( {
2022-11-15 21:50:46 +03:00
csharp : ` FrameLocator("iframe").GetByText("foo", new() { Exact = true }).FrameLocator("frame").First.FrameLocator("iframe").Locator("span") ` ,
java : ` frameLocator("iframe").getByText("foo", new FrameLocator.GetByTextOptions().setExact(true)).frameLocator("frame").first().frameLocator("iframe").locator("span") ` ,
javascript : ` frameLocator('iframe').getByText('foo', { exact: true }).frameLocator('frame').first().frameLocator('iframe').locator('span') ` ,
python : ` frame_locator("iframe").get_by_text("foo", exact=True).frame_locator("frame").first.frame_locator("iframe").locator("span") ` ,
2022-11-09 04:08:08 +03:00
} ) ;
// Note that frame locators with ">>" are not restored back due to ambiguity.
const selector = ( page . frameLocator ( 'div >> iframe' ) . locator ( 'span' ) as any ) . _selector ;
expect . soft ( asLocator ( 'javascript' , selector , false ) ) . toBe ( ` locator('div').frameLocator('iframe').locator('span') ` ) ;
} ) ;
2023-05-16 05:42:51 +03:00
it ( 'generate multiple locators' , async ( { page } ) = > {
const selector = ( page . locator ( 'div' , { hasText : 'foo' } ) . nth ( 0 ) . filter ( { has : page.locator ( 'span' , { hasNotText : 'bar' } ) . nth ( - 1 ) } ) as any ) . _selector ;
const locators = {
javascript : [
` locator('div').filter({ hasText: 'foo' }).first().filter({ has: locator('span').filter({ hasNotText: 'bar' }).last() }) ` ,
` locator('div').filter({ hasText: 'foo' }).first().filter({ has: locator('span').filter({ hasNotText: 'bar' }).nth(-1) }) ` ,
` locator('div').filter({ hasText: 'foo' }).first().filter({ has: locator('span', { hasNotText: 'bar' }).last() }) ` ,
` locator('div').filter({ hasText: 'foo' }).first().filter({ has: locator('span', { hasNotText: 'bar' }).nth(-1) }) ` ,
` locator('div').filter({ hasText: 'foo' }).nth(0).filter({ has: locator('span').filter({ hasNotText: 'bar' }).last() }) ` ,
` locator('div').filter({ hasText: 'foo' }).nth(0).filter({ has: locator('span').filter({ hasNotText: 'bar' }).nth(-1) }) ` ,
` locator('div').filter({ hasText: 'foo' }).nth(0).filter({ has: locator('span', { hasNotText: 'bar' }).last() }) ` ,
` locator('div').filter({ hasText: 'foo' }).nth(0).filter({ has: locator('span', { hasNotText: 'bar' }).nth(-1) }) ` ,
` locator('div', { hasText: 'foo' }).first().filter({ has: locator('span').filter({ hasNotText: 'bar' }).last() }) ` ,
` locator('div', { hasText: 'foo' }).first().filter({ has: locator('span').filter({ hasNotText: 'bar' }).nth(-1) }) ` ,
` locator('div', { hasText: 'foo' }).first().filter({ has: locator('span', { hasNotText: 'bar' }).last() }) ` ,
` locator('div', { hasText: 'foo' }).first().filter({ has: locator('span', { hasNotText: 'bar' }).nth(-1) }) ` ,
` locator('div', { hasText: 'foo' }).nth(0).filter({ has: locator('span').filter({ hasNotText: 'bar' }).last() }) ` ,
` locator('div', { hasText: 'foo' }).nth(0).filter({ has: locator('span').filter({ hasNotText: 'bar' }).nth(-1) }) ` ,
` locator('div', { hasText: 'foo' }).nth(0).filter({ has: locator('span', { hasNotText: 'bar' }).last() }) ` ,
` locator('div', { hasText: 'foo' }).nth(0).filter({ has: locator('span', { hasNotText: 'bar' }).nth(-1) }) ` ,
] ,
java : [
` locator("div").filter(new Locator.FilterOptions().setHasText("foo")).first().filter(new Locator.FilterOptions().setHas(locator("span").filter(new Locator.FilterOptions().setHasNotText("bar")).last())) ` ,
` locator("div").filter(new Locator.FilterOptions().setHasText("foo")).first().filter(new Locator.FilterOptions().setHas(locator("span").filter(new Locator.FilterOptions().setHasNotText("bar")).nth(-1))) ` ,
` locator("div").filter(new Locator.FilterOptions().setHasText("foo")).first().filter(new Locator.FilterOptions().setHas(locator("span", new Page.LocatorOptions().setHasNotText("bar")).last())) ` ,
` locator("div").filter(new Locator.FilterOptions().setHasText("foo")).first().filter(new Locator.FilterOptions().setHas(locator("span", new Page.LocatorOptions().setHasNotText("bar")).nth(-1))) ` ,
` locator("div").filter(new Locator.FilterOptions().setHasText("foo")).nth(0).filter(new Locator.FilterOptions().setHas(locator("span").filter(new Locator.FilterOptions().setHasNotText("bar")).last())) ` ,
` locator("div").filter(new Locator.FilterOptions().setHasText("foo")).nth(0).filter(new Locator.FilterOptions().setHas(locator("span").filter(new Locator.FilterOptions().setHasNotText("bar")).nth(-1))) ` ,
` locator("div").filter(new Locator.FilterOptions().setHasText("foo")).nth(0).filter(new Locator.FilterOptions().setHas(locator("span", new Page.LocatorOptions().setHasNotText("bar")).last())) ` ,
` locator("div").filter(new Locator.FilterOptions().setHasText("foo")).nth(0).filter(new Locator.FilterOptions().setHas(locator("span", new Page.LocatorOptions().setHasNotText("bar")).nth(-1))) ` ,
` locator("div", new Page.LocatorOptions().setHasText("foo")).first().filter(new Locator.FilterOptions().setHas(locator("span").filter(new Locator.FilterOptions().setHasNotText("bar")).last())) ` ,
` locator("div", new Page.LocatorOptions().setHasText("foo")).first().filter(new Locator.FilterOptions().setHas(locator("span").filter(new Locator.FilterOptions().setHasNotText("bar")).nth(-1))) ` ,
` locator("div", new Page.LocatorOptions().setHasText("foo")).first().filter(new Locator.FilterOptions().setHas(locator("span", new Page.LocatorOptions().setHasNotText("bar")).last())) ` ,
` locator("div", new Page.LocatorOptions().setHasText("foo")).first().filter(new Locator.FilterOptions().setHas(locator("span", new Page.LocatorOptions().setHasNotText("bar")).nth(-1))) ` ,
` locator("div", new Page.LocatorOptions().setHasText("foo")).nth(0).filter(new Locator.FilterOptions().setHas(locator("span").filter(new Locator.FilterOptions().setHasNotText("bar")).last())) ` ,
` locator("div", new Page.LocatorOptions().setHasText("foo")).nth(0).filter(new Locator.FilterOptions().setHas(locator("span").filter(new Locator.FilterOptions().setHasNotText("bar")).nth(-1))) ` ,
` locator("div", new Page.LocatorOptions().setHasText("foo")).nth(0).filter(new Locator.FilterOptions().setHas(locator("span", new Page.LocatorOptions().setHasNotText("bar")).last())) ` ,
` locator("div", new Page.LocatorOptions().setHasText("foo")).nth(0).filter(new Locator.FilterOptions().setHas(locator("span", new Page.LocatorOptions().setHasNotText("bar")).nth(-1))) ` ,
] ,
python : [
` locator("div").filter(has_text="foo").first.filter(has=locator("span").filter(has_not_text="bar").last) ` ,
` locator("div").filter(has_text="foo").first.filter(has=locator("span").filter(has_not_text="bar").nth(-1)) ` ,
` locator("div").filter(has_text="foo").first.filter(has=locator("span", has_not_text="bar").last) ` ,
` locator("div").filter(has_text="foo").first.filter(has=locator("span", has_not_text="bar").nth(-1)) ` ,
` locator("div").filter(has_text="foo").nth(0).filter(has=locator("span").filter(has_not_text="bar").last) ` ,
` locator("div").filter(has_text="foo").nth(0).filter(has=locator("span").filter(has_not_text="bar").nth(-1)) ` ,
` locator("div").filter(has_text="foo").nth(0).filter(has=locator("span", has_not_text="bar").last) ` ,
` locator("div").filter(has_text="foo").nth(0).filter(has=locator("span", has_not_text="bar").nth(-1)) ` ,
` locator("div", has_text="foo").first.filter(has=locator("span").filter(has_not_text="bar").last) ` ,
` locator("div", has_text="foo").first.filter(has=locator("span").filter(has_not_text="bar").nth(-1)) ` ,
` locator("div", has_text="foo").first.filter(has=locator("span", has_not_text="bar").last) ` ,
` locator("div", has_text="foo").first.filter(has=locator("span", has_not_text="bar").nth(-1)) ` ,
` locator("div", has_text="foo").nth(0).filter(has=locator("span").filter(has_not_text="bar").last) ` ,
` locator("div", has_text="foo").nth(0).filter(has=locator("span").filter(has_not_text="bar").nth(-1)) ` ,
` locator("div", has_text="foo").nth(0).filter(has=locator("span", has_not_text="bar").last) ` ,
` locator("div", has_text="foo").nth(0).filter(has=locator("span", has_not_text="bar").nth(-1)) ` ,
] ,
csharp : [
` Locator("div").Filter(new() { HasText = "foo" }).First.Filter(new() { Has = Locator("span").Filter(new() { HasNotText = "bar" }).Last }) ` ,
` Locator("div").Filter(new() { HasText = "foo" }).First.Filter(new() { Has = Locator("span").Filter(new() { HasNotText = "bar" }).Nth(-1) }) ` ,
` Locator("div").Filter(new() { HasText = "foo" }).First.Filter(new() { Has = Locator("span", new() { HasNotText = "bar" }).Last }) ` ,
` Locator("div").Filter(new() { HasText = "foo" }).First.Filter(new() { Has = Locator("span", new() { HasNotText = "bar" }).Nth(-1) }) ` ,
` Locator("div").Filter(new() { HasText = "foo" }).Nth(0).Filter(new() { Has = Locator("span").Filter(new() { HasNotText = "bar" }).Last }) ` ,
` Locator("div").Filter(new() { HasText = "foo" }).Nth(0).Filter(new() { Has = Locator("span").Filter(new() { HasNotText = "bar" }).Nth(-1) }) ` ,
` Locator("div").Filter(new() { HasText = "foo" }).Nth(0).Filter(new() { Has = Locator("span", new() { HasNotText = "bar" }).Last }) ` ,
` Locator("div").Filter(new() { HasText = "foo" }).Nth(0).Filter(new() { Has = Locator("span", new() { HasNotText = "bar" }).Nth(-1) }) ` ,
` Locator("div", new() { HasText = "foo" }).First.Filter(new() { Has = Locator("span").Filter(new() { HasNotText = "bar" }).Last }) ` ,
` Locator("div", new() { HasText = "foo" }).First.Filter(new() { Has = Locator("span").Filter(new() { HasNotText = "bar" }).Nth(-1) }) ` ,
` Locator("div", new() { HasText = "foo" }).First.Filter(new() { Has = Locator("span", new() { HasNotText = "bar" }).Last }) ` ,
` Locator("div", new() { HasText = "foo" }).First.Filter(new() { Has = Locator("span", new() { HasNotText = "bar" }).Nth(-1) }) ` ,
` Locator("div", new() { HasText = "foo" }).Nth(0).Filter(new() { Has = Locator("span").Filter(new() { HasNotText = "bar" }).Last }) ` ,
` Locator("div", new() { HasText = "foo" }).Nth(0).Filter(new() { Has = Locator("span").Filter(new() { HasNotText = "bar" }).Nth(-1) }) ` ,
` Locator("div", new() { HasText = "foo" }).Nth(0).Filter(new() { Has = Locator("span", new() { HasNotText = "bar" }).Last }) ` ,
` Locator("div", new() { HasText = "foo" }).Nth(0).Filter(new() { Has = Locator("span", new() { HasNotText = "bar" }).Nth(-1) }) ` ,
] ,
} ;
for ( const lang of [ 'javascript' , 'java' , 'python' , 'csharp' ] as const ) {
expect . soft ( asLocators ( lang , selector , false ) ) . toEqual ( locators [ lang ] ) ;
for ( const locator of locators [ lang ] )
expect . soft ( parseLocator ( lang , locator , 'data-testid' ) , ` parse( ${ lang } ): ${ locator } ` ) . toBe ( selector ) ;
}
} ) ;
2022-10-31 22:55:35 +03:00
it . describe ( ( ) = > {
2022-10-18 23:09:54 +03:00
it . beforeEach ( async ( { context } ) = > {
await ( context as any ) . _enableRecorder ( { language : 'javascript' } ) ;
} ) ;
2022-10-22 02:29:45 +03:00
it ( 'reverse engineer internal:has-text locators' , async ( { page } ) = > {
2022-10-18 23:09:54 +03:00
await page . setContent ( `
< div > Hello < span > world < / span > < / div >
< div > Goodbye < span mark = 1 > world < / span > < / div >
` );
expect . soft ( await generateForNode ( page , '[mark="1"]' ) ) . toEqual ( {
2022-11-30 07:56:18 +03:00
csharp : 'Locator("div").Filter(new() { HasText = "Goodbye world" }).Locator("span")' ,
2022-12-28 20:13:06 +03:00
java : 'locator("div").filter(new Locator.FilterOptions().setHasText("Goodbye world")).locator("span")' ,
2022-10-18 23:09:54 +03:00
javascript : ` locator('div').filter({ hasText: 'Goodbye world' }).locator('span') ` ,
python : 'locator("div").filter(has_text="Goodbye world").locator("span")' ,
} ) ;
2023-03-15 23:43:42 +03:00
expect . soft ( asLocator ( 'javascript' , 'div >> internal:has-text="foo"s' , false ) ) . toBe ( ` locator('div').locator('internal:has-text="foo"s') ` ) ;
2023-04-06 00:13:28 +03:00
expect . soft ( asLocator ( 'javascript' , 'div >> internal:has-not-text="foo"s' , false ) ) . toBe ( ` locator('div').locator('internal:has-not-text="foo"s') ` ) ;
2022-10-18 23:09:54 +03:00
} ) ;
2022-10-12 03:50:41 +03:00
} ) ;
2022-11-04 01:17:08 +03:00
2023-05-05 21:14:01 +03:00
it ( 'asLocator internal:and' , async ( ) = > {
expect . soft ( asLocator ( 'javascript' , 'div >> internal:and="span >> article"' , false ) ) . toBe ( ` locator('div').and(locator('span').locator('article')) ` ) ;
expect . soft ( asLocator ( 'python' , 'div >> internal:and="span >> article"' , false ) ) . toBe ( ` locator("div").and_(locator("span").locator("article")) ` ) ;
expect . soft ( asLocator ( 'java' , 'div >> internal:and="span >> article"' , false ) ) . toBe ( ` locator("div").and(locator("span").locator("article")) ` ) ;
expect . soft ( asLocator ( 'csharp' , 'div >> internal:and="span >> article"' , false ) ) . toBe ( ` Locator("div").And(Locator("span").Locator("article")) ` ) ;
} ) ;
2023-03-23 01:28:59 +03:00
it ( 'asLocator internal:or' , async ( ) = > {
expect . soft ( asLocator ( 'javascript' , 'div >> internal:or="span >> article"' , false ) ) . toBe ( ` locator('div').or(locator('span').locator('article')) ` ) ;
expect . soft ( asLocator ( 'python' , 'div >> internal:or="span >> article"' , false ) ) . toBe ( ` locator("div").or_(locator("span").locator("article")) ` ) ;
expect . soft ( asLocator ( 'java' , 'div >> internal:or="span >> article"' , false ) ) . toBe ( ` locator("div").or(locator("span").locator("article")) ` ) ;
expect . soft ( asLocator ( 'csharp' , 'div >> internal:or="span >> article"' , false ) ) . toBe ( ` Locator("div").Or(Locator("span").Locator("article")) ` ) ;
} ) ;
2023-07-14 22:21:45 +03:00
it ( 'asLocator internal:chain' , async ( ) = > {
expect . soft ( asLocator ( 'javascript' , 'div >> internal:chain="span >> article"' , false ) ) . toBe ( ` locator('div').locator(locator('span').locator('article')) ` ) ;
expect . soft ( asLocator ( 'python' , 'div >> internal:chain="span >> article"' , false ) ) . toBe ( ` locator("div").locator(locator("span").locator("article")) ` ) ;
expect . soft ( asLocator ( 'java' , 'div >> internal:chain="span >> article"' , false ) ) . toBe ( ` locator("div").locator(locator("span").locator("article")) ` ) ;
expect . soft ( asLocator ( 'csharp' , 'div >> internal:chain="span >> article"' , false ) ) . toBe ( ` Locator("div").Locator(Locator("span").Locator("article")) ` ) ;
} ) ;
2023-07-25 22:55:35 +03:00
it ( 'asLocator xpath' , async ( ) = > {
const selector = ` //*[contains(normalizer-text(), 'foo'] ` ;
expect . soft ( asLocator ( 'javascript' , selector , false ) ) . toBe ( ` locator('xpath=//*[contains(normalizer-text(), \\ 'foo \\ ']') ` ) ;
expect . soft ( asLocator ( 'python' , selector , false ) ) . toBe ( ` locator( \ "xpath=//*[contains(normalizer-text(), 'foo'] \ ") ` ) ;
expect . soft ( asLocator ( 'java' , selector , false ) ) . toBe ( ` locator( \ "xpath=//*[contains(normalizer-text(), 'foo'] \ ") ` ) ;
expect . soft ( asLocator ( 'csharp' , selector , false ) ) . toBe ( ` Locator( \ "xpath=//*[contains(normalizer-text(), 'foo'] \ ") ` ) ;
} ) ;
2022-11-04 01:17:08 +03:00
it ( 'parse locators strictly' , ( ) = > {
const selector = 'div >> internal:has-text=\"Goodbye world\"i >> span' ;
// Exact
2022-11-30 07:56:18 +03:00
expect . soft ( parseLocator ( 'csharp' , ` Locator("div").Filter(new() { HasText = "Goodbye world" }).Locator("span") ` ) ) . toBe ( selector ) ;
2022-12-28 20:13:06 +03:00
expect . soft ( parseLocator ( 'java' , ` locator("div").filter(new Locator.FilterOptions().setHasText("Goodbye world")).locator("span") ` ) ) . toBe ( selector ) ;
2022-11-04 01:17:08 +03:00
expect . soft ( parseLocator ( 'javascript' , ` locator('div').filter({ hasText: 'Goodbye world' }).locator('span') ` ) ) . toBe ( selector ) ;
expect . soft ( parseLocator ( 'python' , ` locator("div").filter(has_text="Goodbye world").locator("span") ` ) ) . toBe ( selector ) ;
// Quotes
expect . soft ( parseLocator ( 'javascript' , ` locator("div").filter({ hasText: "Goodbye world" }).locator("span") ` ) ) . toBe ( selector ) ;
expect . soft ( parseLocator ( 'python' , ` locator('div').filter(has_text='Goodbye world').locator('span') ` ) ) . toBe ( selector ) ;
// Whitespace
2022-11-30 07:56:18 +03:00
expect . soft ( parseLocator ( 'csharp' , ` Locator("div") . Filter (new ( ) { HasText = "Goodbye world" }).Locator( "span" ) ` ) ) . toBe ( selector ) ;
2022-12-28 20:13:06 +03:00
expect . soft ( parseLocator ( 'java' , ` locator("div" ). filter( new Locator. FilterOptions ( ) .setHasText( "Goodbye world" ) ).locator( "span") ` ) ) . toBe ( selector ) ;
2022-11-04 01:17:08 +03:00
expect . soft ( parseLocator ( 'javascript' , ` locator \ n('div') \ n \ n.filter({ hasText : 'Goodbye world' \ n } \ n).locator('span') \ n ` ) ) . toBe ( selector ) ;
expect . soft ( parseLocator ( 'python' , ` \ tlocator( \ t"div").filter( \ thas_text="Goodbye world" \ t).locator \ t("span") ` ) ) . toBe ( selector ) ;
// Extra symbols
2022-11-30 07:56:18 +03:00
expect . soft ( parseLocator ( 'csharp' , ` Locator("div").Filter(new() { HasText = "Goodbye world" }).Locator("span")) ` ) ) . not . toBe ( selector ) ;
2022-12-28 20:13:06 +03:00
expect . soft ( parseLocator ( 'java' , ` locator("div").filter(new Locator.FilterOptions().setHasText("Goodbye world"))..locator("span") ` ) ) . not . toBe ( selector ) ;
2022-11-04 01:17:08 +03:00
expect . soft ( parseLocator ( 'javascript' , ` locator('div').filter({ hasText: 'Goodbye world' }}).locator('span') ` ) ) . not . toBe ( selector ) ;
expect . soft ( parseLocator ( 'python' , ` locator("div").filter(has_text=="Goodbye world").locator("span") ` ) ) . not . toBe ( selector ) ;
} ) ;