diff --git a/packages/playwright-core/src/client/channelOwner.ts b/packages/playwright-core/src/client/channelOwner.ts index 6a2118cf75..a147dbec4f 100644 --- a/packages/playwright-core/src/client/channelOwner.ts +++ b/packages/playwright-core/src/client/channelOwner.ts @@ -20,11 +20,12 @@ import { maybeFindValidator, ValidationError, type ValidatorContext } from '../p import { debugLogger } from '../common/debugLogger'; import type { ExpectZone, ParsedStackTrace } from '../utils/stackTrace'; import { captureRawStack, captureLibraryStackTrace } from '../utils/stackTrace'; -import { isUnderTest } from '../utils'; +import { isString, isUnderTest } from '../utils'; import { zones } from '../utils/zones'; import type { ClientInstrumentation } from './clientInstrumentation'; import type { Connection } from './connection'; import type { Logger } from './types'; +import { asLocator } from '../utils/isomorphic/locatorGenerators'; type Listener = (...args: any[]) => void; @@ -228,8 +229,18 @@ function renderCallWithParams(apiName: string, params: any) { const paramsArray = []; if (params) { for (const name of paramsToRender) { - if (params[name]) - paramsArray.push(params[name]); + if (!(name in params)) + continue; + let value; + if (name === 'selector' && isString(params[name]) && params[name].startsWith('internal:')) { + const getter = asLocator('javascript', params[name], false, true); + apiName = apiName.replace(/^locator\./, 'locator.' + getter + '.'); + apiName = apiName.replace(/^page\./, 'page.' + getter + '.'); + apiName = apiName.replace(/^frame\./, 'frame.' + getter + '.'); + } else { + value = params[name]; + paramsArray.push(value); + } } } const paramsText = paramsArray.length ? '(' + paramsArray.join(', ') + ')' : ''; diff --git a/packages/playwright-core/src/inProcessFactory.ts b/packages/playwright-core/src/inProcessFactory.ts index 86539217f2..9ef4d7e6be 100644 --- a/packages/playwright-core/src/inProcessFactory.ts +++ b/packages/playwright-core/src/inProcessFactory.ts @@ -19,7 +19,7 @@ import { createPlaywright, DispatcherConnection, RootDispatcher, PlaywrightDispa import { Connection } from './client/connection'; import { BrowserServerLauncherImpl } from './browserServerImpl'; import { AndroidServerLauncherImpl } from './androidServerImpl'; -import type { Language } from './server/isomorphic/locatorGenerators'; +import type { Language } from './utils/isomorphic/locatorGenerators'; export function createInProcessPlaywright(): PlaywrightAPI { const playwright = createPlaywright((process.env.PW_LANG_NAME as Language | undefined) || 'javascript'); diff --git a/packages/playwright-core/src/server/DEPS.list b/packages/playwright-core/src/server/DEPS.list index 4415348429..bc32bb8486 100644 --- a/packages/playwright-core/src/server/DEPS.list +++ b/packages/playwright-core/src/server/DEPS.list @@ -3,6 +3,7 @@ ../generated/ ../protocol/ ../utils/ +../utils/isomorphic/ ../utilsBundle.ts ../zipBundle.ts ./ diff --git a/packages/playwright-core/src/server/browser.ts b/packages/playwright-core/src/server/browser.ts index 63d8f12719..73933cee9b 100644 --- a/packages/playwright-core/src/server/browser.ts +++ b/packages/playwright-core/src/server/browser.ts @@ -26,7 +26,7 @@ import type { CallMetadata } from './instrumentation'; import { SdkObject } from './instrumentation'; import { Artifact } from './artifact'; import type { Selectors } from './selectors'; -import type { Language } from './isomorphic/locatorGenerators'; +import type { Language } from '../utils/isomorphic/locatorGenerators'; export interface BrowserProcess { onclose?: ((exitCode: number | null, signal: string | null) => void); diff --git a/packages/playwright-core/src/server/debugController.ts b/packages/playwright-core/src/server/debugController.ts index 1d29c1a4e6..dc274bf3b7 100644 --- a/packages/playwright-core/src/server/debugController.ts +++ b/packages/playwright-core/src/server/debugController.ts @@ -23,8 +23,8 @@ import type { InstrumentationListener } from './instrumentation'; import type { Playwright } from './playwright'; import { Recorder } from './recorder'; import { EmptyRecorderApp } from './recorder/recorderApp'; -import { asLocator } from './isomorphic/locatorGenerators'; -import type { Language } from './isomorphic/locatorGenerators'; +import { asLocator } from '../utils/isomorphic/locatorGenerators'; +import type { Language } from '../utils/isomorphic/locatorGenerators'; const internalMetadata = serverSideCallMetadata(); diff --git a/packages/playwright-core/src/server/frameSelectors.ts b/packages/playwright-core/src/server/frameSelectors.ts index df05f926f6..9ef6b4fb94 100644 --- a/packages/playwright-core/src/server/frameSelectors.ts +++ b/packages/playwright-core/src/server/frameSelectors.ts @@ -16,7 +16,7 @@ import { type Frame } from './frames'; import type * as types from './types'; -import { stringifySelector, type ParsedSelector, splitSelectorByFrame } from './isomorphic/selectorParser'; +import { stringifySelector, type ParsedSelector, splitSelectorByFrame } from '../utils/isomorphic/selectorParser'; import { type FrameExecutionContext, type ElementHandle } from './dom'; import { type JSHandle } from './javascript'; import { type InjectedScript } from './injected/injectedScript'; diff --git a/packages/playwright-core/src/server/frames.ts b/packages/playwright-core/src/server/frames.ts index 4a75699c6b..b18fce5e92 100644 --- a/packages/playwright-core/src/server/frames.ts +++ b/packages/playwright-core/src/server/frames.ts @@ -36,10 +36,10 @@ import type { CallMetadata } from './instrumentation'; import { serverSideCallMetadata, SdkObject } from './instrumentation'; import type { InjectedScript, ElementStateWithoutStable, FrameExpectParams, InjectedScriptPoll, InjectedScriptProgress } from './injected/injectedScript'; import { isSessionClosedError } from './protocolError'; -import { type ParsedSelector, isInvalidSelectorError } from './isomorphic/selectorParser'; +import { type ParsedSelector, isInvalidSelectorError } from '../utils/isomorphic/selectorParser'; import type { ScreenshotOptions } from './screenshotter'; import type { InputFilesItems } from './dom'; -import { asLocator } from './isomorphic/locatorGenerators'; +import { asLocator } from '../utils/isomorphic/locatorGenerators'; import { FrameSelectors } from './frameSelectors'; type ContextData = { diff --git a/packages/playwright-core/src/server/injected/consoleApi.ts b/packages/playwright-core/src/server/injected/consoleApi.ts index fbdb44e8d5..50398c01e9 100644 --- a/packages/playwright-core/src/server/injected/consoleApi.ts +++ b/packages/playwright-core/src/server/injected/consoleApi.ts @@ -17,8 +17,8 @@ import type { ByRoleOptions } from '../../utils/isomorphic/locatorUtils'; import { getByAltTextSelector, getByLabelSelector, getByPlaceholderSelector, getByRoleSelector, getByTestIdSelector, getByTextSelector, getByTitleSelector } from '../../utils/isomorphic/locatorUtils'; import { escapeForTextSelector } from '../../utils/isomorphic/stringUtils'; -import { asLocator } from '../isomorphic/locatorGenerators'; -import type { Language } from '../isomorphic/locatorGenerators'; +import { asLocator } from '../../utils/isomorphic/locatorGenerators'; +import type { Language } from '../../utils/isomorphic/locatorGenerators'; import { type InjectedScript } from './injectedScript'; import { generateSelector } from './selectorGenerator'; diff --git a/packages/playwright-core/src/server/injected/highlight.ts b/packages/playwright-core/src/server/injected/highlight.ts index eb74390342..86ae25f442 100644 --- a/packages/playwright-core/src/server/injected/highlight.ts +++ b/packages/playwright-core/src/server/injected/highlight.ts @@ -14,11 +14,11 @@ * limitations under the License. */ -import { stringifySelector } from '../isomorphic/selectorParser'; -import type { ParsedSelector } from '../isomorphic/selectorParser'; +import { stringifySelector } from '../../utils/isomorphic/selectorParser'; +import type { ParsedSelector } from '../../utils/isomorphic/selectorParser'; import type { InjectedScript } from './injectedScript'; -import { asLocator } from '../isomorphic/locatorGenerators'; -import type { Language } from '../isomorphic/locatorGenerators'; +import { asLocator } from '../../utils/isomorphic/locatorGenerators'; +import type { Language } from '../../utils/isomorphic/locatorGenerators'; type HighlightEntry = { targetElement: Element, diff --git a/packages/playwright-core/src/server/injected/injectedScript.ts b/packages/playwright-core/src/server/injected/injectedScript.ts index 1a361e3add..0571ef9ced 100644 --- a/packages/playwright-core/src/server/injected/injectedScript.ts +++ b/packages/playwright-core/src/server/injected/injectedScript.ts @@ -19,20 +19,20 @@ import { XPathEngine } from './xpathSelectorEngine'; import { ReactEngine } from './reactSelectorEngine'; import { VueEngine } from './vueSelectorEngine'; import { createRoleEngine } from './roleSelectorEngine'; -import { parseAttributeSelector } from '../isomorphic/selectorParser'; -import type { NestedSelectorBody, ParsedSelector, ParsedSelectorPart } from '../isomorphic/selectorParser'; -import { allEngineNames, parseSelector, stringifySelector } from '../isomorphic/selectorParser'; +import { parseAttributeSelector } from '../../utils/isomorphic/selectorParser'; +import type { NestedSelectorBody, ParsedSelector, ParsedSelectorPart } from '../../utils/isomorphic/selectorParser'; +import { allEngineNames, parseSelector, stringifySelector } from '../../utils/isomorphic/selectorParser'; import { type TextMatcher, elementMatchesText, elementText, type ElementText } from './selectorUtils'; import { SelectorEvaluatorImpl } from './selectorEvaluator'; import { enclosingShadowRootOrDocument, isElementVisible, parentElementOrShadowHost } from './domUtils'; -import type { CSSComplexSelectorList } from '../isomorphic/cssParser'; +import type { CSSComplexSelectorList } from '../../utils/isomorphic/cssParser'; import { generateSelector } from './selectorGenerator'; import type * as channels from '@protocol/channels'; import { Highlight } from './highlight'; import { getChecked, getAriaDisabled, getAriaLabelledByElements, getAriaRole, getElementAccessibleName } from './roleUtils'; import { kLayoutSelectorNames, type LayoutSelectorName, layoutSelectorScore } from './layoutSelectorUtils'; -import { asLocator } from '../isomorphic/locatorGenerators'; -import type { Language } from '../isomorphic/locatorGenerators'; +import { asLocator } from '../../utils/isomorphic/locatorGenerators'; +import type { Language } from '../../utils/isomorphic/locatorGenerators'; import { normalizeWhiteSpace } from '../../utils/isomorphic/stringUtils'; type Predicate = (progress: InjectedScriptProgress) => T | symbol; diff --git a/packages/playwright-core/src/server/injected/reactSelectorEngine.ts b/packages/playwright-core/src/server/injected/reactSelectorEngine.ts index 57d4262089..30bf0f9a10 100644 --- a/packages/playwright-core/src/server/injected/reactSelectorEngine.ts +++ b/packages/playwright-core/src/server/injected/reactSelectorEngine.ts @@ -17,7 +17,7 @@ import type { SelectorEngine, SelectorRoot } from './selectorEngine'; import { isInsideScope } from './domUtils'; import { matchesComponentAttribute } from './selectorUtils'; -import { parseAttributeSelector } from '../isomorphic/selectorParser'; +import { parseAttributeSelector } from '../../utils/isomorphic/selectorParser'; type ComponentNode = { key?: any, diff --git a/packages/playwright-core/src/server/injected/roleSelectorEngine.ts b/packages/playwright-core/src/server/injected/roleSelectorEngine.ts index f468c1e52c..d82a819cd5 100644 --- a/packages/playwright-core/src/server/injected/roleSelectorEngine.ts +++ b/packages/playwright-core/src/server/injected/roleSelectorEngine.ts @@ -17,7 +17,7 @@ import type { SelectorEngine, SelectorRoot } from './selectorEngine'; import { matchesAttributePart } from './selectorUtils'; import { getAriaChecked, getAriaDisabled, getAriaExpanded, getAriaLevel, getAriaPressed, getAriaRole, getAriaSelected, getElementAccessibleName, isElementHiddenForAria, kAriaCheckedRoles, kAriaExpandedRoles, kAriaLevelRoles, kAriaPressedRoles, kAriaSelectedRoles } from './roleUtils'; -import { parseAttributeSelector, type AttributeSelectorPart, type AttributeSelectorOperator } from '../isomorphic/selectorParser'; +import { parseAttributeSelector, type AttributeSelectorPart, type AttributeSelectorOperator } from '../../utils/isomorphic/selectorParser'; import { normalizeWhiteSpace } from '../../utils/isomorphic/stringUtils'; type RoleEngineOptions = { diff --git a/packages/playwright-core/src/server/injected/selectorEvaluator.ts b/packages/playwright-core/src/server/injected/selectorEvaluator.ts index b778931356..bbb23a85a1 100644 --- a/packages/playwright-core/src/server/injected/selectorEvaluator.ts +++ b/packages/playwright-core/src/server/injected/selectorEvaluator.ts @@ -14,8 +14,8 @@ * limitations under the License. */ -import type { CSSComplexSelector, CSSSimpleSelector, CSSComplexSelectorList, CSSFunctionArgument } from '../isomorphic/cssParser'; -import { customCSSNames } from '../isomorphic/selectorParser'; +import type { CSSComplexSelector, CSSSimpleSelector, CSSComplexSelectorList, CSSFunctionArgument } from '../../utils/isomorphic/cssParser'; +import { customCSSNames } from '../../utils/isomorphic/selectorParser'; import { isElementVisible, parentElementOrShadowHost } from './domUtils'; import { type LayoutSelectorName, layoutSelectorScore } from './layoutSelectorUtils'; import { elementMatchesText, elementText, shouldSkipForTextMatching, type ElementText } from './selectorUtils'; diff --git a/packages/playwright-core/src/server/injected/selectorUtils.ts b/packages/playwright-core/src/server/injected/selectorUtils.ts index dcfe1942a6..867fcd4974 100644 --- a/packages/playwright-core/src/server/injected/selectorUtils.ts +++ b/packages/playwright-core/src/server/injected/selectorUtils.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { type AttributeSelectorPart } from '../isomorphic/selectorParser'; +import { type AttributeSelectorPart } from '../../utils/isomorphic/selectorParser'; export function matchesComponentAttribute(obj: any, attr: AttributeSelectorPart) { for (const token of attr.jsonPath) { diff --git a/packages/playwright-core/src/server/injected/vueSelectorEngine.ts b/packages/playwright-core/src/server/injected/vueSelectorEngine.ts index 94b4677128..0ba552d558 100644 --- a/packages/playwright-core/src/server/injected/vueSelectorEngine.ts +++ b/packages/playwright-core/src/server/injected/vueSelectorEngine.ts @@ -17,7 +17,7 @@ import type { SelectorEngine, SelectorRoot } from './selectorEngine'; import { isInsideScope } from './domUtils'; import { matchesComponentAttribute } from './selectorUtils'; -import { parseAttributeSelector } from '../isomorphic/selectorParser'; +import { parseAttributeSelector } from '../../utils/isomorphic/selectorParser'; type ComponentNode = { name: string, diff --git a/packages/playwright-core/src/server/page.ts b/packages/playwright-core/src/server/page.ts index 110d824139..6f6725d24f 100644 --- a/packages/playwright-core/src/server/page.ts +++ b/packages/playwright-core/src/server/page.ts @@ -40,7 +40,7 @@ import type { CallMetadata } from './instrumentation'; import { SdkObject } from './instrumentation'; import type { Artifact } from './artifact'; import type { TimeoutOptions } from '../common/types'; -import { isInvalidSelectorError } from './isomorphic/selectorParser'; +import { isInvalidSelectorError } from '../utils/isomorphic/selectorParser'; import { parseEvaluationResultValue, source } from './isomorphic/utilityScriptSerializers'; import type { SerializedValue } from './isomorphic/utilityScriptSerializers'; diff --git a/packages/playwright-core/src/server/playwright.ts b/packages/playwright-core/src/server/playwright.ts index 6c9da633e9..309d351cca 100644 --- a/packages/playwright-core/src/server/playwright.ts +++ b/packages/playwright-core/src/server/playwright.ts @@ -27,7 +27,7 @@ import { createInstrumentation, SdkObject } from './instrumentation'; import { debugLogger } from '../common/debugLogger'; import type { Page } from './page'; import { DebugController } from './debugController'; -import type { Language } from './isomorphic/locatorGenerators'; +import type { Language } from '../utils/isomorphic/locatorGenerators'; export class Playwright extends SdkObject { readonly selectors: Selectors; diff --git a/packages/playwright-core/src/server/recorder.ts b/packages/playwright-core/src/server/recorder.ts index 6e803a2fee..2c3d50c018 100644 --- a/packages/playwright-core/src/server/recorder.ts +++ b/packages/playwright-core/src/server/recorder.ts @@ -41,7 +41,7 @@ import { Debugger } from './debugger'; import { EventEmitter } from 'events'; import { raceAgainstTimeout } from '../utils/timeoutRunner'; import type { Language, LanguageGenerator } from './recorder/language'; -import { locatorOrSelectorAsSelector } from './isomorphic/locatorParser'; +import { locatorOrSelectorAsSelector } from '../utils/isomorphic/locatorParser'; type BindingSource = { frame: Frame, page: Page }; diff --git a/packages/playwright-core/src/server/recorder/csharp.ts b/packages/playwright-core/src/server/recorder/csharp.ts index 7a374cd136..498d6d81fd 100644 --- a/packages/playwright-core/src/server/recorder/csharp.ts +++ b/packages/playwright-core/src/server/recorder/csharp.ts @@ -23,7 +23,7 @@ import type { MouseClickOptions } from './utils'; import { toModifiers } from './utils'; import { escapeWithQuotes } from '../../utils/isomorphic/stringUtils'; const deviceDescriptors = require('../deviceDescriptorsSource.json'); -import { asLocator } from '../isomorphic/locatorGenerators'; +import { asLocator } from '../../utils/isomorphic/locatorGenerators'; type CSharpLanguageMode = 'library' | 'mstest' | 'nunit'; diff --git a/packages/playwright-core/src/server/recorder/java.ts b/packages/playwright-core/src/server/recorder/java.ts index eacc24b06a..1c653740df 100644 --- a/packages/playwright-core/src/server/recorder/java.ts +++ b/packages/playwright-core/src/server/recorder/java.ts @@ -24,7 +24,7 @@ import { toModifiers } from './utils'; const deviceDescriptors = require('../deviceDescriptorsSource.json'); import { JavaScriptFormatter } from './javascript'; import { escapeWithQuotes } from '../../utils/isomorphic/stringUtils'; -import { asLocator } from '../isomorphic/locatorGenerators'; +import { asLocator } from '../../utils/isomorphic/locatorGenerators'; export class JavaLanguageGenerator implements LanguageGenerator { id = 'java'; diff --git a/packages/playwright-core/src/server/recorder/javascript.ts b/packages/playwright-core/src/server/recorder/javascript.ts index c919418544..6d1a27f5c1 100644 --- a/packages/playwright-core/src/server/recorder/javascript.ts +++ b/packages/playwright-core/src/server/recorder/javascript.ts @@ -23,7 +23,7 @@ import type { MouseClickOptions } from './utils'; import { toModifiers } from './utils'; const deviceDescriptors = require('../deviceDescriptorsSource.json'); import { escapeWithQuotes } from '../../utils/isomorphic/stringUtils'; -import { asLocator } from '../isomorphic/locatorGenerators'; +import { asLocator } from '../../utils/isomorphic/locatorGenerators'; export class JavaScriptLanguageGenerator implements LanguageGenerator { id: string; diff --git a/packages/playwright-core/src/server/recorder/language.ts b/packages/playwright-core/src/server/recorder/language.ts index bc6d0ead91..87b1a8fac4 100644 --- a/packages/playwright-core/src/server/recorder/language.ts +++ b/packages/playwright-core/src/server/recorder/language.ts @@ -15,10 +15,10 @@ */ import type { BrowserContextOptions, LaunchOptions } from '../../..'; -import type { Language } from '../isomorphic/locatorGenerators'; +import type { Language } from '../../utils/isomorphic/locatorGenerators'; import type { ActionInContext } from './codeGenerator'; import type { Action, DialogSignal, DownloadSignal, PopupSignal } from './recorderActions'; -export type { Language } from '../isomorphic/locatorGenerators'; +export type { Language } from '../../utils/isomorphic/locatorGenerators'; export type LanguageGeneratorOptions = { browserName: string; diff --git a/packages/playwright-core/src/server/recorder/python.ts b/packages/playwright-core/src/server/recorder/python.ts index 7b3ae576e7..e67f94491f 100644 --- a/packages/playwright-core/src/server/recorder/python.ts +++ b/packages/playwright-core/src/server/recorder/python.ts @@ -23,7 +23,7 @@ import type { MouseClickOptions } from './utils'; import { toModifiers } from './utils'; import { escapeWithQuotes, toSnakeCase } from '../../utils/isomorphic/stringUtils'; const deviceDescriptors = require('../deviceDescriptorsSource.json'); -import { asLocator } from '../isomorphic/locatorGenerators'; +import { asLocator } from '../../utils/isomorphic/locatorGenerators'; export class PythonLanguageGenerator implements LanguageGenerator { id: string; diff --git a/packages/playwright-core/src/server/screenshotter.ts b/packages/playwright-core/src/server/screenshotter.ts index 914df53837..05f6a160e0 100644 --- a/packages/playwright-core/src/server/screenshotter.ts +++ b/packages/playwright-core/src/server/screenshotter.ts @@ -20,7 +20,7 @@ import type { Rect } from '../common/types'; import { helper } from './helper'; import type { Page } from './page'; import type { Frame } from './frames'; -import type { ParsedSelector } from './isomorphic/selectorParser'; +import type { ParsedSelector } from '../utils/isomorphic/selectorParser'; import type * as types from './types'; import type { Progress } from './progress'; import { assert } from '../utils'; diff --git a/packages/playwright-core/src/server/selectors.ts b/packages/playwright-core/src/server/selectors.ts index 3a9923e86d..399f3b7198 100644 --- a/packages/playwright-core/src/server/selectors.ts +++ b/packages/playwright-core/src/server/selectors.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { allEngineNames, InvalidSelectorError, type ParsedSelector, parseSelector, stringifySelector } from './isomorphic/selectorParser'; +import { allEngineNames, InvalidSelectorError, type ParsedSelector, parseSelector, stringifySelector } from '../utils/isomorphic/selectorParser'; import { createGuid } from '../utils'; export class Selectors { diff --git a/packages/playwright-core/src/server/isomorphic/cssParser.ts b/packages/playwright-core/src/utils/isomorphic/cssParser.ts similarity index 100% rename from packages/playwright-core/src/server/isomorphic/cssParser.ts rename to packages/playwright-core/src/utils/isomorphic/cssParser.ts diff --git a/packages/playwright-core/src/server/isomorphic/cssTokenizer.ts b/packages/playwright-core/src/utils/isomorphic/cssTokenizer.ts similarity index 100% rename from packages/playwright-core/src/server/isomorphic/cssTokenizer.ts rename to packages/playwright-core/src/utils/isomorphic/cssTokenizer.ts diff --git a/packages/playwright-core/src/server/isomorphic/locatorGenerators.ts b/packages/playwright-core/src/utils/isomorphic/locatorGenerators.ts similarity index 96% rename from packages/playwright-core/src/server/isomorphic/locatorGenerators.ts rename to packages/playwright-core/src/utils/isomorphic/locatorGenerators.ts index 5f74fceef7..f1324b40f7 100644 --- a/packages/playwright-core/src/server/isomorphic/locatorGenerators.ts +++ b/packages/playwright-core/src/utils/isomorphic/locatorGenerators.ts @@ -14,9 +14,9 @@ * limitations under the License. */ -import { escapeWithQuotes, toSnakeCase, toTitleCase } from '../../utils/isomorphic/stringUtils'; -import { type NestedSelectorBody, parseAttributeSelector, parseSelector, stringifySelector } from '../isomorphic/selectorParser'; -import type { ParsedSelector } from '../isomorphic/selectorParser'; +import { escapeWithQuotes, toSnakeCase, toTitleCase } from './stringUtils'; +import { type NestedSelectorBody, parseAttributeSelector, parseSelector, stringifySelector } from './selectorParser'; +import type { ParsedSelector } from './selectorParser'; export type Language = 'javascript' | 'python' | 'java' | 'csharp'; export type LocatorType = 'default' | 'role' | 'text' | 'label' | 'placeholder' | 'alt' | 'title' | 'test-id' | 'nth' | 'first' | 'last' | 'has-text' | 'has' | 'frame'; @@ -27,8 +27,17 @@ export interface LocatorFactory { generateLocator(base: LocatorBase, kind: LocatorType, body: string | RegExp, options?: LocatorOptions): string; } -export function asLocator(lang: Language, selector: string, isFrameLocator: boolean = false): string { - return innerAsLocator(generators[lang], parseSelector(selector), isFrameLocator); +export function asLocator(lang: Language, selector: string, isFrameLocator: boolean = false, playSafe: boolean = false): string { + if (playSafe) { + try { + return innerAsLocator(generators[lang], parseSelector(selector), isFrameLocator); + } catch (e) { + // Tolerate invalid input. + return selector; + } + } else { + return innerAsLocator(generators[lang], parseSelector(selector), isFrameLocator); + } } function innerAsLocator(factory: LocatorFactory, parsed: ParsedSelector, isFrameLocator: boolean = false): string { diff --git a/packages/playwright-core/src/server/isomorphic/locatorParser.ts b/packages/playwright-core/src/utils/isomorphic/locatorParser.ts similarity index 100% rename from packages/playwright-core/src/server/isomorphic/locatorParser.ts rename to packages/playwright-core/src/utils/isomorphic/locatorParser.ts diff --git a/packages/playwright-core/src/server/isomorphic/selectorParser.ts b/packages/playwright-core/src/utils/isomorphic/selectorParser.ts similarity index 100% rename from packages/playwright-core/src/server/isomorphic/selectorParser.ts rename to packages/playwright-core/src/utils/isomorphic/selectorParser.ts diff --git a/packages/recorder/src/recorderTypes.ts b/packages/recorder/src/recorderTypes.ts index 5d79b3e263..302164321c 100644 --- a/packages/recorder/src/recorderTypes.ts +++ b/packages/recorder/src/recorderTypes.ts @@ -14,7 +14,7 @@ limitations under the License. */ -import type { Language } from '../../playwright-core/src/server/isomorphic/locatorGenerators'; +import type { Language } from '../../playwright-core/src/utils/isomorphic/locatorGenerators'; export type Point = { x: number, y: number }; diff --git a/packages/recorder/tsconfig.json b/packages/recorder/tsconfig.json index 405e2994b2..10f4bfcf2f 100644 --- a/packages/recorder/tsconfig.json +++ b/packages/recorder/tsconfig.json @@ -17,7 +17,7 @@ "baseUrl": ".", "useUnknownInCatchVariables": false, "paths": { - "@isomorphic/*": ["../playwright-core/src/server/isomorphic/*"], + "@isomorphic/*": ["../playwright-core/src/utils/isomorphic/*"], "@protocol/*": ["../protocol/src/*"], "@web/*": ["../web/src/*"], } diff --git a/packages/recorder/vite.config.ts b/packages/recorder/vite.config.ts index 80d1b4e67b..f1e42885cd 100644 --- a/packages/recorder/vite.config.ts +++ b/packages/recorder/vite.config.ts @@ -25,7 +25,7 @@ export default defineConfig({ ], resolve: { alias: { - '@isomorphic': path.resolve(__dirname, '../playwright-core/src/server/isomorphic'), + '@isomorphic': path.resolve(__dirname, '../playwright-core/src/utils/isomorphic'), '@protocol': path.resolve(__dirname, '../protocol/src'), '@web': path.resolve(__dirname, '../web/src'), }, diff --git a/packages/trace-viewer/src/entries.ts b/packages/trace-viewer/src/entries.ts index c55b4171b7..e74dfbffb3 100644 --- a/packages/trace-viewer/src/entries.ts +++ b/packages/trace-viewer/src/entries.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import type { Language } from '../../playwright-core/src/server/isomorphic/locatorGenerators'; +import type { Language } from '../../playwright-core/src/utils/isomorphic/locatorGenerators'; import type { ResourceSnapshot } from '@trace/snapshot'; import type * as trace from '@trace/trace'; diff --git a/packages/trace-viewer/tsconfig.json b/packages/trace-viewer/tsconfig.json index 1de869ca1c..17689aaa4d 100644 --- a/packages/trace-viewer/tsconfig.json +++ b/packages/trace-viewer/tsconfig.json @@ -17,7 +17,7 @@ "baseUrl": ".", "paths": { "@injected/*": ["../playwright-core/src/server/injected/*"], - "@isomorphic/*": ["../playwright-core/src/server/isomorphic/*"], + "@isomorphic/*": ["../playwright-core/src/utils/isomorphic/*"], "@protocol/*": ["../protocol/src/*"], "@recorder/*": ["../recorder/src/*"], "@trace/*": ["../trace/src/*"], diff --git a/packages/trace-viewer/vite.config.ts b/packages/trace-viewer/vite.config.ts index d6e09ea78a..efc0ba148e 100644 --- a/packages/trace-viewer/vite.config.ts +++ b/packages/trace-viewer/vite.config.ts @@ -30,7 +30,7 @@ export default defineConfig({ resolve: { alias: { '@injected': path.resolve(__dirname, '../playwright-core/src/server/injected'), - '@isomorphic': path.resolve(__dirname, '../playwright-core/src/server/isomorphic'), + '@isomorphic': path.resolve(__dirname, '../playwright-core/src/utils/isomorphic'), '@protocol': path.resolve(__dirname, '../protocol/src'), '@trace': path.resolve(__dirname, '../trace/src'), '@web': path.resolve(__dirname, '../web/src'), diff --git a/packages/trace-viewer/vite.sw.config.ts b/packages/trace-viewer/vite.sw.config.ts index f4da45137d..3fe9c9a168 100644 --- a/packages/trace-viewer/vite.sw.config.ts +++ b/packages/trace-viewer/vite.sw.config.ts @@ -29,7 +29,7 @@ export default defineConfig({ ], resolve: { alias: { - '@isomorphic': path.resolve(__dirname, '../playwright-core/src/server/isomorphic'), + '@isomorphic': path.resolve(__dirname, '../playwright-core/src/utils/isomorphic'), '@protocol': path.resolve(__dirname, '../protocol/src'), '@trace': path.resolve(__dirname, '../trace/src'), '@web': path.resolve(__dirname, '../web/src'), diff --git a/packages/trace/src/trace.ts b/packages/trace/src/trace.ts index 6940e25633..acd7a7215c 100644 --- a/packages/trace/src/trace.ts +++ b/packages/trace/src/trace.ts @@ -15,7 +15,7 @@ */ import type { Point, SerializedError, StackFrame } from '@protocol/channels'; -import type { Language } from '../../playwright-core/src/server/isomorphic/locatorGenerators'; +import type { Language } from '../../playwright-core/src/utils/isomorphic/locatorGenerators'; import type { FrameSnapshot, ResourceSnapshot } from './snapshot'; export type Size = { width: number, height: number }; diff --git a/tests/library/component-parser.spec.ts b/tests/library/component-parser.spec.ts index 86ded3acee..3ff3978478 100644 --- a/tests/library/component-parser.spec.ts +++ b/tests/library/component-parser.spec.ts @@ -15,8 +15,8 @@ */ import { playwrightTest as it, expect } from '../config/browserTest'; -import type { AttributeSelector } from '../../packages/playwright-core/src/server/isomorphic/selectorParser'; -import { parseAttributeSelector } from '../../packages/playwright-core/lib/server/isomorphic/selectorParser'; +import type { AttributeSelector } from '../../packages/playwright-core/src/utils/isomorphic/selectorParser'; +import { parseAttributeSelector } from '../../packages/playwright-core/lib/utils/isomorphic/selectorParser'; const parse = (selector: string) => parseAttributeSelector(selector, false); const serialize = (parsed: AttributeSelector) => { diff --git a/tests/library/css-parser.spec.ts b/tests/library/css-parser.spec.ts index bf15922543..3bf8a742e6 100644 --- a/tests/library/css-parser.spec.ts +++ b/tests/library/css-parser.spec.ts @@ -15,7 +15,7 @@ */ import { playwrightTest as it, expect } from '../config/browserTest'; -import { parseCSS, serializeSelector as serialize } from '../../packages/playwright-core/lib/server/isomorphic/cssParser'; +import { parseCSS, serializeSelector as serialize } from '../../packages/playwright-core/lib/utils/isomorphic/cssParser'; const parse = (selector: string) => { return parseCSS(selector, new Set(['text', 'not', 'has', 'react', 'scope', 'right-of', 'is'])).selector; diff --git a/tests/library/locator-generator.spec.ts b/tests/library/locator-generator.spec.ts index 81a057b5b2..e6e8047ff2 100644 --- a/tests/library/locator-generator.spec.ts +++ b/tests/library/locator-generator.spec.ts @@ -15,8 +15,8 @@ */ import { contextTest as it, expect } from '../config/browserTest'; -import { asLocator } from '../../packages/playwright-core/lib/server/isomorphic/locatorGenerators'; -import { locatorOrSelectorAsSelector as parseLocator } from '../../packages/playwright-core/lib/server/isomorphic/locatorParser'; +import { asLocator } from '../../packages/playwright-core/lib/utils/isomorphic/locatorGenerators'; +import { locatorOrSelectorAsSelector as parseLocator } from '../../packages/playwright-core/lib/utils/isomorphic/locatorParser'; import type { Page, Frame, Locator, FrameLocator } from 'playwright-core'; it.skip(({ mode }) => mode !== 'default'); diff --git a/tests/playwright-test/reporter.spec.ts b/tests/playwright-test/reporter.spec.ts index 4781a8bd78..2422ebd7fe 100644 --- a/tests/playwright-test/reporter.spec.ts +++ b/tests/playwright-test/reporter.spec.ts @@ -295,6 +295,7 @@ test('should report api steps', async ({ runInlineTest }) => { page.goto('data:text/html,'), ]); await page.click('button'); + await page.getByRole('button').click(); await page.request.get('http://localhost2').catch(() => {}); await request.get('http://localhost2').catch(() => {}); }); @@ -332,6 +333,8 @@ test('should report api steps', async ({ runInlineTest }) => { `end {\"title\":\"page.goto(data:text/html,)\",\"category\":\"pw:api\"}`, `begin {\"title\":\"page.click(button)\",\"category\":\"pw:api\"}`, `end {\"title\":\"page.click(button)\",\"category\":\"pw:api\"}`, + `begin {\"title\":\"locator.getByRole('button').click\",\"category\":\"pw:api\"}`, + `end {\"title\":\"locator.getByRole('button').click\",\"category\":\"pw:api\"}`, `begin {"title":"apiRequestContext.get(http://localhost2)","category":"pw:api"}`, `end {"title":"apiRequestContext.get(http://localhost2)","category":"pw:api","error":{"message":"","stack":""}}`, `begin {"title":"apiRequestContext.get(http://localhost2)","category":"pw:api"}`, diff --git a/tsconfig.json b/tsconfig.json index c81ac3ab54..ce56169d58 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,7 +12,7 @@ */ "@html-reporter/*": ["./packages/html-reporter/src/*"], "@injected/*": ["./packages/playwright-core/src/server/injected/*"], - "@isomorphic/*": ["./packages/playwright-core/src/server/isomorphic/*"], + "@isomorphic/*": ["./packages/playwright-core/src/utils/isomorphic/*"], "@protocol/*": ["./packages/protocol/src/*"], "@recorder/*": ["./packages/recorder/src/*"], "@trace/*": ["./packages/trace/src/*"], diff --git a/utils/build/build.js b/utils/build/build.js index f8001bb0fc..c2e5382014 100644 --- a/utils/build/build.js +++ b/utils/build/build.js @@ -283,7 +283,7 @@ steps.push({ onChanges.push({ inputs: [ 'packages/playwright-core/src/server/injected/**', - 'packages/playwright-core/src/server/isomorphic/**', + 'packages/playwright-core/src/utils/isomorphic/**', 'utils/generate_injected.js', ], script: 'utils/generate_injected.js', diff --git a/utils/check_deps.js b/utils/check_deps.js index cd2bc3b64b..800598e238 100644 --- a/utils/check_deps.js +++ b/utils/check_deps.js @@ -28,7 +28,7 @@ const packages = new Map(); for (const package of fs.readdirSync(packagesDir)) packages.set(package, packagesDir + '/' + package + '/src/'); packages.set('injected', packagesDir + '/playwright-core/src/server/injected/'); -packages.set('isomorphic', packagesDir + '/playwright-core/src/server/isomorphic/'); +packages.set('isomorphic', packagesDir + '/playwright-core/src/utils/isomorphic/'); const peerDependencies = ['electron', 'react', 'react-dom', '@zip.js/zip.js'];