Skip to content

Commit

Permalink
Merge pull request #406 from angrykoala/dev
Browse files Browse the repository at this point in the history
2.5.0
  • Loading branch information
angrykoala authored Jul 24, 2019
2 parents 39e8389 + 8804cdb commit a90413f
Show file tree
Hide file tree
Showing 43 changed files with 528 additions and 226 deletions.
11 changes: 10 additions & 1 deletion @types/compositer/index.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
declare module 'compositer';
type Class<T = unknown> = new (...arguments: any[]) => T;

type ComponentFunction = (...args: Array<any>) => any;

type Component = { [s: string]: any } | ComponentFunction;

declare module 'compositer' {
function compose(baseClass: Class, components: Component, ...childParams: Array<any>): Class;
export = compose;
}
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
2.5.0 / 2019-07-24
==================

* Pages, selectPage and closePage methods to handle tabs and popups
* Browser.context returns Puppeteer's context object
* Improved typings for module compositer
* A browser won't have 2 tabs opened by default
* Puppeteer updated to 1.19.0
* Minor improvements in internal typings
* Minor fix in InjectionScript error message
* Refactor on browser instances creation and setup

2.4.0 / 2019-07-15
==================

Expand Down
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ True if the browser is configured as incognito page.
**cache**
If the requests cache is active.

**context**
Returns Puppeteer's [BrowserContext](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#class-browsercontext).

#### Methods
All the methods in Browser return a Promise than can easily be handled by using `async/await`.

Expand Down Expand Up @@ -286,6 +289,26 @@ const element = await browser.elementFromPoint(500, 150);
await browser.text(element); // ["My Title"]
```

**selectPage(index: number)**
Selects the given page (a.k.a. tab) to be used by Wendigo. Keep in mind that tabs are **never** changed automatically unless explicitly selected or closed with `closePage`.

```js
await browser.click(".btn.new-tab")
await browser.wait(100); // waits for new tab to be loaded
await browser.pages(); // length is 2
await browser.selectPage(1); // goes to newly opened tab
```

> Due to some limitation, in order for Wendigo to work properly, changing page with `selectPage` will cause the given page to reload.
**closePage(index: number)**
Closes the page with given index, if the closed page is the current active page, it will change to the new page with index 0 (reloading it in the process). If no more pages exists, the browser will close with `browser.close()` automatically.

**pages()**
Returns all Puppeteer's [pages](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#class-page), one per tab or popup.

> **Warning:** All pages related methods are still under revision, and its behavour may heavily change in future releases
**addScript(scriptPath)**
Executes the given script in the browser context. Useful to set helper methods and functions. This method must be called after the page is already loaded, if another page is loaded, the scripts won't be re-executed. If these scripts are required for a plugin to work, remember to execute this method on the `_afterOpen` hook.

Expand Down
36 changes: 18 additions & 18 deletions lib/browser/assertions/assertions_core.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as utils from '../../utils/utils';
import { arrayfy, matchTextList, matchText, stringify, matchTextContainingList } from '../../utils/utils';
import { sameMembers } from '../../utils/assert_utils';
import * as elementsAssertionUtils from './assert_elements';
import * as assertUtils from '../../utils/assert_utils';

import { QueryError, FatalError, WendigoError, AssertionError } from '../../errors';
import { WendigoSelector } from '../../types';
Expand Down Expand Up @@ -67,10 +67,10 @@ export default class AssertionsCore {
if ((!expected && expected !== "") || (Array.isArray(expected) && expected.length === 0)) {
throw new WendigoError("assert.text", `Missing expected text for assertion.`);
}
const processedExpected = utils.arrayfy(expected);
const processedExpected = arrayfy(expected);
const texts = await this._browser.text(selector);
for (const expectedText of processedExpected) {
if (!utils.matchTextList(texts, expectedText)) {
if (!matchTextList(texts, expectedText)) {
if (!msg) {
const foundText = texts.length === 0 ? "no text" : `"${texts.join(" ")}"`;
msg = `Expected element "${selector}" to have text "${expectedText}", ${foundText} found.`;
Expand All @@ -85,11 +85,11 @@ export default class AssertionsCore {
throw new WendigoError("assert.textContains", `Missing expected text for assertion.`);
}

const processedExpected = utils.arrayfy(expected);
const processedExpected = arrayfy(expected);
const texts = await this._browser.text(selector);

for (const expectedText of processedExpected) {
if (!utils.matchTextContainingList(texts, expectedText)) {
if (!matchTextContainingList(texts, expectedText)) {
if (!msg) {
const foundText = texts.length === 0 ? "no text" : `"${texts.join(" ")}"`;
msg = `Expected element "${selector}" to contain text "${expectedText}", ${foundText} found.`;
Expand All @@ -102,7 +102,7 @@ export default class AssertionsCore {
public async title(expected: string | RegExp, msg?: string): Promise<void> {
const title = await this._browser.title();
const foundTitle = title ? `"${title}"` : "no title";
if (!utils.matchText(title, expected)) {
if (!matchText(title, expected)) {
if (!msg) msg = `Expected page title to be "${expected}", ${foundTitle} found.`;
throw new AssertionError("assert.title", msg);
}
Expand Down Expand Up @@ -131,8 +131,8 @@ export default class AssertionsCore {
} catch (err) {
throw new FatalError("assert.url", `Can't obtain page url.${err.extraMessage || err.message}`);
}
if (!utils.matchText(url, expected)) {
if (!msg) msg = `Expected url to be "${utils.stringify(expected)}", "${url}" found`;
if (!matchText(url, expected)) {
if (!msg) msg = `Expected url to be "${stringify(expected)}", "${url}" found`;
throw new AssertionError("assert.url", msg, url, expected);
}
}
Expand Down Expand Up @@ -190,7 +190,7 @@ export default class AssertionsCore {
if (filteredAttributes.length === 0) return Promise.resolve();
} else {
for (const attr of filteredAttributes) {
if (expectedValue === undefined || utils.matchText(attr, expectedValue)) {
if (expectedValue === undefined || matchText(attr, expectedValue)) {
return Promise.resolve();
}
}
Expand Down Expand Up @@ -245,7 +245,7 @@ export default class AssertionsCore {
return Promise.reject(error);
}
for (const html of found) {
if (utils.matchText(html, expected)) return Promise.resolve();
if (matchText(html, expected)) return Promise.resolve();
}

if (!msg) {
Expand All @@ -264,7 +264,7 @@ export default class AssertionsCore {
return Promise.reject(error);
}
for (const html of found) {
if (utils.matchText(html, expected)) return Promise.resolve();
if (matchText(html, expected)) return Promise.resolve();
}

if (!msg) {
Expand All @@ -275,10 +275,10 @@ export default class AssertionsCore {
}

public async options(selector: WendigoSelector, expected: string | Array<string>, msg?: string): Promise<void> {
const parsedExpected = utils.arrayfy(expected);
const parsedExpected = arrayfy(expected);
const options = await this._browser.options(selector);
const sameMembers = assertUtils.sameMembers(parsedExpected, options);
if (!sameMembers) {
const same = sameMembers(parsedExpected, options);
if (!same) {
if (!msg) {
const expectedText = parsedExpected.join(", ");
const optionsText = options.join(", ");
Expand All @@ -289,10 +289,10 @@ export default class AssertionsCore {
}

public async selectedOptions(selector: WendigoSelector, expected: string | Array<string>, msg?: string): Promise<void> {
const parsedExpected = utils.arrayfy(expected);
const parsedExpected = arrayfy(expected);
const selectedOptions = await this._browser.selectedOptions(selector);
const sameMembers = assertUtils.sameMembers(parsedExpected, selectedOptions);
if (!sameMembers) {
const same = sameMembers(parsedExpected, selectedOptions);
if (!same) {
if (!msg) {
const expectedText = parsedExpected.join(", ");
const optionsText = selectedOptions.join(", ");
Expand Down
12 changes: 6 additions & 6 deletions lib/browser/assertions/browser_not_assertions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as utils from '../../utils/utils';
import { arrayfy, matchTextList, matchTextContainingList } from '../../utils/utils';
import { invertify } from '../../utils/assert_utils';
import { WendigoError, QueryError, AssertionError } from '../../errors';
import BrowserAssertions from '../browser_assertions';
Expand Down Expand Up @@ -40,11 +40,11 @@ export default class BrowserNotAssertions {
if ((!expected && expected !== "") || (Array.isArray(expected) && expected.length === 0)) {
throw new WendigoError("assert.not.text", `Missing expected text for assertion.`);
}
const processedExpected = utils.arrayfy(expected);
const processedExpected = arrayfy(expected);

const texts = await this._browser.text(selector);
for (const expectedText of processedExpected) {
if (utils.matchTextList(texts, expectedText)) {
if (matchTextList(texts, expectedText)) {
if (!msg) msg = `Expected element "${selector}" not to have text "${expectedText}".`;
throw new AssertionError("assert.not.text", msg);
}
Expand All @@ -56,11 +56,11 @@ export default class BrowserNotAssertions {
throw new WendigoError("assert.not.textContains", `Missing expected text for assertion.`);
}

const processedExpected = utils.arrayfy(expected);
const processedExpected = arrayfy(expected);
const texts = await this._browser.text(selector);

for (const expectedText of processedExpected) {
if (utils.matchTextContainingList(texts, expectedText)) {
if (matchTextContainingList(texts, expectedText)) {
if (!msg) {
msg = `Expected element "${selector}" to not contain text "${expectedText}".`;
}
Expand Down Expand Up @@ -144,7 +144,7 @@ export default class BrowserNotAssertions {

public selectedOptions(selector: WendigoSelector, expected: string | Array<string>, msg?: string): Promise<void> {
if (!msg) {
const parsedExpected = utils.arrayfy(expected);
const parsedExpected = arrayfy(expected);
const expectedText = parsedExpected.join(", ");
msg = `Expected element "${selector}" not to have options "${expectedText}" selected.`;
}
Expand Down
7 changes: 4 additions & 3 deletions lib/browser/browser.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import PuppeteerContext from '../puppeteer_wrapper/puppeteer_context';
import BrowserTap from './mixins/browser_tap';
import PuppeteerPage from './puppeteer_wrapper/puppeteer_page';
import { FinalBrowserSettings } from '../types';

// Modules
Expand All @@ -10,6 +10,7 @@ import BrowserConsole from '../modules/console/browser_console';
import BrowserWebworker from '../modules/webworkers/browser_webworker';
import BrowserDialog from '../modules/dialog/browser_dialog';
import BrowserAuth from '../modules/auth/browser_auth';
import PuppeteerPage from '../puppeteer_wrapper/puppeteer_page';

export default class Browser extends BrowserTap {
public readonly cookies: BrowserCookies;
Expand All @@ -20,9 +21,9 @@ export default class Browser extends BrowserTap {
public readonly dialog: BrowserDialog;
public readonly auth: BrowserAuth;

constructor(page: PuppeteerPage, settings: FinalBrowserSettings, components: Array<string> = []) {
constructor(context: PuppeteerContext, page: PuppeteerPage, settings: FinalBrowserSettings, components: Array<string> = []) {
components = components.concat(["cookies", "localStorage", "requests", "console", "webworkers", "dialog"]);
super(page, settings, components);
super(context, page, settings, components);
this.cookies = new BrowserCookies(this);
this.localStorage = new BrowserLocalStorage(this);
this.requests = new BrowserRequests(this);
Expand Down
Loading

0 comments on commit a90413f

Please sign in to comment.