diff --git a/src/client/ui/status-bar/index.js b/src/client/ui/status-bar/index.js index a71e526391..a5d559362d 100644 --- a/src/client/ui/status-bar/index.js +++ b/src/client/ui/status-bar/index.js @@ -85,6 +85,7 @@ export default class StatusBar extends serviceUtils.EventEmitter { this.showingTimeout = null; this.windowHeight = document.documentElement ? styleUtils.getHeight(window) : window.innerHeight; + this.maxHeight = 0; this.state = { created: false, @@ -102,6 +103,12 @@ export default class StatusBar extends serviceUtils.EventEmitter { this._initChildListening(); } + get visibleHeight () { + this.maxHeight = Math.max(this.maxHeight, styleUtils.getHeight(this.statusBar)); + + return this.maxHeight; + } + _createButton (text, className) { const button = document.createElement('div'); const icon = document.createElement('div'); @@ -300,13 +307,11 @@ export default class StatusBar extends serviceUtils.EventEmitter { this.windowHeight = window.innerHeight; }); - const statusBarHeight = styleUtils.getHeight(this.statusBar); - listeners.addFirstInternalEventBeforeListener(window, ['mousemove', 'mouseout', 'touchmove'], e => { if (e.type === 'mouseout' && !e.relatedTarget) this._fadeIn(e); else if (e.type === 'mousemove' || e.type === 'touchmove') { - if (e.clientY > this.windowHeight - statusBarHeight) + if (e.clientY > this.windowHeight - this.visibleHeight) this._fadeOut(e); else if (this.state.hidden) this._fadeIn(e); diff --git a/test/functional/fixtures/ui/pages/hiding.html b/test/functional/fixtures/ui/pages/hiding.html new file mode 100644 index 0000000000..ca51984653 --- /dev/null +++ b/test/functional/fixtures/ui/pages/hiding.html @@ -0,0 +1,12 @@ + + + + + Test + + + \ No newline at end of file diff --git a/test/functional/fixtures/ui/test.js b/test/functional/fixtures/ui/test.js index a109bf59b5..a104981bb7 100644 --- a/test/functional/fixtures/ui/test.js +++ b/test/functional/fixtures/ui/test.js @@ -1,3 +1,6 @@ +const config = require('../../config'); + + describe('TestCafe UI', () => { it('Should display correct status', () => { return runTests('./testcafe-fixtures/status-bar-test.js', 'Show status prefix', { assertionTimeout: 3000 }); @@ -6,4 +9,12 @@ describe('TestCafe UI', () => { it('Hide elements when resizing the window', () => { return runTests('./testcafe-fixtures/status-bar-test.js', 'Hide elements when resizing the window', { skip: ['android', 'ipad', 'iphone', 'edge', 'safari'] }); }); + + it('Should hide the status bar even if document was hidden during initialization (GH-7384)', function () { + // NOTE: the test needs direct access to the CDP client through the test controller + if (config.experimentalDebug) + this.skip(); + + return runTests('./testcafe-fixtures/status-bar-test.js', 'Hide status bar after mouse move', { only: ['chrome'] }); + }); }); diff --git a/test/functional/fixtures/ui/testcafe-fixtures/status-bar-test.js b/test/functional/fixtures/ui/testcafe-fixtures/status-bar-test.js index 4737325e70..bcd01e9abb 100644 --- a/test/functional/fixtures/ui/testcafe-fixtures/status-bar-test.js +++ b/test/functional/fixtures/ui/testcafe-fixtures/status-bar-test.js @@ -1,4 +1,5 @@ import { Selector, ClientFunction } from 'testcafe'; +import assert from 'assert'; import OS from 'os-family'; import { saveWindowState, restoreWindowState } from '../../../window-helpers'; @@ -115,3 +116,43 @@ test('Hide elements when resizing the window', async t => { .expect(itemsVisibility.iconVisible).notOk() .expect(statusBarDiv.clientHeight).eql(82); }); + +const TOTAL_DELAY = 5000; +const START_DELAY = 1000; +const AFTER_DELAY = 2000; + +const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); + +async function evaluateOnRemote (client, func) { + const { result } = await client.Runtime.evaluate({ expression: `(${func.toString()})()`, returnByValue: true }); + + return result.value; +} + +async function simulateMoveAndCheckStatusBar (t) { + await delay(START_DELAY); + + const browserConnection = t.testRun.browserConnection; + const providerPlugin = browserConnection.provider.plugin; + const browserClient = providerPlugin._getBrowserProtocolClient(providerPlugin.openedBrowsers[browserConnection.id]); + const remoteInterface = await browserClient.getActiveClient(); + + const windowSize = await evaluateOnRemote(remoteInterface, () => ({ width: innerWidth, height: innerHeight })); + + await remoteInterface.Input.dispatchMouseEvent({ type: 'mouseMoved', x: windowSize.width / 2, y: windowSize.height - 1 }); + + await delay(AFTER_DELAY); + + const statusBarState = await evaluateOnRemote(remoteInterface, () => window['%testCafeDriverInstance%'].statusBar.state); + + assert.ok(statusBarState.hidden); +} + +test + .page('../pages/hiding.html') + ('Hide status bar after mouse move', async t => { + await Promise.all([ + t.wait(TOTAL_DELAY), + simulateMoveAndCheckStatusBar(t), + ]); + });