From d5f3e1747c2c5600567a8dfc7c7ce1fd4304b0a4 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Fri, 24 Jul 2020 17:11:20 +0200 Subject: [PATCH 1/4] update version --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39d04a4..49e15e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +2.13.1 / ####-##-## +=================== + + 2.13.0 / 2020-07-24 =================== diff --git a/package.json b/package.json index ce5a0a4..00d7aba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wendigo", - "version": "2.13.0", + "version": "2.13.1", "description": "A proper monster for front-end automated testing", "engines": { "node": ">=8.0.0" From e042277c4d46b3165dcfd9725b6b266794bd77cf Mon Sep 17 00:00:00 2001 From: angrykoala Date: Sat, 8 Aug 2020 01:13:28 +0200 Subject: [PATCH 2/4] Fixes dockerfile --- CHANGELOG.md | 2 ++ Dockerfile | 1 + README.md | 2 -- package.json | 10 +++++----- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49e15e1..ceed37d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ 2.13.1 / ####-##-## =================== +* Fixes Dockerfile +* Updates dependencies 2.13.0 / 2020-07-24 =================== diff --git a/Dockerfile b/Dockerfile index e782cb8..0fe4754 100644 --- a/Dockerfile +++ b/Dockerfile @@ -44,4 +44,5 @@ RUN apt-get update && apt-get install -y -q --no-install-recommends\ && rm -rf /var/lib/apt/lists/* ENV NO_SANDBOX=true +ENV PUPPETEER_SKIP_DOWNLOAD='true' RUN npm install wendigo && npm cache clean --force diff --git a/README.md b/README.md index 0237b25..a7a6e5d 100644 --- a/README.md +++ b/README.md @@ -2078,8 +2078,6 @@ FROM angrykoala/wendigo WORKDIR /app COPY package*.json ./ -# Copies Puppeteer and Wendigo from the base image -RUN mv /node_modules . # Installs your up (it must have Wendigo as a dependency) RUN npm install # Copies the rest of your app diff --git a/package.json b/package.json index 00d7aba..e607e3e 100644 --- a/package.json +++ b/package.json @@ -46,16 +46,16 @@ "puppeteer": "~5.2.1" }, "devDependencies": { - "@types/mocha": "^8.0.0", - "@types/node": "^14.0.25", + "@types/mocha": "^8.0.1", + "@types/node": "^14.0.27", "@types/puppeteer": "~3.0.1", "basic-auth": "^2.0.1", - "eslint": "^7.5.0", + "eslint": "^7.6.0", "express": "^4.17.1", "markdownlint-cli": "^0.23.2", - "mocha": "^8.0.1", + "mocha": "^8.1.1", "sinon": "^9.0.2", - "tslint": "^6.1.2", + "tslint": "^6.1.3", "typescript": "^3.9.7" } } From 29e2dd74d569f0842d227436e9b5dbe30b81aff1 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Sat, 8 Aug 2020 18:14:43 +0200 Subject: [PATCH 3/4] Message improvements for wait related errors #451 --- CHANGELOG.md | 1 + lib/browser/mixins/browser_wait.ts | 73 +++++++++++++++----- lib/models/errors.ts | 17 ++++- lib/puppeteer_wrapper/puppeteer_types.ts | 2 +- tests/browser/wait_until_not_visible.test.js | 7 ++ 5 files changed, 81 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ceed37d..ceb420a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ =================== * Fixes Dockerfile +* Error messages improved for timeout errors * Updates dependencies 2.13.0 / 2020-07-24 diff --git a/lib/browser/mixins/browser_wait.ts b/lib/browser/mixins/browser_wait.ts index 7e9d7a5..5789d9d 100644 --- a/lib/browser/mixins/browser_wait.ts +++ b/lib/browser/mixins/browser_wait.ts @@ -5,7 +5,7 @@ import { WendigoSelector } from '../../types'; import { createFindTextXPath, delay, isNumber } from '../../utils/utils'; import FailIfNotLoaded from '../../decorators/fail_if_not_loaded'; import OverrideError from '../../decorators/override_error'; -import { EvaluateFn } from '../../puppeteer_wrapper/puppeteer_types'; +import { EvaluateFn, PuppeteerErrors } from '../../puppeteer_wrapper/puppeteer_types'; export default abstract class BrowserWait extends BrowserNavigation { @@ -14,6 +14,7 @@ export default abstract class BrowserWait extends BrowserNavigation { } @FailIfNotLoaded + @OverrideError() public async waitFor(selector: EvaluateFn, timeout?: number, ...args: Array): Promise { timeout = this._getTimeout(timeout); args = args.map((e) => { @@ -25,19 +26,20 @@ export default abstract class BrowserWait extends BrowserNavigation { timeout: timeout, visible: true }, ...args); - } catch (err) { - if (err instanceof Error && err.message.match(/DOMException\:/)) { // TODO: move to a helper/wrapper - throw new QueryError("waitFor", `Invalid selector "${selector}".`); - } else { - let errMsg; - if (typeof selector === 'function') errMsg = `Waiting for function to return true`; - else errMsg = `Waiting for element "${selector}"`; - throw new TimeoutError("waitFor", errMsg, timeout); - } + } catch (error) { + let errMsg; + if (typeof selector === 'function') errMsg = `Waiting for function to return true`; + else errMsg = `Waiting for element "${selector}"`; + throw this._overrideWaitError(error, { + timeoutMessage: errMsg, + selector: `${selector}`, + timeout + }); } } @FailIfNotLoaded + @OverrideError() public async waitUntilNotVisible(selector: WendigoSelector, timeout?: number): Promise { timeout = this._getTimeout(timeout); try { @@ -46,11 +48,16 @@ export default abstract class BrowserWait extends BrowserNavigation { return !WendigoUtils.isVisible(element); }, timeout, selector); } catch (err) { - throw new TimeoutError("waitUntilNotVisible", `Waiting for element "${selector}" to not be visible`, timeout); + throw this._overrideWaitError(err, { + timeoutMessage: `Waiting for element "${selector}" to not be visible`, + selector: `${selector}`, + timeout + }); } } @FailIfNotLoaded + @OverrideError() public async waitForUrl(url: string | RegExp, timeout?: number): Promise { timeout = this._getTimeout(timeout); if (!url) return Promise.reject(new WendigoError("waitForUrl", `Invalid parameter url.`)); @@ -73,11 +80,15 @@ export default abstract class BrowserWait extends BrowserNavigation { } }, timeout, parsedUrl); } catch (err) { - throw new TimeoutError("waitForUrl", `Waiting for url "${url}"`, timeout); + throw this._overrideWaitError(err, { + timeoutMessage: `Waiting for url "${url}"`, + timeout + }); } } @FailIfNotLoaded + @OverrideError() public async waitForNavigation(timeout?: number): Promise { timeout = this._getTimeout(timeout); const t1 = new Date().getTime(); @@ -94,7 +105,10 @@ export default abstract class BrowserWait extends BrowserNavigation { return Boolean(w.WendigoUtils); }, timeout2); } catch (err) { - throw new TimeoutError("waitForNavigation", "", timeout); + throw this._overrideWaitError(err, { + timeoutMessage: "", + timeout + }); } } @@ -109,6 +123,8 @@ export default abstract class BrowserWait extends BrowserNavigation { return result[1]; } + @FailIfNotLoaded + @OverrideError() public async waitForText(text: string, timeout?: number): Promise { timeout = this._getTimeout(timeout); try { @@ -117,21 +133,30 @@ export default abstract class BrowserWait extends BrowserNavigation { return Boolean(WendigoUtils.xPathQuery(xp).length > 0); }, timeout, xPath); } catch (err) { - throw new TimeoutError("waitForText", `Waiting for text "${text}"`, timeout); + throw this._overrideWaitError(err, { + timeoutMessage: `Waiting for text "${text}"`, + timeout + }); } } + @FailIfNotLoaded + @OverrideError() public async waitAndClick(selector: string, timeout?: number): Promise { timeout = this._getTimeout(timeout); try { await this.waitFor(selector, timeout); return await this.click(selector); } catch (err) { - throw new TimeoutError("waitAndClick", "", timeout); + throw this._overrideWaitError(err, { + timeoutMessage: "", + timeout + }); } } @OverrideError() + @FailIfNotLoaded public async waitAndType(selector: string, text: string, timeout?: number): Promise { await this.waitFor(selector, timeout); return await this.type(selector, text); @@ -139,11 +164,14 @@ export default abstract class BrowserWait extends BrowserNavigation { } @OverrideError() + @FailIfNotLoaded public async waitAndCheck(selector: string, timeout?: number): Promise { await this.waitFor(selector, timeout); return await this.check(selector); } + @OverrideError() + @FailIfNotLoaded public async waitUntilEnabled(selector: WendigoSelector, timeout?: number): Promise { timeout = this._getTimeout(timeout); try { @@ -154,7 +182,10 @@ export default abstract class BrowserWait extends BrowserNavigation { return value === null; }, timeout, selector); } catch (err) { - throw new TimeoutError("waitUntilEnabled", `Waiting for element "${selector}" to be enabled`, timeout); + throw this._overrideWaitError(err, { + timeoutMessage: `Waiting for element "${selector}" to be enabled`, + timeout + }); } } @@ -162,4 +193,14 @@ export default abstract class BrowserWait extends BrowserNavigation { if (isNumber(timeout)) return timeout; else return this._settings.defaultTimeout; } + + // TODO: this need to be completely reworked to make a sensible approach to error handling + private _overrideWaitError(error: Error, options: { timeoutMessage: string, timeout: number, selector?: string }): Error { + if (error instanceof PuppeteerErrors.TimeoutError || error instanceof TimeoutError) { + return new TimeoutError("", options.timeoutMessage, options.timeout); + } + if (error instanceof Error && error.message.match(/DOMException\:/) || error instanceof QueryError) { + return new QueryError("", `Invalid selector "${options.selector || ""}".`); + } else return error; + } } diff --git a/lib/models/errors.ts b/lib/models/errors.ts index cb15f8f..b70564d 100644 --- a/lib/models/errors.ts +++ b/lib/models/errors.ts @@ -57,8 +57,8 @@ export class FatalError extends WendigoError { } export class TimeoutError extends WendigoError { - public readonly timeout: number; - constructor(fn: string, message: string, timeout: number) { + public readonly timeout?: number; + constructor(fn: string, message: string, timeout?: number) { let msg = message ? `${message}, timeout` : "Timeout"; if (timeout !== undefined) msg = `${msg} of ${timeout}ms exceeded.`; super(fn, msg); @@ -74,3 +74,16 @@ export class InjectScriptError extends FatalError { this.name = this.constructor.name; } } + +// export function handleError(error: Error, method: string, options: { timeout?: number, selector?: string } = {}): WendigoError { +// if (error instanceof WendigoError) return error; +// if (error instanceof PuppeteerErrors.TimeoutError) { +// return new TimeoutError(method, error.message, options.timeout); +// } +// if (error instanceof Error && error.message.match(/DOMException\:/)) { +// const selectorMessage = options.selector ? ` "${options.selector}"` : ""; +// return new QueryError(method, `Invalid selector${selectorMessage}.`); +// } else { +// return new WendigoError(method, error.message); +// } +// } diff --git a/lib/puppeteer_wrapper/puppeteer_types.ts b/lib/puppeteer_wrapper/puppeteer_types.ts index 3341fa7..2562ef2 100644 --- a/lib/puppeteer_wrapper/puppeteer_types.ts +++ b/lib/puppeteer_wrapper/puppeteer_types.ts @@ -6,5 +6,5 @@ export { Page, Frame, Viewport, EvaluateFn, SerializableOrJSHandle, JSHandle, Response, Worker, ScriptTagOptions, Browser, Base64ScreenShotOptions, Keyboard, Mouse, NavigationOptions, WaitForSelectorOptions, ElementHandle, Touchscreen, Cookie, SetCookie, DeleteCookie, PageEventObj, Request, Timeoutable, PDFOptions, ConsoleMessage, ConsoleMessageType, - ResourceType, DialogType, Dialog, BrowserContext, Target, BrowserContextEventObj, GeoOptions, Permission, MediaType, MediaFeature + ResourceType, DialogType, Dialog, BrowserContext, Target, BrowserContextEventObj, GeoOptions, Permission, MediaType, MediaFeature, errors as PuppeteerErrors } from 'puppeteer'; diff --git a/tests/browser/wait_until_not_visible.test.js b/tests/browser/wait_until_not_visible.test.js index 9dddf0b..7fdfea7 100644 --- a/tests/browser/wait_until_not_visible.test.js +++ b/tests/browser/wait_until_not_visible.test.js @@ -39,4 +39,11 @@ describe("Wait Until Not Visible", function() { await browser.assert.not.exists("#switch.off"); await browser.assert.exists("#switch.on"); }); + + it("Wait Until Not Visible With Invalid Selector Error", async() => { + await browser.open(configUrls.index); + await utils.assertThrowsAsync(async() => { + await browser.waitUntilNotVisible("p[header="); + }, `QueryError: [waitUntilNotVisible] Invalid selector "p[header=".`); + }); }); From b20cc41dc623b2e8588d1a398a62482937905e6a Mon Sep 17 00:00:00 2001 From: angrykoala Date: Sat, 8 Aug 2020 18:22:56 +0200 Subject: [PATCH 4/4] Release 2.13.1 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ceb420a..55447d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -2.13.1 / ####-##-## +2.13.1 / 2020-08-08 =================== * Fixes Dockerfile