Skip to content

Commit

Permalink
chore: generate simple dom descriptions in codegen
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelfeldman committed Aug 27, 2024
1 parent 177576a commit 71d5ae5
Show file tree
Hide file tree
Showing 12 changed files with 196 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export type FrameDescription = {

export type ActionInContext = {
frame: FrameDescription;
description?: string;
action: Action;
committed?: boolean;
};
Expand Down
8 changes: 7 additions & 1 deletion packages/playwright-core/src/server/codegen/javascript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export class JavaScriptLanguageGenerator implements LanguageGenerator {
if (signals.download)
formatter.add(`const download${signals.download.downloadAlias}Promise = ${pageAlias}.waitForEvent('download');`);

formatter.add(this._generateActionCall(subject, actionInContext));
formatter.add(wrapWithStep(actionInContext.description, this._generateActionCall(subject, actionInContext)));

if (signals.popup)
formatter.add(`const ${signals.popup.popupAlias} = await ${signals.popup.popupAlias}Promise;`);
Expand Down Expand Up @@ -259,3 +259,9 @@ export class JavaScriptFormatter {
function quote(text: string) {
return escapeWithQuotes(text, '\'');
}

function wrapWithStep(description: string | undefined, body: string) {
return description ? `await test.step(\`${description}\`, async () => {
${body}
});` : body;
}
2 changes: 1 addition & 1 deletion packages/playwright-core/src/server/frames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ export class Frame extends SdkObject {
const result = await resolved.injected.evaluateHandle((injected, { info, root }) => {
const elements = injected.querySelectorAll(info.parsed, root || document);
const element: Element | undefined = elements[0];
const visible = element ? injected.isVisible(element) : false;
const visible = element ? injected.utils.isElementVisible(element) : false;
let log = '';
if (elements.length > 1) {
if (info.strict)
Expand Down
27 changes: 19 additions & 8 deletions packages/playwright-core/src/server/injected/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
const path = require('path');

module.exports = {
rules: {
"no-restricted-globals": [
"error",
{ "name": "window" },
{ "name": "document" },
{ "name": "globalThis" },
]
}
parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint", "notice"],
parserOptions: {
ecmaVersion: 9,
sourceType: "module",
project: path.join(__dirname, '../../../../../tsconfig.json'),
},
rules: {
"no-restricted-globals": [
"error",
{ "name": "window" },
{ "name": "document" },
{ "name": "globalThis" },
],
'@typescript-eslint/no-floating-promises': 'error',
"@typescript-eslint/no-unnecessary-boolean-literal-compare": 2,
},
};
2 changes: 1 addition & 1 deletion packages/playwright-core/src/server/injected/clock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ export class ClockController {
const sinceLastSync = now - this._realTime!.lastSyncTicks;
this._realTime!.lastSyncTicks = now;
// eslint-disable-next-line no-console
this._runTo(shiftTicks(this._now.ticks, sinceLastSync)).catch(e => console.error(e)).then(() => this._updateRealTimeTimer());
void this._runTo(shiftTicks(this._now.ticks, sinceLastSync)).catch(e => console.error(e)).then(() => this._updateRealTimeTimer());
}, callAt - this._now.ticks),
};
}
Expand Down
44 changes: 23 additions & 21 deletions packages/playwright-core/src/server/injected/injectedScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ import type { CSSComplexSelectorList } from '../../utils/isomorphic/cssParser';
import { generateSelector, type GenerateSelectorOptions } from './selectorGenerator';
import type * as channels from '@protocol/channels';
import { Highlight } from './highlight';
import { getChecked, getAriaDisabled, getAriaRole, getElementAccessibleName, getElementAccessibleDescription } from './roleUtils';
import { getChecked, getAriaDisabled, getAriaRole, getElementAccessibleName, getElementAccessibleDescription, beginAriaCaches, endAriaCaches } from './roleUtils';
import { kLayoutSelectorNames, type LayoutSelectorName, layoutSelectorScore } from './layoutSelectorUtils';
import { asLocator } from '../../utils/isomorphic/locatorGenerators';
import type { Language } from '../../utils/isomorphic/locatorGenerators';
import { cacheNormalizedWhitespaces, normalizeWhiteSpace, trimStringWithEllipsis } from '../../utils/isomorphic/stringUtils';
import { cacheNormalizedWhitespaces, escapeHTML, escapeHTMLAttribute, normalizeWhiteSpace, trimStringWithEllipsis } from '../../utils/isomorphic/stringUtils';

export type FrameExpectParams = Omit<channels.FrameExpectParams, 'expectedValue'> & { expectedValue?: any };

Expand Down Expand Up @@ -66,7 +66,25 @@ export class InjectedScript {
// eslint-disable-next-line no-restricted-globals
readonly window: Window & typeof globalThis;
readonly document: Document;
readonly utils = { isInsideScope, elementText, asLocator, normalizeWhiteSpace, cacheNormalizedWhitespaces };

// Recorder must use any external dependencies through InjectedScript.
// Otherwise it will end up with a copy of all modules it uses, and any
// module-level globals will be duplicated, which leads to subtle bugs.
readonly utils = {
asLocator,
beginAriaCaches,
cacheNormalizedWhitespaces,
elementText,
endAriaCaches,
escapeHTML,
escapeHTMLAttribute,
getAriaRole,
getElementAccessibleDescription,
getElementAccessibleName,
isElementVisible,
isInsideScope,
normalizeWhiteSpace,
};

// eslint-disable-next-line no-restricted-globals
constructor(window: Window & typeof globalThis, isUnderTest: boolean, sdkLanguage: Language, testIdAttributeNameForStrictErrorAndConsoleCodegen: string, stableRafCount: number, browserName: string, customEngines: { name: string, engine: SelectorEngine }[]) {
Expand Down Expand Up @@ -426,10 +444,6 @@ export class InjectedScript {
return new constrFunction(this, params);
}

isVisible(element: Element): boolean {
return isElementVisible(element);
}

async viewportRatio(element: Element): Promise<number> {
return await new Promise(resolve => {
const observer = new IntersectionObserver(entries => {
Expand Down Expand Up @@ -567,9 +581,9 @@ export class InjectedScript {
}

if (state === 'visible')
return this.isVisible(element);
return isElementVisible(element);
if (state === 'hidden')
return !this.isVisible(element);
return !isElementVisible(element);

const disabled = getAriaDisabled(element);
if (state === 'disabled')
Expand Down Expand Up @@ -1296,18 +1310,6 @@ export class InjectedScript {
}
throw this.createStacklessError('Unknown expect matcher: ' + expression);
}

getElementAccessibleName(element: Element, includeHidden?: boolean): string {
return getElementAccessibleName(element, !!includeHidden);
}

getElementAccessibleDescription(element: Element, includeHidden?: boolean): string {
return getElementAccessibleDescription(element, !!includeHidden);
}

getAriaRole(element: Element) {
return getAriaRole(element);
}
}

const autoClosingTags = new Set(['AREA', 'BASE', 'BR', 'COL', 'COMMAND', 'EMBED', 'HR', 'IMG', 'INPUT', 'KEYGEN', 'LINK', 'MENUITEM', 'META', 'PARAM', 'SOURCE', 'TRACK', 'WBR']);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Recorder must use any external dependencies through InjectedScript.
# Recorder must use any external dependencies through injectedScript.utils.
# Otherwise it will end up with a copy of all modules it uses, and any
# module-level globals will be duplicated, which leads to subtle bugs.
[*]
Loading

0 comments on commit 71d5ae5

Please sign in to comment.