mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-15 22:22:53 +03:00
chore: add input logging and timeout debugging hints (#2109)
This commit is contained in:
parent
0bb1ba177c
commit
1c17929bd8
32
src/dom.ts
32
src/dom.ts
@ -227,17 +227,18 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||||||
return point;
|
return point;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _retryPointerAction(action: (point: types.Point) => Promise<void>, options: PointerActionOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}): Promise<void> {
|
async _retryPointerAction(actionName: string, action: (point: types.Point) => Promise<void>, options: PointerActionOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}): Promise<void> {
|
||||||
|
this._page._log(inputLog, `elementHandle.${actionName}()`);
|
||||||
const deadline = this._page._timeoutSettings.computeDeadline(options);
|
const deadline = this._page._timeoutSettings.computeDeadline(options);
|
||||||
while (!helper.isPastDeadline(deadline)) {
|
while (!helper.isPastDeadline(deadline)) {
|
||||||
const result = await this._performPointerAction(action, deadline, options);
|
const result = await this._performPointerAction(actionName, action, deadline, options);
|
||||||
if (result === 'done')
|
if (result === 'done')
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
throw new TimeoutError(`waiting for element to receive pointer events failed: timeout exceeded`);
|
throw new TimeoutError(`waiting for element to receive pointer events failed: timeout exceeded. Re-run with the DEBUG=pw:input env variable to see the debug log.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _performPointerAction(action: (point: types.Point) => Promise<void>, deadline: number, options: PointerActionOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}): Promise<'done' | 'retry'> {
|
async _performPointerAction(actionName: string, action: (point: types.Point) => Promise<void>, deadline: number, options: PointerActionOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}): Promise<'done' | 'retry'> {
|
||||||
const { force = false, position } = options;
|
const { force = false, position } = options;
|
||||||
if (!force)
|
if (!force)
|
||||||
await this._waitForDisplayedAtStablePosition(deadline);
|
await this._waitForDisplayedAtStablePosition(deadline);
|
||||||
@ -271,10 +272,10 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||||||
let restoreModifiers: input.Modifier[] | undefined;
|
let restoreModifiers: input.Modifier[] | undefined;
|
||||||
if (options && options.modifiers)
|
if (options && options.modifiers)
|
||||||
restoreModifiers = await this._page.keyboard._ensureModifiers(options.modifiers);
|
restoreModifiers = await this._page.keyboard._ensureModifiers(options.modifiers);
|
||||||
this._page._log(inputLog, 'performing input action...');
|
this._page._log(inputLog, `performing "${actionName}" action...`);
|
||||||
await action(point);
|
await action(point);
|
||||||
this._page._log(inputLog, '...input action done');
|
this._page._log(inputLog, `... "${actionName}" action done`);
|
||||||
this._page._log(inputLog, 'waiting for navigations to finish...');
|
this._page._log(inputLog, 'waiting for scheduled navigations to finish...');
|
||||||
await this._page._delegate.setActivityPaused(false);
|
await this._page._delegate.setActivityPaused(false);
|
||||||
paused = false;
|
paused = false;
|
||||||
if (restoreModifiers)
|
if (restoreModifiers)
|
||||||
@ -290,18 +291,19 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hover(options?: PointerActionOptions & types.PointerActionWaitOptions): Promise<void> {
|
hover(options?: PointerActionOptions & types.PointerActionWaitOptions): Promise<void> {
|
||||||
return this._retryPointerAction(point => this._page.mouse.move(point.x, point.y), options);
|
return this._retryPointerAction('hover', point => this._page.mouse.move(point.x, point.y), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
click(options?: ClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions): Promise<void> {
|
click(options?: ClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions): Promise<void> {
|
||||||
return this._retryPointerAction(point => this._page.mouse.click(point.x, point.y, options), options);
|
return this._retryPointerAction('click', point => this._page.mouse.click(point.x, point.y, options), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
dblclick(options?: MultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions): Promise<void> {
|
dblclick(options?: MultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions): Promise<void> {
|
||||||
return this._retryPointerAction(point => this._page.mouse.dblclick(point.x, point.y, options), options);
|
return this._retryPointerAction('dblclick', point => this._page.mouse.dblclick(point.x, point.y, options), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async selectOption(values: string | ElementHandle | types.SelectOption | string[] | ElementHandle[] | types.SelectOption[], options?: types.NavigatingActionWaitOptions): Promise<string[]> {
|
async selectOption(values: string | ElementHandle | types.SelectOption | string[] | ElementHandle[] | types.SelectOption[], options?: types.NavigatingActionWaitOptions): Promise<string[]> {
|
||||||
|
this._page._log(inputLog, `elementHandle.selectOption(%s)`, values);
|
||||||
const deadline = this._page._timeoutSettings.computeDeadline(options);
|
const deadline = this._page._timeoutSettings.computeDeadline(options);
|
||||||
let vals: string[] | ElementHandle[] | types.SelectOption[];
|
let vals: string[] | ElementHandle[] | types.SelectOption[];
|
||||||
if (!Array.isArray(values))
|
if (!Array.isArray(values))
|
||||||
@ -326,6 +328,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fill(value: string, options?: types.NavigatingActionWaitOptions): Promise<void> {
|
async fill(value: string, options?: types.NavigatingActionWaitOptions): Promise<void> {
|
||||||
|
this._page._log(inputLog, `elementHandle.fill(${value})`);
|
||||||
assert(helper.isString(value), 'Value must be string. Found value "' + value + '" of type "' + (typeof value) + '"');
|
assert(helper.isString(value), 'Value must be string. Found value "' + value + '" of type "' + (typeof value) + '"');
|
||||||
const deadline = this._page._timeoutSettings.computeDeadline(options);
|
const deadline = this._page._timeoutSettings.computeDeadline(options);
|
||||||
await this._page._frameManager.waitForSignalsCreatedBy(async () => {
|
await this._page._frameManager.waitForSignalsCreatedBy(async () => {
|
||||||
@ -341,11 +344,13 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async selectText(): Promise<void> {
|
async selectText(): Promise<void> {
|
||||||
|
this._page._log(inputLog, `elementHandle.selectText()`);
|
||||||
const injectedResult = await this._evaluateInUtility(({ injected, node }) => injected.selectText(node), {});
|
const injectedResult = await this._evaluateInUtility(({ injected, node }) => injected.selectText(node), {});
|
||||||
handleInjectedResult(injectedResult, '');
|
handleInjectedResult(injectedResult, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
async setInputFiles(files: string | types.FilePayload | string[] | types.FilePayload[], options?: types.NavigatingActionWaitOptions) {
|
async setInputFiles(files: string | types.FilePayload | string[] | types.FilePayload[], options?: types.NavigatingActionWaitOptions) {
|
||||||
|
this._page._log(inputLog, `elementHandle.setInputFiles(...)`);
|
||||||
const deadline = this._page._timeoutSettings.computeDeadline(options);
|
const deadline = this._page._timeoutSettings.computeDeadline(options);
|
||||||
const injectedResult = await this._evaluateInUtility(({ node }): InjectedResult<boolean> => {
|
const injectedResult = await this._evaluateInUtility(({ node }): InjectedResult<boolean> => {
|
||||||
if (node.nodeType !== Node.ELEMENT_NODE || (node as Node as Element).tagName !== 'INPUT')
|
if (node.nodeType !== Node.ELEMENT_NODE || (node as Node as Element).tagName !== 'INPUT')
|
||||||
@ -381,11 +386,13 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async focus() {
|
async focus() {
|
||||||
|
this._page._log(inputLog, `elementHandle.focus()`);
|
||||||
const injectedResult = await this._evaluateInUtility(({ injected, node }) => injected.focusNode(node), {});
|
const injectedResult = await this._evaluateInUtility(({ injected, node }) => injected.focusNode(node), {});
|
||||||
handleInjectedResult(injectedResult, '');
|
handleInjectedResult(injectedResult, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
async type(text: string, options?: { delay?: number } & types.NavigatingActionWaitOptions) {
|
async type(text: string, options?: { delay?: number } & types.NavigatingActionWaitOptions) {
|
||||||
|
this._page._log(inputLog, `elementHandle.type("${text}")`);
|
||||||
const deadline = this._page._timeoutSettings.computeDeadline(options);
|
const deadline = this._page._timeoutSettings.computeDeadline(options);
|
||||||
await this._page._frameManager.waitForSignalsCreatedBy(async () => {
|
await this._page._frameManager.waitForSignalsCreatedBy(async () => {
|
||||||
await this.focus();
|
await this.focus();
|
||||||
@ -394,6 +401,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async press(key: string, options?: { delay?: number } & types.NavigatingActionWaitOptions) {
|
async press(key: string, options?: { delay?: number } & types.NavigatingActionWaitOptions) {
|
||||||
|
this._page._log(inputLog, `elementHandle.press("${key}")`);
|
||||||
const deadline = this._page._timeoutSettings.computeDeadline(options);
|
const deadline = this._page._timeoutSettings.computeDeadline(options);
|
||||||
await this._page._frameManager.waitForSignalsCreatedBy(async () => {
|
await this._page._frameManager.waitForSignalsCreatedBy(async () => {
|
||||||
await this.focus();
|
await this.focus();
|
||||||
@ -402,10 +410,12 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async check(options?: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) {
|
async check(options?: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) {
|
||||||
|
this._page._log(inputLog, `elementHandle.check()`);
|
||||||
await this._setChecked(true, options);
|
await this._setChecked(true, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async uncheck(options?: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) {
|
async uncheck(options?: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) {
|
||||||
|
this._page._log(inputLog, `elementHandle.uncheck()`);
|
||||||
await this._setChecked(false, options);
|
await this._setChecked(false, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -494,7 +504,7 @@ function handleInjectedResult<T = undefined>(injectedResult: InjectedResult<T>,
|
|||||||
if (injectedResult.status === 'notconnected')
|
if (injectedResult.status === 'notconnected')
|
||||||
throw new NotConnectedError();
|
throw new NotConnectedError();
|
||||||
if (injectedResult.status === 'timeout')
|
if (injectedResult.status === 'timeout')
|
||||||
throw new TimeoutError(`waiting for ${timeoutMessage} failed: timeout exceeded`);
|
throw new TimeoutError(`waiting for ${timeoutMessage} failed: timeout exceeded. Re-run with the DEBUG=pw:input env variable to see the debug log.`);
|
||||||
if (injectedResult.status === 'error')
|
if (injectedResult.status === 'error')
|
||||||
throw new Error(injectedResult.error);
|
throw new Error(injectedResult.error);
|
||||||
return injectedResult.value as T;
|
return injectedResult.value as T;
|
||||||
|
@ -684,13 +684,17 @@ export class Frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _retryWithSelectorIfNotConnected<R>(
|
private async _retryWithSelectorIfNotConnected<R>(
|
||||||
|
actionName: string,
|
||||||
selector: string, options: types.TimeoutOptions,
|
selector: string, options: types.TimeoutOptions,
|
||||||
action: (handle: dom.ElementHandle<Element>, deadline: number) => Promise<R>): Promise<R> {
|
action: (handle: dom.ElementHandle<Element>, deadline: number) => Promise<R>): Promise<R> {
|
||||||
const deadline = this._page._timeoutSettings.computeDeadline(options);
|
const deadline = this._page._timeoutSettings.computeDeadline(options);
|
||||||
|
this._page._log(dom.inputLog, `(page|frame).${actionName}("${selector}")`);
|
||||||
while (!helper.isPastDeadline(deadline)) {
|
while (!helper.isPastDeadline(deadline)) {
|
||||||
try {
|
try {
|
||||||
const { world, task } = selectors._waitForSelectorTask(selector, 'attached', deadline);
|
const { world, task } = selectors._waitForSelectorTask(selector, 'attached', deadline);
|
||||||
|
this._page._log(dom.inputLog, `waiting for the selector "${selector}"`);
|
||||||
const handle = await this._scheduleRerunnableTask(task, world, deadline, `selector "${selector}"`);
|
const handle = await this._scheduleRerunnableTask(task, world, deadline, `selector "${selector}"`);
|
||||||
|
this._page._log(dom.inputLog, `...got element for the selector`);
|
||||||
const element = handle.asElement() as dom.ElementHandle<Element>;
|
const element = handle.asElement() as dom.ElementHandle<Element>;
|
||||||
try {
|
try {
|
||||||
return await action(element, deadline);
|
return await action(element, deadline);
|
||||||
@ -703,61 +707,61 @@ export class Frame {
|
|||||||
this._page._log(dom.inputLog, 'Element was detached from the DOM, retrying');
|
this._page._log(dom.inputLog, 'Element was detached from the DOM, retrying');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new TimeoutError(`waiting for selector "${selector}" failed: timeout exceeded`);
|
throw new TimeoutError(`waiting for selector "${selector}" failed: timeout exceeded. Re-run with the DEBUG=pw:input env variable to see the debug log.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async click(selector: string, options: dom.ClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
async click(selector: string, options: dom.ClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
||||||
await this._retryWithSelectorIfNotConnected(selector, options,
|
await this._retryWithSelectorIfNotConnected('click', selector, options,
|
||||||
(handle, deadline) => handle.click(helper.optionsWithUpdatedTimeout(options, deadline)));
|
(handle, deadline) => handle.click(helper.optionsWithUpdatedTimeout(options, deadline)));
|
||||||
}
|
}
|
||||||
|
|
||||||
async dblclick(selector: string, options: dom.MultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
async dblclick(selector: string, options: dom.MultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
||||||
await this._retryWithSelectorIfNotConnected(selector, options,
|
await this._retryWithSelectorIfNotConnected('dblclick', selector, options,
|
||||||
(handle, deadline) => handle.dblclick(helper.optionsWithUpdatedTimeout(options, deadline)));
|
(handle, deadline) => handle.dblclick(helper.optionsWithUpdatedTimeout(options, deadline)));
|
||||||
}
|
}
|
||||||
|
|
||||||
async fill(selector: string, value: string, options: types.NavigatingActionWaitOptions = {}) {
|
async fill(selector: string, value: string, options: types.NavigatingActionWaitOptions = {}) {
|
||||||
await this._retryWithSelectorIfNotConnected(selector, options,
|
await this._retryWithSelectorIfNotConnected('fill', selector, options,
|
||||||
(handle, deadline) => handle.fill(value, helper.optionsWithUpdatedTimeout(options, deadline)));
|
(handle, deadline) => handle.fill(value, helper.optionsWithUpdatedTimeout(options, deadline)));
|
||||||
}
|
}
|
||||||
|
|
||||||
async focus(selector: string, options: types.TimeoutOptions = {}) {
|
async focus(selector: string, options: types.TimeoutOptions = {}) {
|
||||||
await this._retryWithSelectorIfNotConnected(selector, options,
|
await this._retryWithSelectorIfNotConnected('focus', selector, options,
|
||||||
(handle, deadline) => handle.focus());
|
(handle, deadline) => handle.focus());
|
||||||
}
|
}
|
||||||
|
|
||||||
async hover(selector: string, options: dom.PointerActionOptions & types.PointerActionWaitOptions = {}) {
|
async hover(selector: string, options: dom.PointerActionOptions & types.PointerActionWaitOptions = {}) {
|
||||||
await this._retryWithSelectorIfNotConnected(selector, options,
|
await this._retryWithSelectorIfNotConnected('hover', selector, options,
|
||||||
(handle, deadline) => handle.hover(helper.optionsWithUpdatedTimeout(options, deadline)));
|
(handle, deadline) => handle.hover(helper.optionsWithUpdatedTimeout(options, deadline)));
|
||||||
}
|
}
|
||||||
|
|
||||||
async selectOption(selector: string, values: string | dom.ElementHandle | types.SelectOption | string[] | dom.ElementHandle[] | types.SelectOption[], options: types.NavigatingActionWaitOptions = {}): Promise<string[]> {
|
async selectOption(selector: string, values: string | dom.ElementHandle | types.SelectOption | string[] | dom.ElementHandle[] | types.SelectOption[], options: types.NavigatingActionWaitOptions = {}): Promise<string[]> {
|
||||||
return await this._retryWithSelectorIfNotConnected(selector, options,
|
return await this._retryWithSelectorIfNotConnected('selectOption', selector, options,
|
||||||
(handle, deadline) => handle.selectOption(values, helper.optionsWithUpdatedTimeout(options, deadline)));
|
(handle, deadline) => handle.selectOption(values, helper.optionsWithUpdatedTimeout(options, deadline)));
|
||||||
}
|
}
|
||||||
|
|
||||||
async setInputFiles(selector: string, files: string | types.FilePayload | string[] | types.FilePayload[], options: types.NavigatingActionWaitOptions = {}): Promise<void> {
|
async setInputFiles(selector: string, files: string | types.FilePayload | string[] | types.FilePayload[], options: types.NavigatingActionWaitOptions = {}): Promise<void> {
|
||||||
await this._retryWithSelectorIfNotConnected(selector, options,
|
await this._retryWithSelectorIfNotConnected('setInputFiles', selector, options,
|
||||||
(handle, deadline) => handle.setInputFiles(files, helper.optionsWithUpdatedTimeout(options, deadline)));
|
(handle, deadline) => handle.setInputFiles(files, helper.optionsWithUpdatedTimeout(options, deadline)));
|
||||||
}
|
}
|
||||||
|
|
||||||
async type(selector: string, text: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}) {
|
async type(selector: string, text: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}) {
|
||||||
await this._retryWithSelectorIfNotConnected(selector, options,
|
await this._retryWithSelectorIfNotConnected('type', selector, options,
|
||||||
(handle, deadline) => handle.type(text, helper.optionsWithUpdatedTimeout(options, deadline)));
|
(handle, deadline) => handle.type(text, helper.optionsWithUpdatedTimeout(options, deadline)));
|
||||||
}
|
}
|
||||||
|
|
||||||
async press(selector: string, key: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}) {
|
async press(selector: string, key: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}) {
|
||||||
await this._retryWithSelectorIfNotConnected(selector, options,
|
await this._retryWithSelectorIfNotConnected('press', selector, options,
|
||||||
(handle, deadline) => handle.press(key, helper.optionsWithUpdatedTimeout(options, deadline)));
|
(handle, deadline) => handle.press(key, helper.optionsWithUpdatedTimeout(options, deadline)));
|
||||||
}
|
}
|
||||||
|
|
||||||
async check(selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
async check(selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
||||||
await this._retryWithSelectorIfNotConnected(selector, options,
|
await this._retryWithSelectorIfNotConnected('check', selector, options,
|
||||||
(handle, deadline) => handle.check(helper.optionsWithUpdatedTimeout(options, deadline)));
|
(handle, deadline) => handle.check(helper.optionsWithUpdatedTimeout(options, deadline)));
|
||||||
}
|
}
|
||||||
|
|
||||||
async uncheck(selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
async uncheck(selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
||||||
await this._retryWithSelectorIfNotConnected(selector, options,
|
await this._retryWithSelectorIfNotConnected('uncheck', selector, options,
|
||||||
(handle, deadline) => handle.uncheck(helper.optionsWithUpdatedTimeout(options, deadline)));
|
(handle, deadline) => handle.uncheck(helper.optionsWithUpdatedTimeout(options, deadline)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -879,7 +883,7 @@ class RerunnableTask {
|
|||||||
});
|
});
|
||||||
// Since page navigation requires us to re-install the pageScript, we should track
|
// Since page navigation requires us to re-install the pageScript, we should track
|
||||||
// timeout on our end.
|
// timeout on our end.
|
||||||
const timeoutError = new TimeoutError(`waiting for ${title || 'function'} failed: timeout exceeded`);
|
const timeoutError = new TimeoutError(`waiting for ${title || 'function'} failed: timeout exceeded. Re-run with the DEBUG=pw:input env variable to see the debug log.`);
|
||||||
this._timeoutTimer = setTimeout(() => this.terminate(timeoutError), helper.timeUntilDeadline(deadline));
|
this._timeoutTimer = setTimeout(() => this.terminate(timeoutError), helper.timeUntilDeadline(deadline));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ class Helper {
|
|||||||
|
|
||||||
static async waitWithDeadline<T>(promise: Promise<T>, taskName: string, deadline: number): Promise<T> {
|
static async waitWithDeadline<T>(promise: Promise<T>, taskName: string, deadline: number): Promise<T> {
|
||||||
let reject: (error: Error) => void;
|
let reject: (error: Error) => void;
|
||||||
const timeoutError = new TimeoutError(`waiting for ${taskName} failed: timeout exceeded`);
|
const timeoutError = new TimeoutError(`Waiting for ${taskName} failed: timeout exceeded. Re-run with the DEBUG=pw:input env variable to see the debug log.`);
|
||||||
const timeoutPromise = new Promise<T>((resolve, x) => reject = x);
|
const timeoutPromise = new Promise<T>((resolve, x) => reject = x);
|
||||||
const timeoutTimer = setTimeout(() => reject(timeoutError), helper.timeUntilDeadline(deadline));
|
const timeoutTimer = setTimeout(() => reject(timeoutError), helper.timeUntilDeadline(deadline));
|
||||||
try {
|
try {
|
||||||
|
@ -183,12 +183,14 @@ describe('Page.click', function() {
|
|||||||
await page.$eval('button', b => b.style.display = 'none');
|
await page.$eval('button', b => b.style.display = 'none');
|
||||||
const error = await page.click('button', { timeout: 100 }).catch(e => e);
|
const error = await page.click('button', { timeout: 100 }).catch(e => e);
|
||||||
expect(error.message).toContain('timeout exceeded');
|
expect(error.message).toContain('timeout exceeded');
|
||||||
|
expect(error.message).toContain('DEBUG=pw:input');
|
||||||
});
|
});
|
||||||
it('should timeout waiting for visbility:hidden to be gone', async({page, server}) => {
|
it('should timeout waiting for visbility:hidden to be gone', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/input/button.html');
|
await page.goto(server.PREFIX + '/input/button.html');
|
||||||
await page.$eval('button', b => b.style.visibility = 'hidden');
|
await page.$eval('button', b => b.style.visibility = 'hidden');
|
||||||
const error = await page.click('button', { timeout: 100 }).catch(e => e);
|
const error = await page.click('button', { timeout: 100 }).catch(e => e);
|
||||||
expect(error.message).toContain('timeout exceeded');
|
expect(error.message).toContain('timeout exceeded');
|
||||||
|
expect(error.message).toContain('DEBUG=pw:input');
|
||||||
});
|
});
|
||||||
it('should waitFor visible when parent is hidden', async({page, server}) => {
|
it('should waitFor visible when parent is hidden', async({page, server}) => {
|
||||||
let done = false;
|
let done = false;
|
||||||
@ -433,6 +435,7 @@ describe('Page.click', function() {
|
|||||||
});
|
});
|
||||||
const error = await button.click({ timeout: 100 }).catch(e => e);
|
const error = await button.click({ timeout: 100 }).catch(e => e);
|
||||||
expect(error.message).toContain('timeout exceeded');
|
expect(error.message).toContain('timeout exceeded');
|
||||||
|
expect(error.message).toContain('DEBUG=pw:input');
|
||||||
});
|
});
|
||||||
it('should wait for becoming hit target', async({page, server}) => {
|
it('should wait for becoming hit target', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/input/button.html');
|
await page.goto(server.PREFIX + '/input/button.html');
|
||||||
@ -481,6 +484,7 @@ describe('Page.click', function() {
|
|||||||
});
|
});
|
||||||
const error = await button.click({ timeout: 100 }).catch(e => e);
|
const error = await button.click({ timeout: 100 }).catch(e => e);
|
||||||
expect(error.message).toContain('timeout exceeded');
|
expect(error.message).toContain('timeout exceeded');
|
||||||
|
expect(error.message).toContain('DEBUG=pw:input');
|
||||||
});
|
});
|
||||||
it('should fail when obscured and not waiting for hit target', async({page, server}) => {
|
it('should fail when obscured and not waiting for hit target', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/input/button.html');
|
await page.goto(server.PREFIX + '/input/button.html');
|
||||||
@ -583,6 +587,7 @@ describe('Page.click', function() {
|
|||||||
expect(clicked).toBe(false);
|
expect(clicked).toBe(false);
|
||||||
expect(await page.evaluate(() => window.clicked)).toBe(undefined);
|
expect(await page.evaluate(() => window.clicked)).toBe(undefined);
|
||||||
expect(error.message).toContain('timeout exceeded');
|
expect(error.message).toContain('timeout exceeded');
|
||||||
|
expect(error.message).toContain('DEBUG=pw:input');
|
||||||
});
|
});
|
||||||
it.skip(true)('should pause animations', async({page}) => {
|
it.skip(true)('should pause animations', async({page}) => {
|
||||||
// This test requires pausing the page.
|
// This test requires pausing the page.
|
||||||
|
Loading…
Reference in New Issue
Block a user