diff --git a/src/api/skip-js-errors/index.ts b/src/api/skip-js-errors/index.ts index 423ef645053..e2dc969952b 100644 --- a/src/api/skip-js-errors/index.ts +++ b/src/api/skip-js-errors/index.ts @@ -2,7 +2,7 @@ import { Dictionary, SkipJsErrorsCallback, SkipJsErrorsCallbackWithOptionsObject, SkipJsErrorsOptionsObject, } from '../../configuration/interfaces'; import { parseRegExpString } from '../../utils/make-reg-exp'; -import { ExecuteClientFunctionCommand } from '../../test-run/commands/observation'; +import { ExecuteClientFunctionCommand } from '../../test-run/commands/execute-client-function'; import ClientFunctionBuilder from '../../client-functions/client-function-builder'; const SKIP_JS_ERRORS_OBJECT_FUNCTION = ` diff --git a/src/api/test-controller/index.js b/src/api/test-controller/index.js index a92269d87fc..0f5c4d3395f 100644 --- a/src/api/test-controller/index.js +++ b/src/api/test-controller/index.js @@ -602,8 +602,8 @@ export default class TestController { return new Assertion(actual, this, callsite); } - [delegatedAPI(DebugCommand.methodName)] () { - return this.enqueueCommand(DebugCommand); + [delegatedAPI(DebugCommand.methodName)] (selector) { + return this.enqueueCommand(DebugCommand, { selector }); } [delegatedAPI(SetTestSpeedCommand.methodName)] (speed) { diff --git a/src/client-functions/client-function-builder.js b/src/client-functions/client-function-builder.js index 42807fcf9ba..53063783425 100644 --- a/src/client-functions/client-function-builder.js +++ b/src/client-functions/client-function-builder.js @@ -2,7 +2,7 @@ import { isNil as isNullOrUndefined, assign } from 'lodash'; import testRunTracker from '../api/test-run-tracker'; import functionBuilderSymbol from './builder-symbol'; import { createReplicator, FunctionTransform } from './replicator'; -import { ExecuteClientFunctionCommand } from '../test-run/commands/observation'; +import { ExecuteClientFunctionCommand } from '../test-run/commands/execute-client-function'; import compileClientFunction from '../compiler/compile-client-function'; import { APIError, ClientFunctionAPIError } from '../errors/runtime'; import { assertType, is } from '../errors/runtime/type-assertions'; diff --git a/src/client-functions/selectors/selector-builder.js b/src/client-functions/selectors/selector-builder.js index 89af395b4c9..11e7fc17b19 100644 --- a/src/client-functions/selectors/selector-builder.js +++ b/src/client-functions/selectors/selector-builder.js @@ -6,7 +6,7 @@ import { ClientFunctionAPIError } from '../../errors/runtime'; import functionBuilderSymbol from '../builder-symbol'; import { RUNTIME_ERRORS } from '../../errors/types'; import { assertType, is } from '../../errors/runtime/type-assertions'; -import { ExecuteSelectorCommand } from '../../test-run/commands/observation'; +import { ExecuteSelectorCommand } from '../../test-run/commands/execute-client-function'; import defineLazyProperty from '../../utils/define-lazy-property'; import { addAPI, addCustomMethods } from './add-api'; import createSnapshotMethods from './create-snapshot-methods'; diff --git a/src/client/driver/command-executors/action-executor/elements-retriever.ts b/src/client/driver/command-executors/action-executor/elements-retriever.ts index 50e4d62d66c..afd3890da25 100644 --- a/src/client/driver/command-executors/action-executor/elements-retriever.ts +++ b/src/client/driver/command-executors/action-executor/elements-retriever.ts @@ -1,4 +1,4 @@ -import { ExecuteSelectorCommand } from '../../../../test-run/commands/observation'; +import { ExecuteSelectorCommand } from '../../../../test-run/commands/execute-client-function'; import { ExecuteSelectorFn } from '../../../../shared/types'; import NODE_TYPE_DESCRIPTIONS from '../../node-type-descriptions'; import { diff --git a/src/client/driver/command-executors/client-functions/client-function-executor.ts b/src/client/driver/command-executors/client-functions/client-function-executor.ts index c2df8aeebd6..3a1effc6e2b 100644 --- a/src/client/driver/command-executors/client-functions/client-function-executor.ts +++ b/src/client/driver/command-executors/client-functions/client-function-executor.ts @@ -4,7 +4,7 @@ import ClientFunctionNodeTransform from './replicator/transforms/client-function import evalFunction from './eval-function'; import { UncaughtErrorInClientFunctionCode } from '../../../../shared/errors/index'; import Replicator from 'replicator'; -import { ExecuteClientFunctionCommand, ExecuteClientFunctionCommandBase } from '../../../../test-run/commands/observation'; +import { ExecuteClientFunctionCommand, ExecuteClientFunctionCommandBase } from '../../../../test-run/commands/execute-client-function'; import { Dictionary } from '../../../../configuration/interfaces'; // @ts-ignore import { Promise } from '../../deps/hammerhead'; diff --git a/src/client/driver/command-executors/client-functions/selector-executor/index.ts b/src/client/driver/command-executors/client-functions/selector-executor/index.ts index 72f6dcbced7..2907be829e7 100644 --- a/src/client/driver/command-executors/client-functions/selector-executor/index.ts +++ b/src/client/driver/command-executors/client-functions/selector-executor/index.ts @@ -2,7 +2,7 @@ import ClientFunctionExecutor from '../client-function-executor'; import createReplicator from '../replicator/index'; import FunctionTransform from '../replicator/transforms/function-transform'; import SelectorNodeTransform from '../replicator/transforms/selector-node-transform'; -import { ExecuteSelectorCommand } from '../../../../../test-run/commands/observation'; +import { ExecuteSelectorCommand } from '../../../../../test-run/commands/execute-client-function'; import { SelectorErrorParams, SelectorDependencies, diff --git a/src/client/driver/driver.js b/src/client/driver/driver.js index fad4bf07d0a..4de540d77a7 100644 --- a/src/client/driver/driver.js +++ b/src/client/driver/driver.js @@ -1527,10 +1527,10 @@ export default class Driver extends serviceUtils.EventEmitter { }); } - _onSetBreakpointCommand ({ isTestError }) { + _onSetBreakpointCommand ({ isTestError, selector }) { const showDebuggingStatusPromise = this.statusBar.showDebuggingStatus(isTestError); - this.selectorInspectorPanel.show(); + this.selectorInspectorPanel.show(selector); showDebuggingStatusPromise.then(debug => { const stopAfterNextAction = debug === STATUS_BAR_DEBUG_ACTION.step; diff --git a/src/client/ui/selector-inspector-panel/index.js b/src/client/ui/selector-inspector-panel/index.js index 465f3f8a9c5..ee8ed1b29a4 100644 --- a/src/client/ui/selector-inspector-panel/index.js +++ b/src/client/ui/selector-inspector-panel/index.js @@ -14,19 +14,20 @@ export default class SelectorInspectorPanel { elementPicker = elementPicker; constructor () { - this.element = createElementFromDescriptor(panel); - + this.element = createElementFromDescriptor(panel); + this.selectorInputContainer = new SelectorInputContainer(); const pickButton = new PickButton(); - const selectorInputContainer = new SelectorInputContainer(); - const copyButton = new CopyButton(selectorInputContainer); - const container = new MainContainer(pickButton.element, selectorInputContainer.element, copyButton.element); + const copyButton = new CopyButton(this.selectorInputContainer); + const container = new MainContainer(pickButton.element, this.selectorInputContainer.element, copyButton.element); const hideButton = new HideButton(this.element); this.element.appendChild(container.element); this.element.appendChild(hideButton.element); } - show () { + show (selector) { + this.selectorInputContainer.debugSelector(selector); + if (!this.element.parentElement) uiRoot.insertFirstChildToPanelsContainer(this.element); diff --git a/src/client/ui/selector-inspector-panel/selector-input-container.js b/src/client/ui/selector-inspector-panel/selector-input-container.js index bb669a8304e..9866f535094 100644 --- a/src/client/ui/selector-inspector-panel/selector-input-container.js +++ b/src/client/ui/selector-inspector-panel/selector-input-container.js @@ -3,7 +3,8 @@ import hammerhead from './../deps/hammerhead'; import testCafeCore from './../deps/testcafe-core'; import { createElementFromDescriptor } from './utils/create-element-from-descriptor'; -import { getElementsBySelector } from './utils/get-elements-by-selector'; +import { getElementsBySelector, executeSelector } from './utils/get-elements-by-selector'; +import { castArray } from './utils/cast-array'; import * as descriptors from './descriptors'; import { elementPicker, ELEMENT_PICKED } from './element-picker'; @@ -159,4 +160,14 @@ export class SelectorInputContainer { this._indicateMatches(elements); this._highlightElements(elements); } + + async debugSelector (selector) { + highlighter.stopHighlighting(); + + this.value = selector.apiFnChain.join(''); + const elements = castArray(await executeSelector(selector)); + + this._indicateMatches(elements); + this._highlightElements(elements); + } } diff --git a/src/client/ui/selector-inspector-panel/utils/cast-array.js b/src/client/ui/selector-inspector-panel/utils/cast-array.js new file mode 100644 index 00000000000..63a9f792177 --- /dev/null +++ b/src/client/ui/selector-inspector-panel/utils/cast-array.js @@ -0,0 +1,7 @@ +import hammerhead from '../../deps/hammerhead'; + +const nativeMethods = hammerhead.nativeMethods; + +export function castArray (elements) { + return nativeMethods.isArray(elements) ? elements : [elements]; +} diff --git a/src/client/ui/selector-inspector-panel/utils/get-elements-by-selector.js b/src/client/ui/selector-inspector-panel/utils/get-elements-by-selector.js index 5a554d075c4..711a452daf3 100644 --- a/src/client/ui/selector-inspector-panel/utils/get-elements-by-selector.js +++ b/src/client/ui/selector-inspector-panel/utils/get-elements-by-selector.js @@ -20,7 +20,7 @@ async function parseSelector (selector) { return browser.parseSelector(communicationUrls.parseSelector, createNativeXHR, selector); } -async function executeSelector (parsedSelector) { +export async function executeSelector (parsedSelector) { const startTime = nativeMethods.date(); const selectorExecutor = new SelectorExecutor(parsedSelector, GLOBAL_TIMEOUT, startTime, createNotFoundError, createIsInvisibleError); const elements = await selectorExecutor.getResult(); diff --git a/src/reporter/command/command-formatter.ts b/src/reporter/command/command-formatter.ts index b75f00b6076..e87a7c349a1 100644 --- a/src/reporter/command/command-formatter.ts +++ b/src/reporter/command/command-formatter.ts @@ -1,5 +1,5 @@ import { isEmpty } from 'lodash'; -import { ExecuteSelectorCommand, ExecuteClientFunctionCommand } from '../../test-run/commands/observation'; +import { ExecuteSelectorCommand, ExecuteClientFunctionCommand } from '../../test-run/commands/execute-client-function'; import { NavigateToCommand, PressKeyCommand, diff --git a/src/shared/types.d.ts b/src/shared/types.d.ts index 401684901b3..f6fca23f716 100644 --- a/src/shared/types.d.ts +++ b/src/shared/types.d.ts @@ -1,6 +1,6 @@ /* global globalThis */ -import { ExecuteSelectorCommand } from '../test-run/commands/observation'; +import { ExecuteSelectorCommand } from '../test-run/commands/execute-client-function'; export interface NativeMethods { setTimeout: typeof globalThis.setTimeout; diff --git a/src/test-run/bookmark.ts b/src/test-run/bookmark.ts index 68e63b9aa4e..82489ca98a5 100644 --- a/src/test-run/bookmark.ts +++ b/src/test-run/bookmark.ts @@ -12,7 +12,7 @@ import { import { CurrentIframeNotFoundError, CurrentIframeIsNotLoadedError } from '../errors/test-run'; import TestRun from './index'; -import { ExecuteClientFunctionCommand, ExecuteSelectorCommand } from './commands/observation'; +import { ExecuteClientFunctionCommand, ExecuteSelectorCommand } from './commands/execute-client-function'; import Role, { RedirectUrl } from '../role/role'; import { DEFAULT_SPEED_VALUE } from '../configuration/default-values'; import BrowserConsoleMessages from './browser-console-messages'; diff --git a/src/test-run/commands/actions.d.ts b/src/test-run/commands/actions.d.ts index b9dd7c8ee85..07b07fe8d94 100644 --- a/src/test-run/commands/actions.d.ts +++ b/src/test-run/commands/actions.d.ts @@ -1,5 +1,5 @@ import { ActionCommandBase, CommandBase } from './base'; -import { ExecuteClientFunctionCommand, ExecuteSelectorCommand } from './observation'; +import { ExecuteClientFunctionCommand, ExecuteSelectorCommand } from './execute-client-function'; import { ActionOptions, diff --git a/src/test-run/commands/actions.js b/src/test-run/commands/actions.js index 630135a91b3..df4a55df651 100644 --- a/src/test-run/commands/actions.js +++ b/src/test-run/commands/actions.js @@ -48,7 +48,7 @@ import { } from './validations/argument'; import { SetNativeDialogHandlerCodeWrongTypeError } from '../../errors/test-run'; -import { ExecuteClientFunctionCommand } from './observation'; +import { ExecuteClientFunctionCommand } from './execute-client-function'; import { camelCase } from 'lodash'; import { prepareSkipJsErrorsOptions, diff --git a/src/test-run/commands/execute-client-function.d.ts b/src/test-run/commands/execute-client-function.d.ts new file mode 100644 index 00000000000..176f4e2b8d5 --- /dev/null +++ b/src/test-run/commands/execute-client-function.d.ts @@ -0,0 +1,24 @@ +import { CommandBase } from './base'; +import TestRun from '../index'; + +declare class ExecuteClientFunctionCommandBase extends CommandBase { + public constructor(obj: object, testRun: TestRun, type: string); + public instantiationCallsiteName: string; + public fnCode: string; + public args: string[]; + public dependencies: string[]; +} + +export class ExecuteClientFunctionCommand extends ExecuteClientFunctionCommandBase { + public constructor(obj: object, testRun: TestRun); +} + +export class ExecuteSelectorCommand extends ExecuteClientFunctionCommandBase { + public constructor(obj: object, testRun: TestRun); + public visibilityCheck: boolean; + public timeout?: number; + public apiFnChain: string[]; + public needError: boolean; + public index: number; + public strictError: boolean; +} diff --git a/src/test-run/commands/execute-client-function.js b/src/test-run/commands/execute-client-function.js new file mode 100644 index 00000000000..02fde995bd7 --- /dev/null +++ b/src/test-run/commands/execute-client-function.js @@ -0,0 +1,44 @@ +import TYPE from './type'; +import { ActionCommandBase } from './base'; + +export class ExecuteClientFunctionCommandBase extends ActionCommandBase { + constructor (obj, testRun, type) { + super(obj, testRun, type, false); + } + + getAssignableProperties () { + return [ + { name: 'instantiationCallsiteName', defaultValue: '' }, + { name: 'fnCode', defaultValue: '' }, + { name: 'args', defaultValue: [] }, + { name: 'dependencies', defaultValue: [] }, + ]; + } +} + +export class ExecuteClientFunctionCommand extends ExecuteClientFunctionCommandBase { + static methodName = TYPE.executeClientFunction; + + constructor (obj, testRun) { + super(obj, testRun, TYPE.executeClientFunction); + } +} + +export class ExecuteSelectorCommand extends ExecuteClientFunctionCommandBase { + static methodName = TYPE.executeSelector; + + constructor (obj, testRun) { + super(obj, testRun, TYPE.executeSelector); + } + + getAssignableProperties () { + return [ + { name: 'visibilityCheck', defaultValue: false }, + { name: 'timeout', defaultValue: null }, + { name: 'apiFnChain' }, + { name: 'needError' }, + { name: 'index', defaultValue: 0 }, + { name: 'strictError' }, + ]; + } +} diff --git a/src/test-run/commands/observation.d.ts b/src/test-run/commands/observation.d.ts index 6cd97edfec9..ab9c9924e78 100644 --- a/src/test-run/commands/observation.d.ts +++ b/src/test-run/commands/observation.d.ts @@ -1,31 +1,13 @@ -import { CommandBase, ActionCommandBase } from './base'; +import { ActionCommandBase } from './base'; +import { ExecuteClientFunctionCommand } from './execute-client-function'; import TestRun from '../index'; -declare class ExecuteClientFunctionCommandBase extends CommandBase { - public constructor(obj: object, testRun: TestRun, type: string); - public instantiationCallsiteName: string; - public fnCode: string; - public args: string[]; - public dependencies: string[]; -} - -export class ExecuteClientFunctionCommand extends ExecuteClientFunctionCommandBase { - public constructor(obj: object, testRun: TestRun); -} - -export class ExecuteSelectorCommand extends ExecuteClientFunctionCommandBase { - public constructor(obj: object, testRun: TestRun); - public visibilityCheck: boolean; - public timeout?: number; - public apiFnChain: string[]; - public needError: boolean; - public index: number; - public strictError: boolean; -} - export class WaitCommand extends ActionCommandBase { public constructor(obj: object, testRun: TestRun); public timeout: number; } -export class DebugCommand extends ActionCommandBase { } +export class DebugCommand extends ActionCommandBase { + public constructor(obj: object, testRun: TestRun, validateProperties?: boolean); + public selector?: ExecuteClientFunctionCommand; +} diff --git a/src/test-run/commands/observation.js b/src/test-run/commands/observation.js index e86267b70f5..c362467c11e 100644 --- a/src/test-run/commands/observation.js +++ b/src/test-run/commands/observation.js @@ -2,6 +2,15 @@ import TYPE from './type'; import { ActionCommandBase } from './base'; import { positiveIntegerArgument } from './validations/argument'; import { camelCase } from 'lodash'; +import { initSelector } from './validations/initializers'; + + +// Initializers +function initDebugOptions (name, val, options) { + return initSelector(name, val, Object.assign({}, options, + { skipVisibilityCheck: true, collectionMode: true } + )); +} // Commands export class WaitCommand extends ActionCommandBase { @@ -18,52 +27,16 @@ export class WaitCommand extends ActionCommandBase { } } -export class ExecuteClientFunctionCommandBase extends ActionCommandBase { - constructor (obj, testRun, type) { - super(obj, testRun, type, false); - } - - getAssignableProperties () { - return [ - { name: 'instantiationCallsiteName', defaultValue: '' }, - { name: 'fnCode', defaultValue: '' }, - { name: 'args', defaultValue: [] }, - { name: 'dependencies', defaultValue: [] }, - ]; - } -} - -export class ExecuteClientFunctionCommand extends ExecuteClientFunctionCommandBase { - static methodName = TYPE.executeClientFunction; - - constructor (obj, testRun) { - super(obj, testRun, TYPE.executeClientFunction); - } -} - -export class ExecuteSelectorCommand extends ExecuteClientFunctionCommandBase { - static methodName = TYPE.executeSelector; +export class DebugCommand extends ActionCommandBase { + static methodName = camelCase(TYPE.debug); constructor (obj, testRun) { - super(obj, testRun, TYPE.executeSelector); + super(obj, testRun, TYPE.debug); } getAssignableProperties () { return [ - { name: 'visibilityCheck', defaultValue: false }, - { name: 'timeout', defaultValue: null }, - { name: 'apiFnChain' }, - { name: 'needError' }, - { name: 'index', defaultValue: 0 }, - { name: 'strictError' }, + { name: 'selector', init: initDebugOptions, required: false }, ]; } } - -export class DebugCommand extends ActionCommandBase { - static methodName = camelCase(TYPE.debug); - - constructor () { - super(null, null, TYPE.debug); - } -} diff --git a/src/test-run/commands/service.js b/src/test-run/commands/service.js index 2dd4ac9006e..b283f9b43f7 100644 --- a/src/test-run/commands/service.js +++ b/src/test-run/commands/service.js @@ -16,9 +16,10 @@ export class HideAssertionRetriesStatusCommand { } export class SetBreakpointCommand { - constructor (isTestError) { + constructor (isTestError, selector) { this.type = TYPE.setBreakpoint; this.isTestError = isTestError; + this.selector = selector; } } diff --git a/src/test-run/commands/validations/initializers.js b/src/test-run/commands/validations/initializers.js index e1c2e2335ae..9e4905ce014 100644 --- a/src/test-run/commands/validations/initializers.js +++ b/src/test-run/commands/validations/initializers.js @@ -1,7 +1,7 @@ import SelectorBuilder from '../../../client-functions/selectors/selector-builder'; import { ActionSelectorError } from '../../../errors/test-run'; import { APIError } from '../../../errors/runtime'; -import { ExecuteSelectorCommand } from '../observation'; +import { ExecuteSelectorCommand } from '../execute-client-function'; import { executeJsExpression } from '../../execute-js-expression'; import { isJSExpression } from '../utils'; diff --git a/src/test-run/index.ts b/src/test-run/index.ts index 45bd0d0b62e..872ea90304f 100644 --- a/src/test-run/index.ts +++ b/src/test-run/index.ts @@ -75,6 +75,7 @@ import { RemoveRequestHooksCommand, RunCustomActionCommand, } from './commands/actions'; +import { DebugCommand } from './commands/observation'; import { RUNTIME_ERRORS, TEST_RUN_ERRORS } from '../errors/types'; import processTestFnError from '../errors/process-test-fn-error'; @@ -107,7 +108,7 @@ import TestRunPhase from './phase'; import { ExecuteClientFunctionCommand, ExecuteSelectorCommand, -} from './commands/observation'; +} from './commands/execute-client-function'; import addRenderedWarning from '../notifications/add-rendered-warning'; import getBrowser from '../utils/get-browser'; @@ -136,13 +137,13 @@ import NativeAutomationRequestPipeline from '../native-automation/request-pipeli import { NativeAutomationBase } from '../native-automation'; import ReportDataLog from '../reporter/report-data-log'; -const lazyRequire = require('import-lazy')(require); -const ClientFunctionBuilder = lazyRequire('../client-functions/client-function-builder'); -const TestRunBookmark = lazyRequire('./bookmark'); -const actionCommands = lazyRequire('./commands/actions'); -const browserManipulationCommands = lazyRequire('./commands/browser-manipulation'); -const serviceCommands = lazyRequire('./commands/service'); -const observationCommands = lazyRequire('./commands/observation'); +const lazyRequire = require('import-lazy')(require); +const ClientFunctionBuilder = lazyRequire('../client-functions/client-function-builder'); +const TestRunBookmark = lazyRequire('./bookmark'); +const actionCommands = lazyRequire('./commands/actions'); +const browserManipulationCommands = lazyRequire('./commands/browser-manipulation'); +const serviceCommands = lazyRequire('./commands/service'); +const executeClientFunctionCommands = lazyRequire('./commands/execute-client-function'); const { executeJsExpression, executeAsyncJsExpression } = lazyRequire('./execute-js-expression'); @@ -709,7 +710,7 @@ export default class TestRun extends AsyncEventEmitter { if (this.errs.length && this.debugOnFail) { const errStr = this.debugReporterPluginHost.formatError(this.errs[0]); - await this._enqueueSetBreakpointCommand(void 0, errStr); + await this._enqueueSetBreakpointCommand(void 0, null, errStr); } await this.emit('before-done'); @@ -832,11 +833,11 @@ export default class TestRun extends AsyncEventEmitter { return this.cookieProvider.deleteCookies(cookies, urls); } - private async _enqueueSetBreakpointCommand (callsite: CallsiteRecord | undefined, error?: string): Promise { + private async _enqueueSetBreakpointCommand (callsite: CallsiteRecord | undefined, selector?: object | null, error?: string): Promise { if (this.debugLogger) this.debugLogger.showBreakpoint(this.session.id, this.browserConnection.userAgent, callsite, error); - this.debugging = await this._internalExecuteCommand(new serviceCommands.SetBreakpointCommand(!!error), callsite) as boolean; + this.debugging = await this._internalExecuteCommand(new serviceCommands.SetBreakpointCommand(!!error, selector), callsite) as boolean; } private _removeAllNonServiceTasks (): void { @@ -891,7 +892,7 @@ export default class TestRun extends AsyncEventEmitter { private _shouldResolveCurrentDriverTask (driverStatus: DriverStatus): boolean { const currentCommand = this.currentDriverTask.command; - const isExecutingObservationCommand = currentCommand instanceof observationCommands.ExecuteSelectorCommand || + const isExecutingObservationCommand = currentCommand instanceof executeClientFunctionCommands.ExecuteSelectorCommand || currentCommand instanceof ExecuteClientFunctionCommand; const isDebugActive = currentCommand instanceof serviceCommands.SetBreakpointCommand; @@ -1165,7 +1166,7 @@ export default class TestRun extends AsyncEventEmitter { const canDebug = !this.browserConnection.isHeadlessBrowser(); if (canDebug) - return await this._enqueueSetBreakpointCommand(callsite as CallsiteRecord, void 0); + return await this._enqueueSetBreakpointCommand(callsite as CallsiteRecord, (command as DebugCommand)?.selector, void 0); this.debugging = false; diff --git a/test/functional/fixtures/ui/test.js b/test/functional/fixtures/ui/test.js index e9ffa9a7d1b..f398b477d98 100644 --- a/test/functional/fixtures/ui/test.js +++ b/test/functional/fixtures/ui/test.js @@ -43,5 +43,9 @@ describe('TestCafe UI', () => { runTestCafeTest('should copy selector'); runTestCafeTest('should hide panel'); + + runTestCafeTest('should indicate the correct number of elements matching the TestCafe selector passed in debug'); + + runTestCafeTest('should indicate single element matching the TestCafe selector passed in debug'); }); }); diff --git a/test/functional/fixtures/ui/testcafe-fixtures/selector-inspector-test.js b/test/functional/fixtures/ui/testcafe-fixtures/selector-inspector-test.js index e35b9a92e8c..11386736fe7 100644 --- a/test/functional/fixtures/ui/testcafe-fixtures/selector-inspector-test.js +++ b/test/functional/fixtures/ui/testcafe-fixtures/selector-inspector-test.js @@ -283,3 +283,31 @@ test('should hide panel', async t => { await t.debug(); }); + +test('should indicate the correct number of elements matching the TestCafe selector passed in debug', async t => { + await ClientFunction(() => { + const { getMatchIndicatorInnerText, resumeTest } = window; + + getMatchIndicatorInnerText() + .then(text => { + if (text === 'Found: 5') + resumeTest(); + }); + })(); + + await t.debug('p'); +}); + +test('should indicate single element matching the TestCafe selector passed in debug', async t => { + await ClientFunction(() => { + const { getMatchIndicatorInnerText, resumeTest } = window; + + getMatchIndicatorInnerText() + .then(text => { + if (text === 'Found: 1') + resumeTest(); + }); + })(); + + await t.debug('#container'); +}); diff --git a/test/server/data/test-controller-reporter-expected/index.js b/test/server/data/test-controller-reporter-expected/index.js index 4c4710fd8a1..865ee0899a2 100644 --- a/test/server/data/test-controller-reporter-expected/index.js +++ b/test/server/data/test-controller-reporter-expected/index.js @@ -747,6 +747,7 @@ module.exports = { name: 'debug', command: { type: 'debug', + selector: undefined, actionId: 'DebugCommand', }, test: {