Skip to content

Commit f19e074

Browse files
authored
support resize action from multiple windows in chrome (DevExpress#5661)
* support resize action from multiple windows in chrome * fix functional tests * maximize window * fix test for linux * fluxbox * review
1 parent 8e85101 commit f19e074

8 files changed

Lines changed: 155 additions & 12 deletions

File tree

‎.travis.yml‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,14 @@ jobs:
3737
env: GULP_TASK="test-functional-local-multiple-windows"
3838
addons:
3939
chrome: stable
40+
apt:
41+
packages:
42+
- fluxbox
4043
services:
4144
- xvfb
45+
before_script:
46+
- fluxbox >/dev/null 2>&1 &
47+
- sleep 3
4248
- node_js: "stable"
4349
env: GULP_TASK="docker-test-travis"
4450
services:

‎src/browser/provider/built-in/dedicated/chrome/index.js‎

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@ export default {
5454

5555
await this.waitForConnectionReady(browserId);
5656

57-
runtimeInfo.viewportSize = await this.runInitScript(browserId, GET_WINDOW_DIMENSIONS_INFO_SCRIPT);
58-
runtimeInfo.activeWindowId = null;
57+
runtimeInfo.viewportSize = await this.runInitScript(browserId, GET_WINDOW_DIMENSIONS_INFO_SCRIPT);
58+
runtimeInfo.activeWindowId = null;
59+
runtimeInfo.windowDescriptors = {};
5960

6061
if (!disableMultipleWindows)
6162
runtimeInfo.activeWindowId = this.calculateWindowId();
@@ -122,6 +123,25 @@ export default {
122123
};
123124
},
124125

126+
getPageTitle (browserId) {
127+
const runtimeInfo = this.openedBrowsers[browserId];
128+
const isIdlePageShown = !Object.keys(runtimeInfo.windowDescriptors).length;
129+
130+
return isIdlePageShown ? browserId : runtimeInfo.activeWindowId;
131+
},
132+
133+
getWindowDescriptor (browserId) {
134+
const runtimeInfo = this.openedBrowsers[browserId];
135+
136+
return runtimeInfo.windowDescriptors[runtimeInfo.activeWindowId];
137+
},
138+
139+
_setWindowDescriptor (browserId, windowDescriptor) {
140+
const runtimeInfo = this.openedBrowsers[browserId];
141+
142+
runtimeInfo.windowDescriptors[runtimeInfo.activeWindowId] = windowDescriptor;
143+
},
144+
125145
async _ensureWindowIsExpanded (browserId, { height, width, availableHeight, availableWidth, outerWidth, outerHeight }) {
126146
if (height < MIN_AVAILABLE_DIMENSION || width < MIN_AVAILABLE_DIMENSION) {
127147
const newHeight = Math.max(availableHeight, MIN_AVAILABLE_DIMENSION);

‎src/browser/provider/index.ts‎

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,36 @@ export default class BrowserProvider {
7171
};
7272
}
7373

74+
private async _findWindow (browserId: string): Promise<string> {
75+
const pageTitle = this._getPageTitle(browserId);
76+
77+
return browserTools.findWindow(pageTitle);
78+
}
79+
80+
private _getPageTitle (browserId: string): string {
81+
if (this.plugin.getPageTitle)
82+
return this.plugin.getPageTitle(browserId);
83+
84+
return browserId;
85+
}
86+
7487
private _getWindowDescriptor (browserId: string): string | null {
88+
if (this.plugin.getWindowDescriptor)
89+
return this.plugin.getWindowDescriptor(browserId);
90+
7591
return this.localBrowsersInfo[browserId] && this.localBrowsersInfo[browserId].windowDescriptor;
7692
}
7793

94+
private _setWindowDescriptor (browserId: string, windowDescriptor: string | null): void {
95+
if (this.plugin._setWindowDescriptor) {
96+
this.plugin._setWindowDescriptor(browserId, windowDescriptor);
97+
98+
return;
99+
}
100+
101+
this.localBrowsersInfo[browserId].windowDescriptor = windowDescriptor;
102+
}
103+
78104
private _getMaxScreenSize (browserId: string): Size | null {
79105
return this.localBrowsersInfo[browserId] && this.localBrowsersInfo[browserId].maxScreenSize;
80106
}
@@ -147,7 +173,7 @@ export default class BrowserProvider {
147173
let windowDescriptor = null;
148174

149175
try {
150-
windowDescriptor = await browserTools.findWindow(browserId);
176+
windowDescriptor = await this._findWindow(browserId);
151177
}
152178
catch (err) {
153179
// NOTE: We can suppress the error here since we can just disable window manipulation functions
@@ -160,7 +186,7 @@ export default class BrowserProvider {
160186
);
161187
}
162188

163-
this.localBrowsersInfo[browserId].windowDescriptor = windowDescriptor;
189+
this._setWindowDescriptor(browserId, windowDescriptor);
164190
}
165191
}
166192

@@ -183,6 +209,8 @@ export default class BrowserProvider {
183209
}
184210

185211
private async _resizeLocalBrowserWindow (browserId: string, width: number, height: number, currentWidth: number, currentHeight: number): Promise<void> {
212+
await this._ensureBrowserWindowDescriptor(browserId);
213+
186214
const resizeCorrections = this._getResizeCorrections(browserId);
187215

188216
if (resizeCorrections && await browserTools.isMaximized(this._getWindowDescriptor(browserId))) {
@@ -207,6 +235,8 @@ export default class BrowserProvider {
207235
}
208236

209237
private async _maximizeLocalBrowserWindow (browserId: string): Promise<void> {
238+
await this._ensureBrowserWindowDescriptor(browserId);
239+
210240
await browserTools.maximize(this._getWindowDescriptor(browserId));
211241
}
212242

‎test/functional/fixtures/api/es-next/resize-window/test.js‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ describe('[API] Resize window actions', function () {
1818
})
1919
.catch(function (errs) {
2020
expect(errs[0]).to.contains('The "height" argument is expected to be a positive integer, but it was -5.');
21-
expect(errs[0]).to.contains(' > 45 | await t.resizeWindow(500, -5);');
21+
expect(errs[0]).to.contains(' > 48 | await t.resizeWindow(500, -5);');
2222
});
2323
});
2424

@@ -27,7 +27,7 @@ describe('[API] Resize window actions', function () {
2727
.catch(function (errs) {
2828
errorInEachBrowserContains(errs, 'A JavaScript error occurred on "http://localhost:3000/fixtures/api/es-next/resize-window/pages/index.html"', 0);
2929
errorInEachBrowserContains(errs, 'Resize error', 0);
30-
errorInEachBrowserContains(errs, '> 73 | await t.resizeWindow(500, 500);', 0);
30+
errorInEachBrowserContains(errs, '> 76 | await t.resizeWindow(500, 500);', 0);
3131
});
3232
});
3333
});
@@ -48,7 +48,7 @@ describe('[API] Resize window actions', function () {
4848
})
4949
.catch(function (errs) {
5050
expect(errs[0]).to.contains('The "device" argument specifies an unsupported "iPhone555" device. For a list of supported devices, refer to "https://github.com/DevExpress/device-specs/blob/master/viewport-sizes.json"');
51-
expect(errs[0]).to.contains(' > 67 | await t.resizeWindowToFitDevice(\'iPhone555\');');
51+
expect(errs[0]).to.contains(' > 70 | await t.resizeWindowToFitDevice(\'iPhone555\');');
5252
});
5353
});
5454

@@ -57,7 +57,7 @@ describe('[API] Resize window actions', function () {
5757
.catch(function (errs) {
5858
errorInEachBrowserContains(errs, 'A JavaScript error occurred on "http://localhost:3000/fixtures/api/es-next/resize-window/pages/index.html"', 0);
5959
errorInEachBrowserContains(errs, 'Resize error', 0);
60-
errorInEachBrowserContains(errs, '> 79 | await t.resizeWindowToFitDevice(\'iPhone\');', 0);
60+
errorInEachBrowserContains(errs, '> 82 | await t.resizeWindowToFitDevice(\'iPhone\');', 0);
6161
});
6262
});
6363
});
@@ -67,7 +67,7 @@ describe('[API] Resize window actions', function () {
6767
return runTests('./testcafe-fixtures/resize-window-test.js', 'Too big size', { shouldFail: true })
6868
.catch(function (errs) {
6969
errorInEachBrowserContains(errs, 'Unable to resize the window because the specified size exceeds the screen size. On macOS, a window cannot be larger than the screen.', 0);
70-
errorInEachBrowserContains(errs, '> 84 | await t.resizeWindow(hugeWidth, hugeHeight);', 0);
70+
errorInEachBrowserContains(errs, '> 87 | await t.resizeWindow(hugeWidth, hugeHeight);', 0);
7171
});
7272
});
7373
}

‎test/functional/fixtures/api/es-next/resize-window/testcafe-fixtures/resize-window-test.js‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
// NOTE: to preserve callsites, add new tests AFTER the existing ones
22
import { ClientFunction } from 'testcafe';
33
import { expect } from 'chai';
4-
import { saveWindowState, restoreWindowState } from '../../../../../window-helpers';
54

5+
import {
6+
saveWindowState,
7+
restoreWindowState,
8+
getWindowHeight,
9+
getWindowWidth
10+
} from '../../../../../window-helpers';
611

7-
const getWindowWidth = ClientFunction(() => window.innerWidth);
8-
const getWindowHeight = ClientFunction(() => window.innerHeight);
912

1013
const setWindowOnresizeHandler = ClientFunction(() => {
1114
window.onresize = function () {

‎test/functional/fixtures/multiple-windows/test.js‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,4 +288,14 @@ describe('Multiple windows', () => {
288288
return runTests('testcafe-fixtures/api/api-test.js', 'Refresh child and switch to parent', { only: 'chrome' });
289289
});
290290
});
291+
292+
describe('Resize', () => {
293+
it('Resize multiple windows', () => {
294+
return runTests('testcafe-fixtures/api/api-test.js', 'Resize multiple windows', { only: 'chrome' });
295+
});
296+
297+
it('Maximize multiple windows', () => {
298+
return runTests('testcafe-fixtures/api/api-test.js', 'Maximize multiple windows', { only: 'chrome' });
299+
});
300+
});
291301
});

‎test/functional/fixtures/multiple-windows/testcafe-fixtures/api/api-test.js‎

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
import { Selector, ClientFunction } from 'testcafe';
22

3+
import {
4+
saveWindowState,
5+
restoreWindowState,
6+
getWindowHeight,
7+
getWindowWidth
8+
} from '../../../../window-helpers';
9+
10+
311
const reload = ClientFunction(() => window.location.reload());
412

513
const parentUrl = 'http://localhost:3000/fixtures/multiple-windows/pages/api/parent.html';
@@ -329,3 +337,66 @@ test('Refresh child and switch to parent', async t => {
329337

330338
await t.switchToParentWindow();
331339
});
340+
341+
fixture `Resize multiple windows`
342+
.page(parentUrl)
343+
.beforeEach(async t => {
344+
await saveWindowState(t);
345+
})
346+
.afterEach(async t => {
347+
await restoreWindowState(t);
348+
});
349+
350+
test('Resize multiple windows', async t => {
351+
await t.resizeWindow(600, 600);
352+
await t.expect(await getWindowWidth()).eql(600);
353+
await t.expect(await getWindowHeight()).eql(600);
354+
355+
await t.openWindow(child1Url);
356+
357+
await t.resizeWindow(550, 550);
358+
await t.expect(await getWindowWidth()).eql(550);
359+
await t.expect(await getWindowHeight()).eql(550);
360+
361+
await t.switchToParentWindow();
362+
363+
await t.expect(await getWindowWidth()).eql(600);
364+
await t.expect(await getWindowHeight()).eql(600);
365+
366+
await t.resizeWindow(500, 500);
367+
368+
await t.expect(await getWindowWidth()).eql(500);
369+
await t.expect(await getWindowHeight()).eql(500);
370+
});
371+
372+
test('Maximize multiple windows', async t => {
373+
// NOTE: to be sure that window is is maximized we check
374+
// that the width/height value increased at least on 10px
375+
const e = 10;
376+
377+
const parentWidth = await getWindowWidth();
378+
const parentHeight = await getWindowHeight();
379+
380+
await t.openWindow(child1Url);
381+
382+
const childWidth = await getWindowWidth();
383+
const childHeight = await getWindowHeight();
384+
385+
await t.maximizeWindow();
386+
387+
const maxChildWidth = await getWindowWidth();
388+
const maxChildHeight = await getWindowHeight();
389+
390+
await t.expect(maxChildWidth).gt(childWidth + e);
391+
await t.expect(maxChildHeight).gt(childHeight + e);
392+
393+
await t.switchToParentWindow();
394+
395+
await t.maximizeWindow();
396+
397+
const maxParentWidth = await getWindowWidth();
398+
const maxParentHeight = await getWindowHeight();
399+
400+
await t.expect(maxParentWidth).gt(parentWidth + e);
401+
await t.expect(maxParentHeight).gt(parentHeight + e);
402+
});

‎test/functional/window-helpers.js‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,6 @@ export async function restoreWindowState (t) {
2222
else
2323
await t.resizeWindow(t.ctx._savedWindowState.width, t.ctx._savedWindowState.height);
2424
}
25+
26+
export const getWindowWidth = ClientFunction(() => window.innerWidth);
27+
export const getWindowHeight = ClientFunction(() => window.innerHeight);

0 commit comments

Comments
 (0)