implement for JS and python
This commit is contained in:
parent
2855f612be
commit
5a162c5840
|
|
@ -19,7 +19,7 @@ import { type NestedSelectorBody, parseAttributeSelector, parseSelector, stringi
|
||||||
import type { ParsedSelector } from './selectorParser';
|
import type { ParsedSelector } from './selectorParser';
|
||||||
|
|
||||||
export type Language = 'javascript' | 'python' | 'java' | 'csharp' | 'jsonl';
|
export type Language = 'javascript' | 'python' | 'java' | 'csharp' | 'jsonl';
|
||||||
export type LocatorType = 'default' | 'role' | 'text' | 'label' | 'placeholder' | 'alt' | 'title' | 'test-id' | 'nth' | 'first' | 'last' | 'has-text' | 'has-not-text' | 'has' | 'hasNot' | 'frame' | 'and' | 'or' | 'chain';
|
export type LocatorType = 'default' | 'role' | 'text' | 'label' | 'placeholder' | 'alt' | 'title' | 'test-id' | 'nth' | 'first' | 'last' | 'has-text' | 'has-not-text' | 'has' | 'hasNot' | 'frame' | 'frame-locator' | 'and' | 'or' | 'chain';
|
||||||
export type LocatorBase = 'page' | 'locator' | 'frame-locator';
|
export type LocatorBase = 'page' | 'locator' | 'frame-locator';
|
||||||
export type Quote = '\'' | '"' | '`';
|
export type Quote = '\'' | '"' | '`';
|
||||||
|
|
||||||
|
|
@ -194,8 +194,22 @@ function innerAsLocators(factory: LocatorFactory, parsed: ParsedSelector, isFram
|
||||||
const selectorPart = stringifySelector({ parts: [part] }, /* forceEngineName */ true);
|
const selectorPart = stringifySelector({ parts: [part] }, /* forceEngineName */ true);
|
||||||
locatorPartWithEngine = factory.generateLocator(base, 'default', selectorPart);
|
locatorPartWithEngine = factory.generateLocator(base, 'default', selectorPart);
|
||||||
}
|
}
|
||||||
|
const locatorParts = [locatorPart, locatorPartWithEngine].filter(Boolean) as string[];
|
||||||
|
|
||||||
tokens.push([locatorPart, locatorPartWithEngine].filter(Boolean) as string[]);
|
if (nextPart && nextPart.name === 'internal:control' && (nextPart.body as string) === 'enter-frame') {
|
||||||
|
// Two options:
|
||||||
|
// - locator('iframe').contentFrame()
|
||||||
|
// - frameLocator('iframe')
|
||||||
|
tokens.push([
|
||||||
|
...locatorParts.map(p => factory.chainLocators([p, factory.generateLocator(base, 'frame', '')])),
|
||||||
|
factory.generateLocator(base, 'frame-locator', selectorPart),
|
||||||
|
]);
|
||||||
|
nextBase = 'frame-locator';
|
||||||
|
index++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
tokens.push(locatorParts);
|
||||||
}
|
}
|
||||||
|
|
||||||
return combineTokens(factory, tokens, maxOutputSize);
|
return combineTokens(factory, tokens, maxOutputSize);
|
||||||
|
|
@ -251,6 +265,8 @@ export class JavaScriptLocatorFactory implements LocatorFactory {
|
||||||
if (options.hasNotText !== undefined)
|
if (options.hasNotText !== undefined)
|
||||||
return `locator(${this.quote(body as string)}, { hasNotText: ${this.toHasText(options.hasNotText)} })`;
|
return `locator(${this.quote(body as string)}, { hasNotText: ${this.toHasText(options.hasNotText)} })`;
|
||||||
return `locator(${this.quote(body as string)})`;
|
return `locator(${this.quote(body as string)})`;
|
||||||
|
case 'frame-locator':
|
||||||
|
return `frameLocator(${this.quote(body as string)})`;
|
||||||
case 'frame':
|
case 'frame':
|
||||||
return `contentFrame()`;
|
return `contentFrame()`;
|
||||||
case 'nth':
|
case 'nth':
|
||||||
|
|
@ -343,6 +359,8 @@ export class PythonLocatorFactory implements LocatorFactory {
|
||||||
if (options.hasNotText !== undefined)
|
if (options.hasNotText !== undefined)
|
||||||
return `locator(${this.quote(body as string)}, has_not_text=${this.toHasText(options.hasNotText)})`;
|
return `locator(${this.quote(body as string)}, has_not_text=${this.toHasText(options.hasNotText)})`;
|
||||||
return `locator(${this.quote(body as string)})`;
|
return `locator(${this.quote(body as string)})`;
|
||||||
|
case 'frame-locator':
|
||||||
|
return `frame_locator(${this.quote(body as string)})`;
|
||||||
case 'frame':
|
case 'frame':
|
||||||
return `content_frame`;
|
return `content_frame`;
|
||||||
case 'nth':
|
case 'nth':
|
||||||
|
|
|
||||||
|
|
@ -584,3 +584,11 @@ it('parse locators strictly', () => {
|
||||||
expect.soft(parseLocator('javascript', `locator('div').filter({ hasText: 'Goodbye world' }}).locator('span')`)).not.toBe(selector);
|
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);
|
expect.soft(parseLocator('python', `locator("div").filter(has_text=="Goodbye world").locator("span")`)).not.toBe(selector);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('parseLocator frames', async () => {
|
||||||
|
expect.soft(parseLocator('javascript', `locator('iframe').contentFrame().getByText('foo')`, '')).toBe(`iframe >> internal:control=enter-frame >> internal:text=\"foo\"i`);
|
||||||
|
expect.soft(parseLocator('javascript', `frameLocator('iframe').getByText('foo')`, '')).toBe(`iframe >> internal:control=enter-frame >> internal:text=\"foo\"i`);
|
||||||
|
|
||||||
|
expect.soft(parseLocator('python', `locator("iframe").content_frame.get_by_text("foo")`, '')).toBe(`iframe >> internal:control=enter-frame >> internal:text=\"foo\"i`);
|
||||||
|
expect.soft(parseLocator('python', `frame_locator("iframe").get_by_text("foo")`, '')).toBe(`iframe >> internal:control=enter-frame >> internal:text=\"foo\"i`);
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue