Skip to content

Commit

Permalink
bump 1.4.0 with prebuilt browser object at lib index
Browse files Browse the repository at this point in the history
  • Loading branch information
yashaka committed May 9, 2023
1 parent 95a5240 commit 247a39c
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 32 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog

## next

* think on refactoring
* `await browser.element('#new-todo').type('do something').then(perform.pressEnter)`
* to
* `await browser.element('#new-todo').type('do something').then(command.pressEnter)`
* consider returning ElementPromise from all Element.* commands to allow:
* `await browser.element('#new-todo').type('do something').pressEnter()`
* same like in raw Selenium WebDriver

## 1.4.0

* add prebuilt browser object to selenidejs imports

## 1.3.7 (to be released on 2022.12.08)

* added `collection.second` as alias to `collection.elementAt(1)`
Expand Down
21 changes: 13 additions & 8 deletions lib/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// limitations under the License.

import {
Builder, By, Capabilities, WebDriver,
Builder, By, Capabilities, ThenableWebDriver, WebDriver,
} from 'selenium-webdriver';
import { Collection } from './collection';
import { Configuration, Customized } from './configuration';
Expand Down Expand Up @@ -46,13 +46,11 @@ export class Browser extends Entity implements Assertable, Matchable {
}

with(customConfig: Partial<Configuration>): Browser {
return new Browser(new Configuration({ ...this.configuration, ...customConfig }));
return new Browser({ ...this.configuration, ...customConfig });
}

get driver(): WebDriver {
return typeof this.configuration.driver === 'function'
? this.configuration.driver()
: this.configuration.driver;
get driver(): ThenableWebDriver {
return this.configuration.driver;
}

// eslint-disable-next-line class-methods-use-this
Expand Down Expand Up @@ -123,7 +121,14 @@ export class Browser extends Entity implements Assertable, Matchable {
? relativeOrAbsoluteUrl
: this.configuration.baseUrl + relativeOrAbsoluteUrl;

await this.driver.get(absoluteUrl);
// await this.driver.getSession().then(
// _ => this.driver.get(absoluteUrl),
// onFailure => {
// this.config.driver = undefined;
// this.driver.get(absoluteUrl);
// },
// );
this.driver.get(absoluteUrl);
return this;
}

Expand All @@ -144,7 +149,7 @@ export class Browser extends Entity implements Assertable, Matchable {
}

async quit() {
await this.driver.quit();
await this.config._resetDriver();
}

async refresh() {
Expand Down
124 changes: 105 additions & 19 deletions lib/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
// limitations under the License.

// import * as path from 'path';
import { Builder, By, Capabilities, WebDriver } from 'selenium-webdriver';
import {
Builder, By, Capabilities, ThenableWebDriver, WebDriver,
} from 'selenium-webdriver';
import * as capabilities from 'selenium-webdriver/lib/capabilities';
import { Browser } from './browser';
import { OnFailureHook } from './wait';
import { Collection } from './collection';
Expand All @@ -28,34 +31,39 @@ import { Extensions } from './utils/extensions';
* Enjoy;)
*/

/**
* Same as corresponding Capabilities.<browserName> key
*/
type BrowserName = 'chrome' | 'edge' | 'firefox' | 'ie' | 'safari';

export type OnEntityFailureHook = OnFailureHook<Browser | Element | Collection>;

export class Configuration {
static with(): Customized<Configuration> {
return Customized.configuration();
}

static withDriver(driver: WebDriver | (() => WebDriver)): Customized<Configuration> {
static withDriver(driver: ThenableWebDriver | (() => ThenableWebDriver)): Customized<Configuration> {
return Configuration.with().driver(driver);
}

readonly driver: WebDriver | (() => WebDriver) = null;
driver: ThenableWebDriver | undefined;

readonly timeout: number = 4000; // todo: seems like explicit types are not needed somewhere...
timeout: number = 4000; // todo: seems like explicit types are not needed somewhere...

readonly baseUrl: string = '';
baseUrl: string = '';

readonly setValueByJs: boolean = false;
setValueByJs: boolean = false;

readonly typeByJs: boolean = false;
typeByJs: boolean = false;

readonly windowWidth: string = ''; // todo: why not as number?
windowWidth: string = ''; // todo: why not as number?

readonly windowHeight: string = ''; // todo: why not as number?
windowHeight: string = ''; // todo: why not as number?

// readonly htmlPath: string = path.resolve('./htmls');
// readonly screenshotPath: string = path.resolve('./screenshots');
readonly fullPageScreenshot: boolean = true;
fullPageScreenshot: boolean = true;
// todo: should we bother and make it immutable?
/* readonly onFailureHooks: OnEntityFailureHook[] = [
async (failure: Error, entity: Browser | Element | Collection): Promise<void | Error> => {
Expand All @@ -74,13 +82,84 @@ export class Configuration {
}
]; */

readonly _locationStrategy: (selector: string | By) => By = Extensions.cssOrXPathToBy;

constructor(init?: Partial<Configuration>) {
Object.assign(this, init);
if (this.driver === null) {
this.driver = new Builder().withCapabilities(Capabilities.chrome()).build();
}
_locationStrategy: (selector: string | By) => By = Extensions.cssOrXPathToBy;

_driver: ThenableWebDriver;

__getDriver: () => ThenableWebDriver = undefined; // TODO: deprecate

_buildDriver: (config?: Configuration) => ThenableWebDriver;

// todo: should we name it quitDriver? or tearDownDriver?
_resetDriver: (config?: Configuration) => Promise<void>;

// todo: should we add something like isDriverAlive()? by default = this._driver != undefined

// should we refactor out driver, buildDriver, resetDriver, etc into driverManager? for SRP at least

browserName: BrowserName = 'chrome';

capabilities: Capabilities | undefined = undefined;

remoteUrl: string | undefined = undefined;

// TODO: cover other builder.using* properties like proxy and agent

constructor({
driver, _driver, _buildDriver: buildDriver, ...options
}: Partial<Configuration> = {}) {
Object.assign(this, options);

// if (driver) {
// this._driver = driver;
// }
Object.assign(this, { _driver: driver ?? _driver });

this._buildDriver = buildDriver ?? function fromConfig(config: Configuration) {
const builder = new Builder();
const caps = Capabilities[config.browserName ?? 'chrome']();
if (config.capabilities) {
caps.merge(config.capabilities);
}
if (config.remoteUrl) {
builder.usingServer(config.remoteUrl);
}
return builder.withCapabilities(caps).build();
};

Object.defineProperty(this, 'driver', {
enumerable: false,
get() {
if (this.__getDriver) {
return this.__getDriver();
}

// TODO: should we also check if driver is not closed (i.e. alive)?
this._driver = this._driver ?? this._buildDriver(this);
return this._driver;
},
set(value = undefined) {
this._driver = value;
},
});

this._resetDriver = driver
// ? async function justQuitDriverThatWasManuallyPassed()
? async () => this.driver.quit()
// : async function quitAndRemoveStoredInstance() {
: async () => {
if (!this._driver) {
return;
}
await this.driver.getSession().then(
_ => this.driver.quit(),
error => console.warn(
'You seem to try to quit a browser that is already not alive:',
error,
),
);
this.driver = undefined;
};
}
}

Expand Down Expand Up @@ -110,8 +189,15 @@ export class Customized<T> { // todo: add generic? Customized<T> ... constructor
return new this.customizedType(this.configuration);
}

driver(webdriver: WebDriver | (() => WebDriver)) {
this.configuration = { ...this.configuration, driver: webdriver };
driver(webdriver: WebDriver | ThenableWebDriver | (() => ThenableWebDriver) | (() => WebDriver)) {
this.configuration = {
...this.configuration,
...(
typeof webdriver === 'function'
? { __getDriver: webdriver as () => ThenableWebDriver } // todo: refactor as ...
: { driver: webdriver as ThenableWebDriver } // todo: refactor as ...
),
};
return this;
}

Expand Down
4 changes: 1 addition & 3 deletions lib/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,7 @@ export class Element extends Entity implements Assertable, Matchable {
}

private get driver(): WebDriver {
return typeof this.configuration.driver === 'function'
? this.configuration.driver()
: this.configuration.driver;
return this.config.driver;
}

/* Commands */
Expand Down
4 changes: 4 additions & 0 deletions lib/entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ export abstract class Entity implements Assertable, Matchable/* , Configured */
this.wait = new Wait(this, configuration.timeout);
}

get config(): Configuration {
return this.configuration;
}

/*
* todo: consider assert or shouldMatch aliases for should
* should is good for
Expand Down
1 change: 1 addition & 0 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
* ```
*/
export { Browser } from './browser';
export { browser } from './support/shared';

/**
* AND:
Expand Down
3 changes: 3 additions & 0 deletions lib/support/shared.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { Browser } from '../browser';

export const browser = new Browser();
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "selenidejs",
"description": "Test-oriented Wrapper for Selenium Webdriver",
"homepage": "https://github.com/KnowledgeExpert/selenidejs",
"version": "1.3.7",
"version": "1.4.0",
"main": "built/index.js",
"typings": "built/index.d.ts",
"dependencies": {
Expand Down Expand Up @@ -31,7 +31,8 @@
"clean": "rm -rf ./built",
"compile-test": "npm run clean && tsc --skipLibCheck --project test",
"compile": "npm run clean && tsc --skipLibCheck --project lib",
"startserver": "http-server ./resources -p 4445",
"compile:watch": "npm run clean && tsc -w --skipLibCheck --project lib",
"startserver": "http-server ./resources -p 4446",
"lint": "eslint ./lib --ext .ts",
"pretest": "npm run compile-test",
"test": "nyc --nycrc-path=./test/.nycrc jasmine --config=./test/jasmine.json",
Expand Down

0 comments on commit 247a39c

Please sign in to comment.