diff options
Diffstat (limited to '')
5 files changed, 672 insertions, 0 deletions
diff --git a/remote/test/browser/emulation/browser.ini b/remote/test/browser/emulation/browser.ini new file mode 100644 index 0000000000..c604dd98b3 --- /dev/null +++ b/remote/test/browser/emulation/browser.ini @@ -0,0 +1,13 @@ +[DEFAULT] +tags = remote +subsuite = remote +prefs = + remote.enabled=true +support-files = + !/remote/test/browser/chrome-remote-interface.js + !/remote/test/browser/head.js + head.js + +[browser_setDeviceMetricsOverride.js] +[browser_setTouchEmulationEnabled.js] +[browser_setUserAgentOverride.js] diff --git a/remote/test/browser/emulation/browser_setDeviceMetricsOverride.js b/remote/test/browser/emulation/browser_setDeviceMetricsOverride.js new file mode 100644 index 0000000000..7e7d278b4f --- /dev/null +++ b/remote/test/browser/emulation/browser_setDeviceMetricsOverride.js @@ -0,0 +1,418 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const DOC_SMALL = toDataURL("<div>Hello world"); +const DOC_LARGE = toDataURL("<div style='margin: 150vh 0 0 150vw'>Hello world"); + +const MAX_WINDOW_SIZE = 10000000; + +add_task(async function dimensionsSmallerThanWindow({ client }) { + const { Emulation, Page } = client; + + await loadURL(DOC_SMALL); + const { layoutViewport } = await Page.getLayoutMetrics(); + + const overrideSettings = { + width: Math.floor(layoutViewport.clientWidth / 2), + height: Math.floor(layoutViewport.clientHeight / 3), + deviceScaleFactor: 1.0, + }; + + await Emulation.setDeviceMetricsOverride(overrideSettings); + await loadURL(DOC_SMALL); + + const updatedLayoutMetrics = await Page.getLayoutMetrics(); + is( + updatedLayoutMetrics.layoutViewport.clientWidth, + overrideSettings.width, + "Expected layout viewport width set" + ); + is( + updatedLayoutMetrics.layoutViewport.clientHeight, + overrideSettings.height, + "Expected layout viewport height set" + ); + is( + updatedLayoutMetrics.contentSize.width, + overrideSettings.width, + "Expected content size width set" + ); + is( + updatedLayoutMetrics.contentSize.height, + overrideSettings.height, + "Expected content size height set" + ); +}); + +add_task(async function dimensionsLargerThanWindow({ client }) { + const { Emulation, Page } = client; + + await loadURL(DOC_LARGE); + const { layoutViewport } = await Page.getLayoutMetrics(); + + const overrideSettings = { + width: layoutViewport.clientWidth * 2, + height: layoutViewport.clientHeight * 2, + deviceScaleFactor: 1.0, + }; + + await Emulation.setDeviceMetricsOverride(overrideSettings); + await loadURL(DOC_LARGE); + + const scrollbarSize = await getScrollbarSize(); + const updatedLayoutMetrics = await Page.getLayoutMetrics(); + + is( + updatedLayoutMetrics.layoutViewport.clientWidth, + overrideSettings.width - scrollbarSize.width, + "Expected layout viewport width set" + ); + is( + updatedLayoutMetrics.layoutViewport.clientHeight, + overrideSettings.height - scrollbarSize.height, + "Expected layout viewport height set" + ); +}); + +add_task(async function noSizeChangeForSameWidthAndHeight({ client }) { + const { Emulation, Page } = client; + + await loadURL(DOC_SMALL); + const { layoutViewport } = await Page.getLayoutMetrics(); + + const overrideSettings = { + width: layoutViewport.clientWidth, + height: layoutViewport.clientHeight, + deviceScaleFactor: 1.0, + }; + + await Emulation.setDeviceMetricsOverride(overrideSettings); + await loadURL(DOC_SMALL); + + const updatedLayoutMetrics = await Page.getLayoutMetrics(); + is( + updatedLayoutMetrics.layoutViewport.clientWidth, + layoutViewport.clientWidth, + "Expected layout viewport width set" + ); + is( + updatedLayoutMetrics.layoutViewport.clientHeight, + layoutViewport.clientHeight, + "Expected layout viewport height set" + ); +}); + +add_task(async function noWidthChangeWithZeroWidth({ client }) { + const { Emulation, Page } = client; + + await loadURL(DOC_SMALL); + const { layoutViewport } = await Page.getLayoutMetrics(); + + const overrideSettings = { + width: 0, + height: Math.floor(layoutViewport.clientHeight / 3), + deviceScaleFactor: 1.0, + }; + + await Emulation.setDeviceMetricsOverride(overrideSettings); + await loadURL(DOC_SMALL); + + const updatedLayoutMetrics = await Page.getLayoutMetrics(); + is( + updatedLayoutMetrics.layoutViewport.clientWidth, + layoutViewport.clientWidth, + "Expected layout viewport width set" + ); + is( + updatedLayoutMetrics.layoutViewport.clientHeight, + overrideSettings.height, + "Expected layout viewport height set" + ); +}); + +add_task(async function noHeightChangeWithZeroHeight({ client }) { + const { Emulation, Page } = client; + + await loadURL(DOC_SMALL); + const { layoutViewport } = await Page.getLayoutMetrics(); + + const overrideSettings = { + width: Math.floor(layoutViewport.clientWidth / 2), + height: 0, + deviceScaleFactor: 1.0, + }; + + await Emulation.setDeviceMetricsOverride(overrideSettings); + await loadURL(DOC_SMALL); + + const updatedLayoutMetrics = await Page.getLayoutMetrics(); + is( + updatedLayoutMetrics.layoutViewport.clientWidth, + overrideSettings.width, + "Expected layout viewport width set" + ); + is( + updatedLayoutMetrics.layoutViewport.clientHeight, + layoutViewport.clientHeight, + "Expected layout viewport height set" + ); +}); + +add_task(async function nosizeChangeWithZeroWidthAndHeight({ client }) { + const { Emulation, Page } = client; + + await loadURL(DOC_SMALL); + const { layoutViewport } = await Page.getLayoutMetrics(); + + const overrideSettings = { + width: 0, + height: 0, + deviceScaleFactor: 1.0, + }; + + await Emulation.setDeviceMetricsOverride(overrideSettings); + await loadURL(DOC_SMALL); + + const updatedLayoutMetrics = await Page.getLayoutMetrics(); + is( + updatedLayoutMetrics.layoutViewport.clientWidth, + layoutViewport.clientWidth, + "Expected layout viewport width set" + ); + is( + updatedLayoutMetrics.layoutViewport.clientHeight, + layoutViewport.clientHeight, + "Expected layout viewport height set" + ); +}); + +add_task(async function failsWithNegativeWidth({ client }) { + const { Emulation, Page } = client; + + await loadURL(DOC_SMALL); + const { layoutViewport } = await Page.getLayoutMetrics(); + const ratio = await getContentProperty("devicePixelRatio"); + + const overrideSettings = { + width: -1, + height: Math.floor(layoutViewport.clientHeight / 3), + deviceScaleFactor: 1.0, + }; + + let errorThrown = false; + try { + await Emulation.setDeviceMetricsOverride(overrideSettings); + } catch (e) { + errorThrown = true; + } + ok(errorThrown, "Negative width raised error"); + + await loadURL(DOC_SMALL); + const updatedLayoutMetrics = await Page.getLayoutMetrics(); + + is( + updatedLayoutMetrics.layoutViewport.clientWidth, + layoutViewport.clientWidth, + "Visible layout width hasn't been changed" + ); + is( + updatedLayoutMetrics.layoutViewport.clientHeight, + layoutViewport.clientHeight, + "Visible layout height hasn't been changed" + ); + is( + await getContentProperty("devicePixelRatio"), + ratio, + "Device pixel ratio hasn't been changed" + ); +}); + +add_task(async function failsWithTooLargeWidth({ client }) { + const { Emulation, Page } = client; + + await loadURL(DOC_SMALL); + const { layoutViewport } = await Page.getLayoutMetrics(); + const ratio = await getContentProperty("devicePixelRatio"); + + const overrideSettings = { + width: MAX_WINDOW_SIZE + 1, + height: Math.floor(layoutViewport.clientHeight / 3), + deviceScaleFactor: 1.0, + }; + + let errorThrown = false; + try { + await Emulation.setDeviceMetricsOverride(overrideSettings); + } catch (e) { + errorThrown = true; + } + ok(errorThrown, "Too large width raised error"); + + await loadURL(DOC_SMALL); + const updatedLayoutMetrics = await Page.getLayoutMetrics(); + + is( + updatedLayoutMetrics.layoutViewport.clientWidth, + layoutViewport.clientWidth, + "Visible layout width hasn't been changed" + ); + is( + updatedLayoutMetrics.layoutViewport.clientHeight, + layoutViewport.clientHeight, + "Visible layout height hasn't been changed" + ); + is( + await getContentProperty("devicePixelRatio"), + ratio, + "Device pixel ratio hasn't been changed" + ); +}); + +add_task(async function failsWithNegativeHeight({ client }) { + const { Emulation, Page } = client; + + await loadURL(DOC_SMALL); + const { layoutViewport } = await Page.getLayoutMetrics(); + const ratio = await getContentProperty("devicePixelRatio"); + + const overrideSettings = { + width: Math.floor(layoutViewport.clientWidth / 2), + height: -1, + deviceScaleFactor: 1.0, + }; + + let errorThrown = false; + try { + await Emulation.setDeviceMetricsOverride(overrideSettings); + } catch (e) { + errorThrown = true; + } + ok(errorThrown, "Negative height raised error"); + + await loadURL(DOC_SMALL); + const updatedLayoutMetrics = await Page.getLayoutMetrics(); + + is( + updatedLayoutMetrics.layoutViewport.clientWidth, + layoutViewport.clientWidth, + "Visible layout width hasn't been changed" + ); + is( + updatedLayoutMetrics.layoutViewport.clientHeight, + layoutViewport.clientHeight, + "Visible layout height hasn't been changed" + ); + is( + await getContentProperty("devicePixelRatio"), + ratio, + "Device pixel ratio hasn't been changed" + ); +}); + +add_task(async function failsWithTooLargeHeight({ client }) { + const { Emulation, Page } = client; + + await loadURL(DOC_SMALL); + const { layoutViewport } = await Page.getLayoutMetrics(); + const ratio = await getContentProperty("devicePixelRatio"); + + const overrideSettings = { + width: Math.floor(layoutViewport.clientWidth / 2), + height: MAX_WINDOW_SIZE + 1, + deviceScaleFactor: 1.0, + }; + + let errorThrown = false; + try { + await Emulation.setDeviceMetricsOverride(overrideSettings); + } catch (e) { + errorThrown = true; + } + ok(errorThrown, "Too large height raised error"); + + await loadURL(DOC_SMALL); + const updatedLayoutMetrics = await Page.getLayoutMetrics(); + + is( + updatedLayoutMetrics.layoutViewport.clientWidth, + layoutViewport.clientWidth, + "Visible layout width hasn't been changed" + ); + is( + updatedLayoutMetrics.layoutViewport.clientHeight, + layoutViewport.clientHeight, + "Visible layout height hasn't been changed" + ); + is( + await getContentProperty("devicePixelRatio"), + ratio, + "Device pixel ratio hasn't been changed" + ); +}); + +add_task(async function setDevicePixelRatio({ client }) { + const { Emulation, Page } = client; + + await loadURL(DOC_SMALL); + const { layoutViewport } = await Page.getLayoutMetrics(); + const ratio_orig = await getContentProperty("devicePixelRatio"); + + const overrideSettings = { + width: layoutViewport.clientWidth, + height: layoutViewport.clientHeight, + deviceScaleFactor: ratio_orig * 2, + }; + + // Set a custom pixel ratio + await Emulation.setDeviceMetricsOverride(overrideSettings); + await loadURL(DOC_SMALL); + + is( + await getContentProperty("devicePixelRatio"), + ratio_orig * 2, + "Expected device pixel ratio set" + ); +}); + +add_task(async function failsWithNegativeRatio({ client }) { + const { Emulation, Page } = client; + + await loadURL(DOC_SMALL); + const { layoutViewport } = await Page.getLayoutMetrics(); + const ratio = await getContentProperty("devicePixelRatio"); + + const overrideSettings = { + width: Math.floor(layoutViewport.clientHeight / 2), + height: Math.floor(layoutViewport.clientHeight / 3), + deviceScaleFactor: -1, + }; + + let errorThrown = false; + try { + await Emulation.setDeviceMetricsOverride(overrideSettings); + } catch (e) { + errorThrown = true; + } + ok(errorThrown, "Negative device scale factor raised error"); + + await loadURL(DOC_SMALL); + const updatedLayoutMetrics = await Page.getLayoutMetrics(); + + is( + updatedLayoutMetrics.layoutViewport.clientWidth, + layoutViewport.clientWidth, + "Visible layout width hasn't been changed" + ); + is( + updatedLayoutMetrics.layoutViewport.clientHeight, + layoutViewport.clientHeight, + "Visible layout height hasn't been changed" + ); + is( + await getContentProperty("devicePixelRatio"), + ratio, + "Device pixel ratio hasn't been changed" + ); +}); diff --git a/remote/test/browser/emulation/browser_setTouchEmulationEnabled.js b/remote/test/browser/emulation/browser_setTouchEmulationEnabled.js new file mode 100644 index 0000000000..48315ed0e9 --- /dev/null +++ b/remote/test/browser/emulation/browser_setTouchEmulationEnabled.js @@ -0,0 +1,83 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const DOC_TOUCH = toDataURL("<div>Hello world"); + +add_task(async function invalidEnabledType({ client }) { + const { Emulation } = client; + + for (const enabled of [null, "", 1, [], {}]) { + let errorThrown = ""; + try { + await Emulation.setTouchEmulationEnabled({ enabled }); + } catch (e) { + errorThrown = e.message; + } + ok( + errorThrown.match(/enabled: boolean value expected/), + `Fails with invalid type: ${enabled}` + ); + } +}); + +add_task(async function enableAndDisable({ client }) { + const { Emulation, Runtime } = client; + const url = toDataURL("<p>foo"); + + await enableRuntime(client); + + let contextCreated = Runtime.executionContextCreated(); + await loadURL(url); + let result = await contextCreated; + await assertTouchEnabled(client, result.context, false); + + await Emulation.setTouchEmulationEnabled({ enabled: true }); + contextCreated = Runtime.executionContextCreated(); + await loadURL(url); + result = await contextCreated; + await assertTouchEnabled(client, result.context, true); + + await Emulation.setTouchEmulationEnabled({ enabled: false }); + contextCreated = Runtime.executionContextCreated(); + await loadURL(url); + result = await contextCreated; + await assertTouchEnabled(client, result.context, false); +}); + +add_task(async function receiveTouchEventsWhenEnabled({ client }) { + const { Emulation, Runtime } = client; + + await enableRuntime(client); + + await Emulation.setTouchEmulationEnabled({ enabled: true }); + const contextCreated = Runtime.executionContextCreated(); + await loadURL(DOC_TOUCH); + const { context } = await contextCreated; + + await assertTouchEnabled(client, context, true); + + const { result } = await evaluate(client, context.id, () => { + return new Promise(resolve => { + window.ontouchstart = () => { + resolve(true); + }; + window.dispatchEvent(new Event("touchstart")); + resolve(false); + }); + }); + is(result.value, true, "Received touch event"); +}); + +async function assertTouchEnabled(client, context, expectedStatus) { + const { result } = await evaluate(client, context.id, () => { + return "ontouchstart" in window; + }); + + if (expectedStatus) { + ok(result.value, "Touch emulation enabled"); + } else { + ok(!result.value, "Touch emulation disabled"); + } +} diff --git a/remote/test/browser/emulation/browser_setUserAgentOverride.js b/remote/test/browser/emulation/browser_setUserAgentOverride.js new file mode 100644 index 0000000000..9275675452 --- /dev/null +++ b/remote/test/browser/emulation/browser_setUserAgentOverride.js @@ -0,0 +1,147 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const DOC = toDataURL(`<script>document.write(navigator.userAgent);</script>`); + +add_task(async function invalidPlatform({ client }) { + const { Emulation } = client; + const userAgent = "Mozilla/5.0 (rv: 23) Romanesco/42.0\n"; + + for (const platform of [null, true, 1, [], {}]) { + let errorThrown = ""; + try { + await Emulation.setUserAgentOverride({ userAgent, platform }); + } catch (e) { + errorThrown = e.message; + } + ok( + errorThrown.match(/platform: string value expected/), + `Fails with invalid type: ${platform}` + ); + } +}); + +add_task(async function setAndResetUserAgent({ client }) { + const { Emulation } = client; + const userAgent = "Mozilla/5.0 (rv: 23) Romanesco/42.0"; + + await loadURL(DOC); + const originalUserAgent = await getNavigatorProperty("userAgent"); + + isnot(originalUserAgent, userAgent, "Custom user agent hasn't been set"); + + await Emulation.setUserAgentOverride({ userAgent }); + await loadURL(DOC); + is( + await getNavigatorProperty("userAgent"), + userAgent, + "Custom user agent has been set" + ); + + await Emulation.setUserAgentOverride({ userAgent: "" }); + await loadURL(DOC); + is( + await getNavigatorProperty("userAgent"), + originalUserAgent, + "Custom user agent has been reset" + ); +}); + +add_task(async function invalidUserAgent({ Emulation }) { + const userAgent = "Mozilla/5.0 (rv: 23) Romanesco/42.0\n"; + + await loadURL(DOC); + isnot( + await getNavigatorProperty("userAgent"), + userAgent, + "Custom user agent hasn't been set" + ); + + let errorThrown = false; + try { + await Emulation.setUserAgentOverride({ userAgent }); + } catch (e) { + errorThrown = true; + } + ok(errorThrown, "Invalid user agent format raised error"); +}); + +add_task(async function setAndResetPlatform({ client }) { + const { Emulation } = client; + const userAgent = "Mozilla/5.0 (rv: 23) Romanesco/42.0"; + const platform = "foobar"; + + await loadURL(DOC); + const originalUserAgent = await getNavigatorProperty("userAgent"); + const originalPlatform = await getNavigatorProperty("platform"); + + isnot(userAgent, originalUserAgent, "Custom user agent hasn't been set"); + isnot(platform, originalPlatform, "Custom platform hasn't been set"); + + await Emulation.setUserAgentOverride({ userAgent, platform }); + await loadURL(DOC); + is( + await getNavigatorProperty("userAgent"), + userAgent, + "Custom user agent has been set" + ); + is( + await getNavigatorProperty("platform"), + platform, + "Custom platform has been set" + ); + + await Emulation.setUserAgentOverride({ userAgent: "", platform: "" }); + await loadURL(DOC); + is( + await getNavigatorProperty("userAgent"), + originalUserAgent, + "Custom user agent has been reset" + ); + is( + await getNavigatorProperty("platform"), + originalPlatform, + "Custom platform has been reset" + ); +}); + +add_task(async function notSetForNewContext({ client }) { + const { Emulation, Target } = client; + const userAgent = "Mozilla/5.0 (rv: 23) Romanesco/42.0"; + const platform = "foobar"; + + await Emulation.setUserAgentOverride({ userAgent, platform }); + await loadURL(DOC); + is( + await getNavigatorProperty("userAgent"), + userAgent, + "Custom user agent has been set" + ); + is( + await getNavigatorProperty("platform"), + platform, + "Custom platform has been set" + ); + + const { targetInfo } = await openTab(Target); + await Target.activateTarget({ targetId: targetInfo.targetId }); + + isnot( + await getNavigatorProperty("userAgent"), + userAgent, + "Custom user agent has not been set" + ); + isnot( + await getNavigatorProperty("platform"), + platform, + "Custom platform has not been set" + ); +}); + +async function getNavigatorProperty(prop) { + return SpecialPowers.spawn(gBrowser.selectedBrowser, [prop], _prop => { + return content.navigator[_prop]; + }); +} diff --git a/remote/test/browser/emulation/head.js b/remote/test/browser/emulation/head.js new file mode 100644 index 0000000000..7131e98b6f --- /dev/null +++ b/remote/test/browser/emulation/head.js @@ -0,0 +1,11 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/* import-globals-from ../head.js */ + +Services.scriptloader.loadSubScript( + "chrome://mochitests/content/browser/remote/test/browser/head.js", + this +); |