Skip to content

Commit 56221d8

Browse files
committed
support mobileextension
1 parent 324f6e8 commit 56221d8

File tree

5 files changed

+152
-37
lines changed

5 files changed

+152
-37
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "selenium-appium",
3-
"version": "0.0.6",
3+
"version": "0.0.7",
44
"description": "A selenium-webdriver extension to support native app testing by Mobile JSON Wire Protocol which appium supports, also provides easy wait for element for pages or navigation among pages, and supports PageObject pattern",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
*/
55

66
export { By2 } from './by2';
7-
export { IWebDriver2, createWebDriver2 } from './webdriver2'
7+
export { WebDriver2, createWebDriver2 } from './webdriver2'
88
export { windowsNativeAppCapabilities } from './webdriver2.windows'
99
export { IPageObject, PageObject, waitForPage, clickAndWaitForPage } from './pageobject'

src/mobileextension.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Executor } from "selenium-webdriver/lib/command";
22

3-
export const MobileExtensionCommand = {
3+
export const MobileJSONWireCommand = {
44
GET_NETWORK_CONDITION: 'getNetworkConnection',
55
SET_NETWORK_CONDITION: 'setNetworkConnection',
66
};
@@ -13,14 +13,18 @@ export enum NetworkConnectionType {
1313
None = 0
1414
}
1515

16-
export function configureExecutor(executor: Executor) {
16+
export type NetworkConnectionParam = {
17+
type: NetworkConnectionType
18+
}
19+
20+
export function configureMobileJSONWireExtension(executor: Executor) {
1721
executor.defineCommand(
18-
MobileExtensionCommand.GET_NETWORK_CONDITION,
22+
MobileJSONWireCommand.GET_NETWORK_CONDITION,
1923
'GET',
20-
'/session/:sessionid/network_connection');
24+
'/session/:sessionId/network_connection');
2125

2226
executor.defineCommand(
23-
MobileExtensionCommand.SET_NETWORK_CONDITION,
27+
MobileJSONWireCommand.SET_NETWORK_CONDITION,
2428
'POST',
25-
'/session/:sessionid/network_connection');
29+
'/session/:sessionId/network_connection');
2630
}

src/pageobject.ts

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
* Licensed under the MIT License.
44
*/
55

6-
import { WebDriver, WebElementCondition, By } from "selenium-webdriver";
6+
import { WebDriver, WebElementCondition, Locator } from "selenium-webdriver";
77
import { IWebDriver2 } from './webdriver2';
88

99
export interface IPageObject {
10-
elementExists(by: By): Promise<boolean>;
11-
clickAndWaitForPage<T extends IPageObject>(type: (new (...args: any[]) => T), by: By, timeout?: number): Promise<T>;
10+
clickOn(locator: Locator): Promise<void>;
11+
elementExists(locator: Locator): Promise<boolean>;
12+
clickAndWaitForPage<T extends IPageObject>(type: (new (...args: any[]) => T), locator: Locator, timeout?: number): Promise<T>;
1213
waitForPage<T extends IPageObject>(type: (new (...args: any[]) => T), timeout?: number): Promise<T>;
1314
isReadyConditions(): WebElementCondition[];
1415
waitUntilReady(timeout?: number): Promise<void>;
@@ -25,16 +26,20 @@ export function waitForPage<T extends IPageObject>(type: (new (...args: any[]) =
2526
});
2627
}
2728

28-
export function clickAndWaitForPage<T extends IPageObject>(type: (new (...args: any[]) => T), driver: IWebDriver2, by: By, timeout?: number): Promise<T> {
29+
export function clickAndWaitForPage<T extends IPageObject>(type: (new (...args: any[]) => T), driver: IWebDriver2, locator: Locator, timeout?: number): Promise<T> {
2930
return new Promise<T>((resolve) => {
30-
driver.getBy(by, timeout)
31+
driver.getBy(locator, timeout)
3132
.then(el => { return el.click(); })
3233
.then(() => { return waitForPage(type, driver, timeout); })
3334
.then(page => resolve(page));
3435
});
3536
}
3637

3738
export class PageObject implements IPageObject {
39+
clickOn(locator: Locator): Promise<void> {
40+
return this.webDriver2.getBy(locator).click();
41+
}
42+
3843
private static defaultTimeout: number = 20000; //ms
3944
private timeout?: number;
4045
private getTimeout(timeout?: number): number {
@@ -49,16 +54,16 @@ export class PageObject implements IPageObject {
4954
this.defaultTimeout = ms;
5055
}
5156

52-
protected appiumDriver: IWebDriver2;
57+
protected webDriver2: IWebDriver2;
5358

5459
constructor(driver: IWebDriver2, timeout?: number) {
5560
this.timeout = timeout;
56-
this.appiumDriver = driver;
61+
this.webDriver2 = driver;
5762
}
5863

59-
elementExists(by: By): Promise<boolean> {
64+
elementExists(locator: Locator): Promise<boolean> {
6065
return new Promise<boolean>(resolve =>
61-
this.appiumDriver.seleniumDriver().findElement(by)
66+
this.webDriver2.seleniumDriver().findElement(locator)
6267
.then(() => resolve(true))
6368
.catch(() => resolve(false))
6469
);
@@ -69,20 +74,20 @@ export class PageObject implements IPageObject {
6974
}
7075

7176
waitUntilReady(timeout?: number): Promise<void> {
72-
const webDriver = this.appiumDriver.seleniumDriver();
77+
const webDriver = this.webDriver2.seleniumDriver();
7378
if (webDriver) {
7479
return PageObject.waitForConditions(webDriver, this.isReadyConditions(), this.getTimeout(timeout));
7580
} else {
7681
return Promise.reject("no driver found");
7782
}
7883
}
7984

80-
clickAndWaitForPage<T extends IPageObject>(type: (new (...args: any[]) => T), by: By, timeout?: number): Promise<T> {
81-
return clickAndWaitForPage(type, this.appiumDriver, by, this.getTimeout(timeout));
85+
clickAndWaitForPage<T extends IPageObject>(type: (new (...args: any[]) => T), locator: Locator, timeout?: number): Promise<T> {
86+
return clickAndWaitForPage(type, this.webDriver2, locator, this.getTimeout(timeout));
8287
}
8388

8489
waitForPage<T extends IPageObject>(type: (new (...args: any[]) => T), timeout?: number): Promise<T> {
85-
return waitForPage(type, this.appiumDriver, this.getTimeout(timeout));
90+
return waitForPage(type, this.webDriver2, this.getTimeout(timeout));
8691
}
8792

8893
private static async waitForConditions(driver: WebDriver, conditions: WebElementCondition[], timeout?: number) {

src/webdriver2.ts

Lines changed: 122 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,49 @@
77
import { Locator, WebDriver, Builder, until, Capabilities, WebElement, WebElementPromise, ThenableWebDriver, FileDetector, Session, Actions, WebElementCondition, Condition, Options, Navigation, TargetLocator } from 'selenium-webdriver'
88
import { Command, Executor } from 'selenium-webdriver/lib/command'
99
import { By2 } from './by2';
10-
import { MobileExtensionCommand, NetworkConnectionType } from './mobileextension';
10+
import { MobileJSONWireCommand, NetworkConnectionParam, configureMobileJSONWireExtension } from './mobileextension';
1111

1212
interface INativeWaitAndGet {
13+
/**
14+
* wait until element by accessibility id exists or timeout
15+
*/
1316
getByNativeAccessibilityId(id: string, timeout?: number, message?: string): WebElementPromise;
17+
/**
18+
* wait until element by name exists or timeout
19+
*/
1420
getByNativeName(name: string, timeout?: number, message?: string): WebElementPromise;
21+
/**
22+
* wait until element by id exists or timeout
23+
*/
1524
getByNativeId(id: string, timeout?: number, message?: string): WebElementPromise;
25+
/**
26+
* wait until element by class name exists or timeout
27+
*/
1628
getByNativeclassName(className: string, timeout?: number, message?: string): WebElementPromise;
1729
}
1830

1931
interface IWaitAndGet extends INativeWaitAndGet {
32+
/**
33+
* wait until element by locator exists or timeout
34+
*/
2035
getBy(locator: Locator, timeout?: number, message?: string): WebElementPromise;
2136
}
2237

23-
export interface IWebDriver2 extends IWaitAndGet {
24-
// internal WebDriver is created by user
38+
/**
39+
* @see https://github.com/SeleniumHQ/mobile-spec/blob/master/spec-draft.md
40+
*/
41+
export interface IMobileJSONWireExtension {
42+
/**
43+
* A workaround before WebDriver supports Mobile JSONWire
44+
*/
45+
enableMobileJSONWire(): void;
46+
47+
getNetworkCondition(): Promise<NetworkConnectionParam>;
48+
setNetworkCondition(params: NetworkConnectionParam): Promise<NetworkConnectionParam>;
49+
}
50+
51+
export interface IWebDriver2 extends IWaitAndGet, IMobileJSONWireExtension {
52+
// For user who want to customize the WebDriver create process
2553
attach(webDriver: WebDriver): void;
2654
detach(): void;
2755

@@ -33,117 +61,195 @@ export interface IWebDriver2 extends IWaitAndGet {
3361
isActive(): Promise<boolean>;
3462
seleniumDriver(): WebDriver;
3563
lastError(): any;
36-
64+
3765
}
3866

3967
export class WebDriver2 implements IWebDriver2 {
40-
/**
41-
* Schedules a command to get Chrome network emulation settings.
42-
* @return {!Promise} A promise that will be resolved when network
43-
* emulation settings are retrievied.
44-
*/
45-
getNetworkCondition(): Promise<{type: NetworkConnectionType}> {
46-
return this.execute(new Command(MobileExtensionCommand.GET_NETWORK_CONDITION));
68+
enableMobileJSONWire() {
69+
configureMobileJSONWireExtension(this.getExecutor());
4770
}
4871

49-
setNetworkCondition(type: NetworkConnectionType) {
50-
return this.execute(
51-
new Command(MobileExtensionCommand.SET_NETWORK_CONDITION)
52-
.setParameter('network_conditions', {type: type}));
72+
getNetworkCondition(): Promise<NetworkConnectionParam> {
73+
return this.execute<NetworkConnectionParam>(new Command(MobileJSONWireCommand.GET_NETWORK_CONDITION));
5374
}
5475

76+
setNetworkCondition(params: NetworkConnectionParam) {
77+
return this.execute<NetworkConnectionParam>(
78+
new Command(MobileJSONWireCommand.SET_NETWORK_CONDITION)
79+
.setParameter('type', params.type));
80+
}
81+
82+
/**
83+
* @see WebDriver.wait
84+
*/
5585
wait(condition: WebElementCondition, opt_timeout?: number | undefined, opt_message?: string | undefined): WebElementPromise {
5686
return this.seleniumDriver().wait(condition, opt_timeout, opt_message);
5787
}
5888

89+
/**
90+
* @see WebDriver.wait
91+
*/
5992
wait2<T>(condition: Function | PromiseLike<T> | Condition<T> | ((driver: WebDriver) => T | PromiseLike<T>), opt_timeout?: number | undefined, opt_message?: string | undefined): Promise<T> {
6093
return this.seleniumDriver().wait<T>(condition, opt_timeout, opt_message);
6194
}
6295

96+
/**
97+
* @see WebDriver.sleep
98+
*/
6399
sleep(ms: number): Promise<void> {
64100
return this.seleniumDriver().sleep(ms);
65101
}
66102

67-
[Symbol.toStringTag]: string;
103+
/**
104+
* @see WebDriver.execute
105+
*/
68106
execute<T>(command: Command, description?: string | undefined): Promise<T> {
69107
return this.seleniumDriver().execute<T>(command, description);
70108
}
71109

110+
/**
111+
* @see WebDriver.setFileDetector
112+
*/
72113
setFileDetector(detector: FileDetector): void {
73114
return this.seleniumDriver().setFileDetector(detector);
74115
}
75116

117+
/**
118+
* @see WebDriver.getExecutor
119+
*/
76120
getExecutor(): Executor {
77121
return this.seleniumDriver().getExecutor();
78122
}
79123

124+
/**
125+
* @see WebDriver.getSession
126+
*/
80127
getSession(): Promise<Session> {
81128
return this.seleniumDriver().getSession();
82129
}
83130

131+
/**
132+
* @see WebDriver.getCapabilities
133+
*/
84134
getCapabilities(): Promise<Capabilities> {
85135
return this.seleniumDriver().getCapabilities();
86136
}
87137

138+
/**
139+
* @see WebDriver.quit
140+
*/
88141
quit(): Promise<void> {
89142
return this.stop();
90143
}
91144

145+
/**
146+
* @see WebDriver.actions
147+
*/
92148
actions(options?: { async: boolean; bridge: boolean; } | { async: boolean; } | { bridge: boolean; } | undefined): Actions {
93149
return this.seleniumDriver().actions(options);
94150
}
95151

152+
/**
153+
* @see WebDriver.executeScript
154+
*/
96155
executeScript<T>(script: string | Function, ...var_args: any[]): Promise<T> {
97156
return this.seleniumDriver().executeScript(script, var_args);
98157
}
99158

159+
/**
160+
* @see WebDriver.executeAsyncScript
161+
*/
100162
executeAsyncScript<T>(script: string | Function, ...var_args: any[]): Promise<T> {
101163
return this.seleniumDriver().executeAsyncScript<T>(script, var_args);
102164
}
103165

166+
/**
167+
* @see WebDriver.getWindowHandle
168+
*/
104169
getWindowHandle(): Promise<string> {
105170
return this.seleniumDriver().getWindowHandle();
106171
}
107172

173+
/**
174+
* @see WebDriver.getAllWindowHandles
175+
*/
108176
getAllWindowHandles(): Promise<string[]> {
109177
return this.seleniumDriver().getAllWindowHandles();
110178
}
111179

180+
/**
181+
* @see WebDriver.getPageSource
182+
*/
112183
getPageSource(): Promise<string> {
113184
return this.seleniumDriver().getPageSource();
114185
}
115186

187+
/**
188+
* @see WebDriver.close
189+
*/
116190
close(): Promise<void> {
117191
return this.seleniumDriver().close();
118192
}
119193

194+
/**
195+
* @see WebDriver.get
196+
*/
120197
get(url: string): Promise<void> {
121198
return this.seleniumDriver().get(url);
122199
}
123200

201+
/**
202+
* @see WebDriver.getCurrentUrl
203+
*/
124204
getCurrentUrl(): Promise<string> {
125205
return this.seleniumDriver().getCurrentUrl();
126206
}
127207

208+
/**
209+
* @see WebDriver.getTitle
210+
*/
128211
getTitle(): Promise<string> {
129212
return this.seleniumDriver().getTitle();
130213
}
131214

215+
/**
216+
* @see WebDriver.findElement
217+
*/
132218
findElement(locator: Locator): WebElementPromise {
133219
return this.seleniumDriver().findElement(locator);
134220
}
221+
222+
/**
223+
* @see WebDriver.findElements
224+
*/
135225
findElements(locator: Locator): Promise<WebElement[]> {
136226
return this.seleniumDriver().findElements(locator);
137227
}
228+
229+
/**
230+
* @see WebDriver.takeScreenshot
231+
*/
138232
takeScreenshot(): Promise<string> {
139233
return this.seleniumDriver().takeScreenshot();
140234
}
235+
236+
/**
237+
* @see WebDriver.manage
238+
*/
141239
manage(): Options {
142240
return this.seleniumDriver().manage();
143241
}
242+
243+
/**
244+
* @see WebDriver.navigate
245+
*/
144246
navigate(): Navigation {
145247
return this.seleniumDriver().navigate();
146248
}
249+
250+
/**
251+
* @see WebDriver.switchTo
252+
*/
147253
switchTo(): TargetLocator {
148254
return this.seleniumDriver().switchTo();
149255
}

0 commit comments

Comments
 (0)