Skip to content

Commit 244bc6a

Browse files
authored
Merge pull request #4 from gemini-testing/FEI-18599.wait_page_open
feat: add wrapper over "url" in order to wait until the page is completely open
2 parents 12d4824 + 1c9a595 commit 244bc6a

File tree

7 files changed

+125
-1
lines changed

7 files changed

+125
-1
lines changed

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
module.exports = {
22
extends: 'gemini-testing',
3+
env: {browser: true},
34
root: true
45
};

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ module.exports = {
3737
browsers: {
3838
safari13: {
3939
commands: [
40+
'url',
4041
'swipe',
4142
'touch',
4243
'dragAndDrop'
@@ -53,6 +54,7 @@ module.exports = {
5354
### Existing safari commands:
5455

5556
Wrappers over existing commands:
57+
* **url** - wrapper over wdio "url" in order to wait until the page is completely open (used timeout from [`hermione.pageLoadTimeout`](https://github.com/gemini-testing/hermione#pageloadtimeout) or `30000` ms). In [appium-xcuitest-driver](https://github.com/appium/appium-xcuitest-driver) page is open with using the `xcrun` utility - `xcrun simctl openurl` which just tells the simulator to open the page and does not wait anything;
5658
* **swipe** - replaces wdio "swipe" in order to perform swipe by coordinates in native context;
5759
* **touch** - replaces wdio "touch" in order to perform touch click by coordinates in native context;
5860
* **dragAndDrop** - replaces wdio "dragAndDrop" in order to perform drag and drop elements by coordinates in native context.

lib/commands/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

33
module.exports = {
4+
url: require('./url'),
45
swipe: require('./swipe'),
56
touch: require('./touch'),
67
dragAndDrop: require('./dragAndDrop')

lib/commands/url.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict';
2+
3+
const {PAGE_LOAD_TIMEOUT} = require('../constants');
4+
5+
module.exports = (browser, config) => {
6+
const baseUrlFn = browser.url;
7+
const pageLoadTimeout = config.pageLoadTimeout || PAGE_LOAD_TIMEOUT;
8+
9+
browser.addCommand('url', async (uri) => {
10+
if (!uri) {
11+
return baseUrlFn.call(this, uri);
12+
}
13+
14+
// in order to clear the page from previous search result
15+
await browser.execute(() => document.body.remove());
16+
await baseUrlFn.call(this, uri);
17+
18+
await browser.waitUntil(
19+
() => browser.isVisible('body'),
20+
pageLoadTimeout,
21+
`The page did not load in ${pageLoadTimeout} ms`
22+
);
23+
}, true);
24+
};

lib/constants.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22

33
module.exports = {
44
NATIVE_CONTEXT: 'NATIVE_APP',
5-
WAIT_BETWEEN_ACTIONS_IN_MS: 100
5+
WAIT_BETWEEN_ACTIONS_IN_MS: 100,
6+
PAGE_LOAD_TIMEOUT: 30000
67
};

test/lib/commands/url.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
'use strict';
2+
3+
const _ = require('lodash');
4+
const wrapUrlCommand = require('lib/commands/url');
5+
const {PAGE_LOAD_TIMEOUT} = require('lib/constants');
6+
const {mkBrowser_} = require('../../utils');
7+
8+
describe('"url" command', () => {
9+
let browser, initialDocument;
10+
11+
const wrapUrlCommand_ = (browser, opts = {}) => {
12+
opts = _.defaultsDeep(opts, {
13+
pageLoadTimeout: null
14+
});
15+
16+
wrapUrlCommand(browser, opts);
17+
};
18+
19+
beforeEach(() => {
20+
browser = mkBrowser_();
21+
initialDocument = global.document;
22+
global.document = {body: {remove: sinon.stub()}};
23+
});
24+
25+
afterEach(() => {
26+
sinon.restore();
27+
global.document = initialDocument;
28+
});
29+
30+
it('should wrap "url" command', () => {
31+
wrapUrlCommand_(browser);
32+
33+
assert.calledOnceWith(browser.addCommand, 'url', sinon.match.func, true);
34+
});
35+
36+
it('should call base "url" command if url is not passed', async () => {
37+
const baseUrlFn = browser.url;
38+
wrapUrlCommand_(browser);
39+
40+
await browser.url();
41+
42+
assert.calledOnce(baseUrlFn);
43+
assert.notCalled(browser.execute);
44+
});
45+
46+
it('should remove body element from the page before make request', async () => {
47+
const baseUrlFn = browser.url;
48+
wrapUrlCommand_(browser);
49+
50+
browser.execute.callsFake(() => {
51+
browser.execute.firstCall.args[0]();
52+
});
53+
54+
await browser.url('/?text=test');
55+
56+
assert.calledOnceWith(browser.execute, sinon.match.func);
57+
assert.calledOnce(global.document.body.remove);
58+
assert.callOrder(browser.execute, baseUrlFn);
59+
});
60+
61+
it('should wait until request will be completed', async () => {
62+
wrapUrlCommand_(browser, {pageLoadTimeout: 100500});
63+
64+
browser.waitUntil.callsFake(() => {
65+
browser.waitUntil.firstCall.args[0]();
66+
});
67+
68+
await browser.url('/?text=test');
69+
70+
assert.calledOnceWith(
71+
browser.waitUntil,
72+
sinon.match.func,
73+
100500,
74+
'The page did not load in 100500 ms'
75+
);
76+
assert.calledOnceWith(browser.isVisible, 'body');
77+
});
78+
79+
it('should use default "pageLoadTimeout" if it does not specified in browser config', async () => {
80+
wrapUrlCommand_(browser, {pageLoadTimeout: null});
81+
82+
await browser.url('/?text=test');
83+
84+
assert.calledOnceWith(
85+
browser.waitUntil,
86+
sinon.match.func,
87+
PAGE_LOAD_TIMEOUT,
88+
`The page did not load in ${PAGE_LOAD_TIMEOUT} ms`
89+
);
90+
});
91+
});

test/utils.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,15 @@ exports.mkBrowser_ = () => {
2020
const session = Promise.resolve();
2121

2222
session.executionContext = {};
23+
session.url = sinon.stub().named('url').resolves();
2324
session.touchAction = sinon.stub().named('touchAction').resolves();
2425
session.getElementSize = sinon.stub().named('getElementSize').resolves({});
2526
session.getLocation = sinon.stub().named('getLocation').resolves({});
2627
session.context = sinon.stub().named('context').resolves({value: 'default-ctx'});
2728
session.contexts = sinon.stub().named('contexts').resolves({value: ['default-ctx-1', 'default-ctx-2']});
29+
session.execute = sinon.stub().named('execute').resolves();
30+
session.waitUntil = sinon.stub().named('waitUntil').resolves();
31+
session.isVisible = sinon.stub().named('isVisible').resolves();
2832

2933
session.addCommand = sinon.stub().callsFake((name, command) => {
3034
session[name] = command;

0 commit comments

Comments
 (0)