diff options
Diffstat (limited to 'testing/mochitest/tests/browser')
36 files changed, 1123 insertions, 0 deletions
diff --git a/testing/mochitest/tests/browser/browser.toml b/testing/mochitest/tests/browser/browser.toml new file mode 100644 index 0000000000..9367630370 --- /dev/null +++ b/testing/mochitest/tests/browser/browser.toml @@ -0,0 +1,102 @@ +[DEFAULT] +support-files = [ + "head.js", + "dummy.html"] + +['browser_BrowserTestUtils.js'] +skip-if = [ + "verify", +] + +['browser_add_task.js'] + +['browser_async.js'] + +['browser_browserLoaded_content_loaded.js'] +https_first_disabled = true + +['browser_document_builder_sjs.js'] + +['browser_fail.js'] +skip-if = [ + "verify", +] + +['browser_fail_add_task.js'] +skip-if = [ + "verify", +] + +['browser_fail_add_task_uncaught_rejection.js'] +skip-if = [ + "verify", +] + +['browser_fail_async.js'] +skip-if = [ + "verify", +] + +['browser_fail_if.js'] +fail-if = true + +['browser_fail_throw.js'] +skip-if = [ + "verify", +] + +['browser_fail_timeout.js'] +skip-if = true # Disabled beacuse it takes too long (bug 1178959) + +['browser_fail_uncaught_rejection.js'] +skip-if = [ + "verify", +] + +['browser_fail_uncaught_rejection_expected.js'] +skip-if = [ + "verify", +] + +['browser_fail_uncaught_rejection_expected_multi.js'] +skip-if = [ + "verify", +] + +['browser_fail_unexpectedTimeout.js'] +skip-if = true # Disabled beacuse it takes too long (bug 1178959) + +['browser_getTestFile.js'] +support-files = [ + "test-dir/*", + "waitForFocusPage.html"] + +['browser_head.js'] + +['browser_parameters.js'] + +['browser_pass.js'] + +['browser_privileges.js'] + +['browser_requestLongerTimeout.js'] +skip-if = true # Disabled beacuse it takes too long (bug 1178959) + +['browser_sanityException.js'] + +['browser_sanityException2.js'] + +['browser_setup_runs_first.js'] + +['browser_setup_runs_for_only_tests.js'] + +['browser_tasks_skip.js'] + +['browser_tasks_skipall.js'] + +['browser_uncaught_rejection_expected.js'] + +['browser_waitForFocus.js'] + +['browser_zz_fail_openwindow.js'] +skip-if = true # this catches outside of the main loop to find an extra window diff --git a/testing/mochitest/tests/browser/browser_BrowserTestUtils.js b/testing/mochitest/tests/browser/browser_BrowserTestUtils.js new file mode 100644 index 0000000000..cde2b8b927 --- /dev/null +++ b/testing/mochitest/tests/browser/browser_BrowserTestUtils.js @@ -0,0 +1,312 @@ +function getLastEventDetails(browser) { + return SpecialPowers.spawn(browser, [], async function () { + return content.document.getElementById("out").textContent; + }); +} + +add_task(async function () { + let onClickEvt = + 'document.getElementById("out").textContent = event.target.localName + "," + event.clientX + "," + event.clientY;'; + const url = + "<body onclick='" + + onClickEvt + + "' style='margin: 0'>" + + "<button id='one' style='margin: 0; margin-left: 16px; margin-top: 14px; width: 80px; height: 40px;'>Test</button>" + + "<div onmousedown='event.preventDefault()' style='margin: 0; width: 80px; height: 60px;'>Other</div>" + + "<span id='out'></span></body>"; + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "data:text/html," + url + ); + + let browser = tab.linkedBrowser; + await BrowserTestUtils.synthesizeMouseAtCenter("#one", {}, browser); + let details = await getLastEventDetails(browser); + + is(details, "button,56,34", "synthesizeMouseAtCenter"); + + await BrowserTestUtils.synthesizeMouse("#one", 4, 9, {}, browser); + details = await getLastEventDetails(browser); + is(details, "button,20,23", "synthesizeMouse"); + + await BrowserTestUtils.synthesizeMouseAtPoint(15, 6, {}, browser); + details = await getLastEventDetails(browser); + is(details, "body,15,6", "synthesizeMouseAtPoint on body"); + + await BrowserTestUtils.synthesizeMouseAtPoint( + 20, + 22, + {}, + browser.browsingContext + ); + details = await getLastEventDetails(browser); + is(details, "button,20,22", "synthesizeMouseAtPoint on button"); + + await BrowserTestUtils.synthesizeMouseAtCenter("body > div", {}, browser); + details = await getLastEventDetails(browser); + is(details, "div,40,84", "synthesizeMouseAtCenter with complex selector"); + + let cancelled = await BrowserTestUtils.synthesizeMouseAtCenter( + "body > div", + { type: "mousedown" }, + browser + ); + details = await getLastEventDetails(browser); + is( + details, + "div,40,84", + "synthesizeMouseAtCenter mousedown with complex selector" + ); + ok( + cancelled, + "synthesizeMouseAtCenter mousedown with complex selector not cancelled" + ); + + cancelled = await BrowserTestUtils.synthesizeMouseAtCenter( + "body > div", + { type: "mouseup" }, + browser + ); + details = await getLastEventDetails(browser); + is( + details, + "div,40,84", + "synthesizeMouseAtCenter mouseup with complex selector" + ); + ok( + !cancelled, + "synthesizeMouseAtCenter mouseup with complex selector cancelled" + ); + + gBrowser.removeTab(tab); +}); + +add_task(async function testSynthesizeMouseAtPointsButtons() { + let onMouseEvt = + 'document.getElementById("mouselog").textContent += "/" + [event.type,event.clientX,event.clientY,event.button,event.buttons].join(",");'; + + let getLastMouseEventDetails = browser => { + return SpecialPowers.spawn(browser, [], async () => { + let log = content.document.getElementById("mouselog").textContent; + content.document.getElementById("mouselog").textContent = ""; + return log; + }); + }; + + const url = + "<body" + + "' onmousedown='" + + onMouseEvt + + "' onmousemove='" + + onMouseEvt + + "' onmouseup='" + + onMouseEvt + + "' style='margin: 0'>" + + "<div style='margin: 0; width: 80px; height: 60px;'>Mouse area</div>" + + "<span id='mouselog'></span>" + + "</body>"; + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "data:text/html," + url + ); + + let browser = tab.linkedBrowser; + let details; + + await BrowserTestUtils.synthesizeMouseAtPoint( + 21, + 22, + { + type: "mousemove", + }, + browser.browsingContext + ); + details = await getLastMouseEventDetails(browser); + is(details, "/mousemove,21,22,0,0", "synthesizeMouseAtPoint mousemove"); + + await BrowserTestUtils.synthesizeMouseAtPoint( + 22, + 23, + {}, + browser.browsingContext + ); + details = await getLastMouseEventDetails(browser); + is( + details, + "/mousedown,22,23,0,1/mouseup,22,23,0,0", + "synthesizeMouseAtPoint default action includes buttons on mousedown only" + ); + + await BrowserTestUtils.synthesizeMouseAtPoint( + 20, + 22, + { + type: "mousedown", + }, + browser.browsingContext + ); + details = await getLastMouseEventDetails(browser); + is( + details, + "/mousedown,20,22,0,1", + "synthesizeMouseAtPoint mousedown includes buttons" + ); + + await BrowserTestUtils.synthesizeMouseAtPoint( + 21, + 20, + { + type: "mouseup", + }, + browser.browsingContext + ); + details = await getLastMouseEventDetails(browser); + is(details, "/mouseup,21,20,0,0", "synthesizeMouseAtPoint mouseup"); + + await BrowserTestUtils.synthesizeMouseAtPoint( + 20, + 22, + { + type: "mousedown", + button: 2, + }, + browser.browsingContext + ); + details = await getLastMouseEventDetails(browser); + is( + details, + "/mousedown,20,22,2,2", + + "synthesizeMouseAtPoint mousedown respects specified button 2" + ); + + await BrowserTestUtils.synthesizeMouseAtPoint( + 21, + 20, + { + type: "mouseup", + button: 2, + }, + browser.browsingContext + ); + details = await getLastMouseEventDetails(browser); + is( + details, + "/mouseup,21,20,2,0", + "synthesizeMouseAtPoint mouseup with button 2" + ); + + gBrowser.removeTab(tab); +}); + +add_task(async function mouse_in_iframe() { + let onClickEvt = "document.body.lastChild.textContent = event.target.id;"; + const url = `<iframe style='margin: 30px;' src='data:text/html,<body onclick="${onClickEvt}"> + <p><button>One</button></p><p><button id="two">Two</button></p><p id="out"></p></body>'></iframe> + <iframe style='margin: 10px;' src='data:text/html,<body onclick="${onClickEvt}"> + <p><button>Three</button></p><p><button id="four">Four</button></p><p id="out"></p></body>'></iframe>`; + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "data:text/html," + url + ); + + let browser = tab.linkedBrowser; + + await BrowserTestUtils.synthesizeMouse( + "#two", + 5, + 10, + {}, + browser.browsingContext.children[0] + ); + + let details = await getLastEventDetails(browser.browsingContext.children[0]); + is(details, "two", "synthesizeMouse"); + + await BrowserTestUtils.synthesizeMouse( + "#four", + 5, + 10, + {}, + browser.browsingContext.children[1] + ); + details = await getLastEventDetails(browser.browsingContext.children[1]); + is(details, "four", "synthesizeMouse"); + + gBrowser.removeTab(tab); +}); + +add_task(async function () { + await BrowserTestUtils.registerAboutPage( + registerCleanupFunction, + "about-pages-are-cool", + getRootDirectory(gTestPath) + "dummy.html", + 0 + ); + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "about:about-pages-are-cool", + true + ); + ok(tab, "Successfully created an about: page and loaded it."); + BrowserTestUtils.removeTab(tab); + try { + await BrowserTestUtils.unregisterAboutPage("about-pages-are-cool"); + ok(true, "Successfully unregistered the about page."); + } catch (ex) { + ok(false, "Should not throw unregistering a known about: page"); + } + await BrowserTestUtils.unregisterAboutPage("random-other-about-page").then( + () => { + ok( + false, + "Should not have succeeded unregistering an unknown about: page." + ); + }, + () => { + ok( + true, + "Should have returned a rejected promise trying to unregister an unknown about page" + ); + } + ); +}); + +add_task(async function testWaitForEvent() { + // A promise returned by BrowserTestUtils.waitForEvent should not be resolved + // in the same event tick as the event listener is called. + let eventListenerCalled = false; + let waitForEventResolved = false; + // Use capturing phase to make sure the event listener added by + // BrowserTestUtils.waitForEvent is called before the normal event listener + // below. + let eventPromise = BrowserTestUtils.waitForEvent( + gBrowser, + "dummyevent", + true + ); + eventPromise.then(() => { + waitForEventResolved = true; + }); + // Add normal event listener that is called after the event listener added by + // BrowserTestUtils.waitForEvent. + gBrowser.addEventListener( + "dummyevent", + () => { + eventListenerCalled = true; + is( + waitForEventResolved, + false, + "BrowserTestUtils.waitForEvent promise resolution handler shouldn't be called at this point." + ); + }, + { once: true } + ); + + var event = new CustomEvent("dummyevent"); + gBrowser.dispatchEvent(event); + + await eventPromise; + + is(eventListenerCalled, true, "dummyevent listener should be called"); +}); diff --git a/testing/mochitest/tests/browser/browser_add_task.js b/testing/mochitest/tests/browser/browser_add_task.js new file mode 100644 index 0000000000..2466112834 --- /dev/null +++ b/testing/mochitest/tests/browser/browser_add_task.js @@ -0,0 +1,31 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +var test1Complete = false; +var test2Complete = false; + +function executeWithTimeout() { + return new Promise(resolve => + executeSoon(function () { + ok(true, "we get here after a timeout"); + resolve(); + }) + ); +} + +add_task(async function asyncTest_no1() { + await executeWithTimeout(); + test1Complete = true; +}); + +add_task(async function asyncTest_no2() { + await executeWithTimeout(); + test2Complete = true; +}); + +add_task(function () { + ok(test1Complete, "We have been through test 1"); + ok(test2Complete, "We have been through test 2"); +}); diff --git a/testing/mochitest/tests/browser/browser_async.js b/testing/mochitest/tests/browser/browser_async.js new file mode 100644 index 0000000000..d07cb21740 --- /dev/null +++ b/testing/mochitest/tests/browser/browser_async.js @@ -0,0 +1,9 @@ +function test() { + waitForExplicitFinish(); + function done() { + ok(true, "timeout ran"); + finish(); + } + // eslint-disable-next-line mozilla/no-arbitrary-setTimeout + setTimeout(done, 500); +} diff --git a/testing/mochitest/tests/browser/browser_browserLoaded_content_loaded.js b/testing/mochitest/tests/browser/browser_browserLoaded_content_loaded.js new file mode 100644 index 0000000000..fa29e03d23 --- /dev/null +++ b/testing/mochitest/tests/browser/browser_browserLoaded_content_loaded.js @@ -0,0 +1,53 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +function isDOMLoaded(browser) { + return SpecialPowers.spawn(browser, [], async function () { + Assert.equal( + content.document.readyState, + "complete", + "Browser should be loaded." + ); + }); +} + +// It checks if calling BrowserTestUtils.browserLoaded() yields +// browser object. +add_task(async function () { + let tab = BrowserTestUtils.addTab(gBrowser, "http://example.com"); + let browser = tab.linkedBrowser; + await BrowserTestUtils.browserLoaded(browser); + await isDOMLoaded(browser); + gBrowser.removeTab(tab); +}); + +// It checks that BrowserTestUtils.browserLoaded() works well with +// promise.all(). +add_task(async function () { + let tabURLs = [ + `http://example.org`, + `http://mochi.test:8888`, + `http://test:80`, + ]; + // Add tabs, get the respective browsers + let browsers = tabURLs.map( + u => BrowserTestUtils.addTab(gBrowser, u).linkedBrowser + ); + + // wait for promises to settle + await Promise.all( + (function* () { + for (let b of browsers) { + yield BrowserTestUtils.browserLoaded(b); + } + })() + ); + for (const browser of browsers) { + await isDOMLoaded(browser); + } + // cleanup + browsers + .map(browser => gBrowser.getTabForBrowser(browser)) + .forEach(tab => gBrowser.removeTab(tab)); +}); diff --git a/testing/mochitest/tests/browser/browser_document_builder_sjs.js b/testing/mochitest/tests/browser/browser_document_builder_sjs.js new file mode 100644 index 0000000000..4b653a792d --- /dev/null +++ b/testing/mochitest/tests/browser/browser_document_builder_sjs.js @@ -0,0 +1,74 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// Checks that document-builder.sjs works as expected +add_task(async function assertHtmlParam() { + const html = "<main><h1>I'm built different</h1></main>"; + const delay = 5000; + + const params = new URLSearchParams({ + delay, + html, + }); + params.append("headers", "x-header-1:a"); + params.append("headers", "x-header-2:b"); + + const startTime = performance.now(); + const request = new Request( + `https://example.com/document-builder.sjs?${params}` + ); + info("Do a fetch request to document-builder.sjs"); + const response = await fetch(request); + const duration = performance.now() - startTime; + + is(response.status, 200, "Response is a 200"); + ok( + duration > delay, + `The delay parameter works as expected (took ${duration}ms)` + ); + + const responseText = await response.text(); + is(responseText, html, "The response has the expected content"); + + is( + response.headers.get("content-type"), + "text/html", + "response has the expected content-type" + ); + is( + response.headers.get("x-header-1"), + "a", + "first header was set as expected" + ); + is( + response.headers.get("x-header-2"), + "b", + "second header was set as expected" + ); +}); + +add_task(async function assertFileParam() { + const file = `browser/testing/mochitest/tests/browser/dummy.html`; + const request = new Request( + `https://example.com/document-builder.sjs?file=${file}` + ); + + info("Do a fetch request to document-builder.sjs with a `file` parameter"); + const response = await fetch(request); + is(response.status, 200, "Response is a 200"); + is( + response.headers.get("content-type"), + "text/html", + "response has the expected content-type" + ); + + const responseText = await response.text(); + const parser = new DOMParser(); + const doc = parser.parseFromString(responseText, "text/html"); + is( + doc.body.innerHTML.trim(), + "This is a dummy page", + "The response has the file content" + ); +}); diff --git a/testing/mochitest/tests/browser/browser_fail.js b/testing/mochitest/tests/browser/browser_fail.js new file mode 100644 index 0000000000..f6b439fb0d --- /dev/null +++ b/testing/mochitest/tests/browser/browser_fail.js @@ -0,0 +1,10 @@ +setExpectedFailuresForSelfTest(6); + +function test() { + ok(false, "fail ok"); + is(true, false, "fail is"); + isnot(true, true, "fail isnot"); + todo(true, "fail todo"); + todo_is(true, true, "fail todo_is"); + todo_isnot(true, false, "fail todo_isnot"); +} diff --git a/testing/mochitest/tests/browser/browser_fail_add_task.js b/testing/mochitest/tests/browser/browser_fail_add_task.js new file mode 100644 index 0000000000..aeb1129943 --- /dev/null +++ b/testing/mochitest/tests/browser/browser_fail_add_task.js @@ -0,0 +1,27 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +setExpectedFailuresForSelfTest(4); + +function rejectOnNextTick(error) { + return new Promise((resolve, reject) => executeSoon(() => reject(error))); +} + +add_task(async function failWithoutError() { + await rejectOnNextTick(undefined); +}); + +add_task(async function failWithString() { + await rejectOnNextTick("This is a string"); +}); + +add_task(async function failWithInt() { + await rejectOnNextTick(42); +}); + +// This one should display a stack trace +add_task(async function failWithError() { + await rejectOnNextTick(new Error("This is an error")); +}); diff --git a/testing/mochitest/tests/browser/browser_fail_add_task_uncaught_rejection.js b/testing/mochitest/tests/browser/browser_fail_add_task_uncaught_rejection.js new file mode 100644 index 0000000000..8a42740acb --- /dev/null +++ b/testing/mochitest/tests/browser/browser_fail_add_task_uncaught_rejection.js @@ -0,0 +1,29 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +setExpectedFailuresForSelfTest(4); + +async function rejectOnNextTick(error) { + await Promise.resolve(); + + Promise.reject(error); +} + +add_task(async function failWithoutError() { + await rejectOnNextTick(undefined); +}); + +add_task(async function failWithString() { + await rejectOnNextTick("This is a string"); +}); + +add_task(async function failWithInt() { + await rejectOnNextTick(42); +}); + +// This one should display a stack trace +add_task(async function failWithError() { + await rejectOnNextTick(new Error("This is an error")); +}); diff --git a/testing/mochitest/tests/browser/browser_fail_async.js b/testing/mochitest/tests/browser/browser_fail_async.js new file mode 100644 index 0000000000..6f284bf2aa --- /dev/null +++ b/testing/mochitest/tests/browser/browser_fail_async.js @@ -0,0 +1,9 @@ +setExpectedFailuresForSelfTest(1); + +function test() { + waitForExplicitFinish(); + executeSoon(() => { + ok(false, "fail"); + finish(); + }); +} diff --git a/testing/mochitest/tests/browser/browser_fail_if.js b/testing/mochitest/tests/browser/browser_fail_if.js new file mode 100644 index 0000000000..dad56e7dac --- /dev/null +++ b/testing/mochitest/tests/browser/browser_fail_if.js @@ -0,0 +1,4 @@ +// We expect this test to fail because it is marked as fail-if in the manifest. +function test() { + ok(false, "fail ok"); +} diff --git a/testing/mochitest/tests/browser/browser_fail_throw.js b/testing/mochitest/tests/browser/browser_fail_throw.js new file mode 100644 index 0000000000..585b47561d --- /dev/null +++ b/testing/mochitest/tests/browser/browser_fail_throw.js @@ -0,0 +1,5 @@ +setExpectedFailuresForSelfTest(1); + +function test() { + throw new Error("thrown exception"); +} diff --git a/testing/mochitest/tests/browser/browser_fail_timeout.js b/testing/mochitest/tests/browser/browser_fail_timeout.js new file mode 100644 index 0000000000..44030a00f0 --- /dev/null +++ b/testing/mochitest/tests/browser/browser_fail_timeout.js @@ -0,0 +1,9 @@ +function test() { + function end() { + ok(false, "should have timed out"); + finish(); + } + waitForExplicitFinish(); + // eslint-disable-next-line mozilla/no-arbitrary-setTimeout + setTimeout(end, 40000); +} diff --git a/testing/mochitest/tests/browser/browser_fail_uncaught_rejection.js b/testing/mochitest/tests/browser/browser_fail_uncaught_rejection.js new file mode 100644 index 0000000000..86d3e77b7f --- /dev/null +++ b/testing/mochitest/tests/browser/browser_fail_uncaught_rejection.js @@ -0,0 +1,14 @@ +setExpectedFailuresForSelfTest(2); + +function test() { + Promise.reject(new Error("Promise rejection.")); + (async () => { + throw new Error("Synchronous rejection from async function."); + })(); + + // The following rejections are caught, so they won't result in failures. + Promise.reject(new Error("Promise rejection.")).catch(() => {}); + (async () => { + throw new Error("Synchronous rejection from async function."); + })().catch(() => {}); +} diff --git a/testing/mochitest/tests/browser/browser_fail_uncaught_rejection_expected.js b/testing/mochitest/tests/browser/browser_fail_uncaught_rejection_expected.js new file mode 100644 index 0000000000..6c30d4eb3d --- /dev/null +++ b/testing/mochitest/tests/browser/browser_fail_uncaught_rejection_expected.js @@ -0,0 +1,12 @@ +setExpectedFailuresForSelfTest(1); + +// The test will fail because there is only one of two expected rejections. +const { PromiseTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/PromiseTestUtils.sys.mjs" +); +PromiseTestUtils.expectUncaughtRejection(/Promise rejection./); +PromiseTestUtils.expectUncaughtRejection(/Promise rejection./); + +function test() { + Promise.reject(new Error("Promise rejection.")); +} diff --git a/testing/mochitest/tests/browser/browser_fail_uncaught_rejection_expected_multi.js b/testing/mochitest/tests/browser/browser_fail_uncaught_rejection_expected_multi.js new file mode 100644 index 0000000000..cea5a870aa --- /dev/null +++ b/testing/mochitest/tests/browser/browser_fail_uncaught_rejection_expected_multi.js @@ -0,0 +1,11 @@ +setExpectedFailuresForSelfTest(1); + +// The test will fail because an expected uncaught rejection is actually caught. +const { PromiseTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/PromiseTestUtils.sys.mjs" +); +PromiseTestUtils.expectUncaughtRejection(/Promise rejection./); + +function test() { + Promise.reject(new Error("Promise rejection.")).catch(() => {}); +} diff --git a/testing/mochitest/tests/browser/browser_fail_unexpectedTimeout.js b/testing/mochitest/tests/browser/browser_fail_unexpectedTimeout.js new file mode 100644 index 0000000000..d0aef231bd --- /dev/null +++ b/testing/mochitest/tests/browser/browser_fail_unexpectedTimeout.js @@ -0,0 +1,14 @@ +function test() { + function message() { + info("This should delay timeout"); + } + function end() { + ok(true, "Should have not timed out, but notified long running test"); + finish(); + } + waitForExplicitFinish(); + // eslint-disable-next-line mozilla/no-arbitrary-setTimeout + setTimeout(message, 20000); + // eslint-disable-next-line mozilla/no-arbitrary-setTimeout + setTimeout(end, 40000); +} diff --git a/testing/mochitest/tests/browser/browser_getTestFile.js b/testing/mochitest/tests/browser/browser_getTestFile.js new file mode 100644 index 0000000000..154bf716da --- /dev/null +++ b/testing/mochitest/tests/browser/browser_getTestFile.js @@ -0,0 +1,37 @@ +add_task(async function test() { + SimpleTest.doesThrow(function () { + getTestFilePath("/browser_getTestFile.js"); + }, "getTestFilePath rejects absolute paths"); + + await Promise.all([ + IOUtils.exists(getTestFilePath("browser_getTestFile.js")).then(function ( + exists + ) { + ok(exists, "getTestFilePath consider the path as being relative"); + }), + + IOUtils.exists(getTestFilePath("./browser_getTestFile.js")).then(function ( + exists + ) { + ok(exists, "getTestFilePath also accepts explicit relative path"); + }), + + IOUtils.exists(getTestFilePath("./browser_getTestFileTypo.xul")).then( + function (exists) { + ok(!exists, "getTestFilePath do not throw if the file doesn't exists"); + } + ), + + IOUtils.readUTF8(getTestFilePath("test-dir/test-file")).then(function ( + content + ) { + is(content, "foo\n", "getTestFilePath can reach sub-folder files 1/2"); + }), + + IOUtils.readUTF8(getTestFilePath("./test-dir/test-file")).then(function ( + content + ) { + is(content, "foo\n", "getTestFilePath can reach sub-folder files 2/2"); + }), + ]); +}); diff --git a/testing/mochitest/tests/browser/browser_head.js b/testing/mochitest/tests/browser/browser_head.js new file mode 100644 index 0000000000..3e3893f2d4 --- /dev/null +++ b/testing/mochitest/tests/browser/browser_head.js @@ -0,0 +1,16 @@ +var testVar; + +registerCleanupFunction(function () { + ok(true, "I'm a cleanup function in test file"); + is( + this.testVar, + "I'm a var in test file", + "Test cleanup function scope is correct" + ); +}); + +function test() { + is(headVar, "I'm a var in head file", "Head variables are set"); + ok(headMethod(), "Head methods are imported"); + testVar = "I'm a var in test file"; +} diff --git a/testing/mochitest/tests/browser/browser_parameters.js b/testing/mochitest/tests/browser/browser_parameters.js new file mode 100644 index 0000000000..813cd662ba --- /dev/null +++ b/testing/mochitest/tests/browser/browser_parameters.js @@ -0,0 +1,3 @@ +function test() { + ok(SimpleTest.harnessParameters, "Should have parameters"); +} diff --git a/testing/mochitest/tests/browser/browser_pass.js b/testing/mochitest/tests/browser/browser_pass.js new file mode 100644 index 0000000000..e512ff374a --- /dev/null +++ b/testing/mochitest/tests/browser/browser_pass.js @@ -0,0 +1,13 @@ +function test() { + SimpleTest.requestCompleteLog(); + ok(true, "pass ok"); + is(true, true, "pass is"); + isnot(false, true, "pass isnot"); + todo(false, "pass todo"); + todo_is(false, true, "pass todo_is"); + todo_isnot(true, true, "pass todo_isnot"); + info("info message"); + + var func = is; + func(true, true, "pass indirect is"); +} diff --git a/testing/mochitest/tests/browser/browser_privileges.js b/testing/mochitest/tests/browser/browser_privileges.js new file mode 100644 index 0000000000..042a928b9c --- /dev/null +++ b/testing/mochitest/tests/browser/browser_privileges.js @@ -0,0 +1,17 @@ +function test() { + // simple test to confirm we have chrome privileges + let hasPrivileges = true; + + // this will throw an exception if we are not running with privileges + try { + // eslint-disable-next-line no-unused-vars, mozilla/use-services + var prefs = Cc["@mozilla.org/preferences-service;1"].getService( + Ci.nsIPrefBranch + ); + } catch (e) { + hasPrivileges = false; + } + + // if we get here, we must have chrome privileges + ok(hasPrivileges, "running with chrome privileges"); +} diff --git a/testing/mochitest/tests/browser/browser_requestLongerTimeout.js b/testing/mochitest/tests/browser/browser_requestLongerTimeout.js new file mode 100644 index 0000000000..4107e11fd0 --- /dev/null +++ b/testing/mochitest/tests/browser/browser_requestLongerTimeout.js @@ -0,0 +1,10 @@ +function test() { + requestLongerTimeout(2); + function end() { + ok(true, "should not time out"); + finish(); + } + waitForExplicitFinish(); + // eslint-disable-next-line mozilla/no-arbitrary-setTimeout + setTimeout(end, 40000); +} diff --git a/testing/mochitest/tests/browser/browser_sanityException.js b/testing/mochitest/tests/browser/browser_sanityException.js new file mode 100644 index 0000000000..2678dd80ad --- /dev/null +++ b/testing/mochitest/tests/browser/browser_sanityException.js @@ -0,0 +1,5 @@ +function test() { + ok(true, "ok called"); + expectUncaughtException(); + throw new Error("this is a deliberately thrown exception"); +} diff --git a/testing/mochitest/tests/browser/browser_sanityException2.js b/testing/mochitest/tests/browser/browser_sanityException2.js new file mode 100644 index 0000000000..4512ed982b --- /dev/null +++ b/testing/mochitest/tests/browser/browser_sanityException2.js @@ -0,0 +1,11 @@ +function test() { + waitForExplicitFinish(); + ok(true, "ok called"); + executeSoon(function () { + expectUncaughtException(); + throw new Error("this is a deliberately thrown exception"); + }); + executeSoon(function () { + finish(); + }); +} diff --git a/testing/mochitest/tests/browser/browser_setup_runs_first.js b/testing/mochitest/tests/browser/browser_setup_runs_first.js new file mode 100644 index 0000000000..6b9ce145da --- /dev/null +++ b/testing/mochitest/tests/browser/browser_setup_runs_first.js @@ -0,0 +1,14 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +let someVar = 1; + +add_task(() => { + is(someVar, 2, "Should get updated by setup which runs first."); +}); + +add_setup(() => { + someVar = 2; +}); diff --git a/testing/mochitest/tests/browser/browser_setup_runs_for_only_tests.js b/testing/mochitest/tests/browser/browser_setup_runs_for_only_tests.js new file mode 100644 index 0000000000..d1b811b2d1 --- /dev/null +++ b/testing/mochitest/tests/browser/browser_setup_runs_for_only_tests.js @@ -0,0 +1,15 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +let someVar = 1; + +add_setup(() => { + someVar = 2; +}); + +/* eslint-disable mozilla/reject-addtask-only */ +add_task(() => { + is(someVar, 2, "Setup should have run, even though this is the only test."); +}).only(); diff --git a/testing/mochitest/tests/browser/browser_tasks_skip.js b/testing/mochitest/tests/browser/browser_tasks_skip.js new file mode 100644 index 0000000000..99f3e8d2c2 --- /dev/null +++ b/testing/mochitest/tests/browser/browser_tasks_skip.js @@ -0,0 +1,21 @@ +"use strict"; + +add_task(async function skipMeNot1() { + Assert.ok(true, "Well well well."); +}); + +add_task(async function skipMe1() { + Assert.ok(false, "Not skipped after all."); +}).skip(); + +add_task(async function skipMeNot2() { + Assert.ok(true, "Well well well."); +}); + +add_task(async function skipMeNot3() { + Assert.ok(true, "Well well well."); +}); + +add_task(async function skipMe2() { + Assert.ok(false, "Not skipped after all."); +}).skip(); diff --git a/testing/mochitest/tests/browser/browser_tasks_skipall.js b/testing/mochitest/tests/browser/browser_tasks_skipall.js new file mode 100644 index 0000000000..13290e58ba --- /dev/null +++ b/testing/mochitest/tests/browser/browser_tasks_skipall.js @@ -0,0 +1,23 @@ +"use strict"; + +/* eslint-disable mozilla/reject-addtask-only */ + +add_task(async function skipMe1() { + Assert.ok(false, "Not skipped after all."); +}); + +add_task(async function skipMe2() { + Assert.ok(false, "Not skipped after all."); +}).skip(); + +add_task(async function skipMe3() { + Assert.ok(false, "Not skipped after all."); +}).only(); + +add_task(async function skipMeNot() { + Assert.ok(true, "Well well well."); +}).only(); + +add_task(async function skipMe4() { + Assert.ok(false, "Not skipped after all."); +}); diff --git a/testing/mochitest/tests/browser/browser_uncaught_rejection_expected.js b/testing/mochitest/tests/browser/browser_uncaught_rejection_expected.js new file mode 100644 index 0000000000..2ee9f23d79 --- /dev/null +++ b/testing/mochitest/tests/browser/browser_uncaught_rejection_expected.js @@ -0,0 +1,12 @@ +const { PromiseTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/PromiseTestUtils.sys.mjs" +); +PromiseTestUtils.allowMatchingRejectionsGlobally(/Allowed rejection./); +PromiseTestUtils.expectUncaughtRejection(/Promise rejection./); +PromiseTestUtils.expectUncaughtRejection(/Promise rejection./); + +function test() { + Promise.reject(new Error("Promise rejection.")); + Promise.reject(new Error("Promise rejection.")); + Promise.reject(new Error("Allowed rejection.")); +} diff --git a/testing/mochitest/tests/browser/browser_waitForFocus.js b/testing/mochitest/tests/browser/browser_waitForFocus.js new file mode 100644 index 0000000000..b41b07f423 --- /dev/null +++ b/testing/mochitest/tests/browser/browser_waitForFocus.js @@ -0,0 +1,160 @@ +const gBaseURL = "https://example.com/browser/testing/mochitest/tests/browser/"; + +function promiseTabLoadEvent(tab, url) { + let promise = BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, url); + if (url) { + tab.linkedBrowser.loadURI(Services.io.newURI(url)); + } + return promise; +} + +// Load a new blank tab +add_task(async function () { + await BrowserTestUtils.openNewForegroundTab(gBrowser); + + gURLBar.focus(); + + let browser = gBrowser.selectedBrowser; + await SimpleTest.promiseFocus(browser, true); + + is( + document.activeElement, + browser, + "Browser is focused when about:blank is loaded" + ); + + gBrowser.removeCurrentTab(); + gURLBar.focus(); +}); + +add_task(async function () { + await BrowserTestUtils.openNewForegroundTab(gBrowser); + + gURLBar.focus(); + + let browser = gBrowser.selectedBrowser; + // If we're running in e10s, we don't have access to the content + // window, so only test window arguments in non-e10s mode. + if (browser.contentWindow) { + await SimpleTest.promiseFocus(browser.contentWindow, true); + + is( + document.activeElement, + browser, + "Browser is focused when about:blank is loaded" + ); + } + + gBrowser.removeCurrentTab(); + gURLBar.focus(); +}); + +// Load a tab with a subframe inside it and wait until the subframe is focused +add_task(async function () { + let tab = BrowserTestUtils.addTab(gBrowser); + gBrowser.selectedTab = tab; + + let browser = gBrowser.getBrowserForTab(tab); + // If we're running in e10s, we don't have access to the content + // window, so only test <iframe> arguments in non-e10s mode. + if (browser.contentWindow) { + await promiseTabLoadEvent(tab, gBaseURL + "waitForFocusPage.html"); + + await SimpleTest.promiseFocus(browser.contentWindow); + + is( + document.activeElement, + browser, + "Browser is focused when page is loaded" + ); + + await SimpleTest.promiseFocus(browser.contentWindow.frames[0]); + + is( + browser.contentWindow.document.activeElement.localName, + "iframe", + "Child iframe is focused" + ); + } + + gBrowser.removeCurrentTab(); +}); + +// Pass a browser to promiseFocus +add_task(async function () { + await BrowserTestUtils.openNewForegroundTab( + gBrowser, + gBaseURL + "waitForFocusPage.html" + ); + + gURLBar.focus(); + + await SimpleTest.promiseFocus(gBrowser.selectedBrowser); + + is( + document.activeElement, + gBrowser.selectedBrowser, + "Browser is focused when promiseFocus is passed a browser" + ); + + gBrowser.removeCurrentTab(); +}); + +// Tests focusing the sidebar, which is in a parent process subframe +// and then switching the focus to another window. +add_task(async function () { + await SidebarUI.show("viewBookmarksSidebar"); + + gURLBar.focus(); + + // Focus the sidebar. + await SimpleTest.promiseFocus(SidebarUI.browser); + is( + document.activeElement, + document.getElementById("sidebar"), + "sidebar focused" + ); + ok( + document.activeElement.contentDocument.hasFocus(), + "sidebar document hasFocus" + ); + + // Focus the sidebar again, which should cause no change. + await SimpleTest.promiseFocus(SidebarUI.browser); + is( + document.activeElement, + document.getElementById("sidebar"), + "sidebar focused" + ); + ok( + document.activeElement.contentDocument.hasFocus(), + "sidebar document hasFocus" + ); + + // Focus another window. The sidebar should no longer be focused. + let window2 = await BrowserTestUtils.openNewBrowserWindow(); + is( + document.activeElement, + document.getElementById("sidebar"), + "sidebar focused after window 2 opened" + ); + ok( + !document.activeElement.contentDocument.hasFocus(), + "sidebar document hasFocus after window 2 opened" + ); + + // Focus the first window again and the sidebar should be focused again. + await SimpleTest.promiseFocus(window); + is( + document.activeElement, + document.getElementById("sidebar"), + "sidebar focused after window1 refocused" + ); + ok( + document.activeElement.contentDocument.hasFocus(), + "sidebar document hasFocus after window1 refocused" + ); + + await BrowserTestUtils.closeWindow(window2); + await SidebarUI.hide(); +}); diff --git a/testing/mochitest/tests/browser/browser_zz_fail_openwindow.js b/testing/mochitest/tests/browser/browser_zz_fail_openwindow.js new file mode 100644 index 0000000000..2f7fb04d78 --- /dev/null +++ b/testing/mochitest/tests/browser/browser_zz_fail_openwindow.js @@ -0,0 +1,13 @@ +function test() { + waitForExplicitFinish(); + function done() { + ok(true, "timeout ran"); + finish(); + } + + ok(OpenBrowserWindow(), "opened browser window"); + // and didn't close it! + + // eslint-disable-next-line mozilla/no-arbitrary-setTimeout + setTimeout(done, 10000); +} diff --git a/testing/mochitest/tests/browser/dummy.html b/testing/mochitest/tests/browser/dummy.html new file mode 100644 index 0000000000..7954185285 --- /dev/null +++ b/testing/mochitest/tests/browser/dummy.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<html> + <meta http-equiv="Content-Security-Policy" content="default-src 'none'; object-src 'none'"></meta> + <title>This is a dummy page</title> + <meta charset="utf-8"> + <body>This is a dummy page</body> +</html> diff --git a/testing/mochitest/tests/browser/head.js b/testing/mochitest/tests/browser/head.js new file mode 100644 index 0000000000..fdfd097176 --- /dev/null +++ b/testing/mochitest/tests/browser/head.js @@ -0,0 +1,16 @@ +var headVar = "I'm a var in head file"; + +function headMethod() { + return true; +} + +ok(true, "I'm a test in head file"); + +registerCleanupFunction(function () { + ok(true, "I'm a cleanup function in head file"); + is( + this.headVar, + "I'm a var in head file", + "Head cleanup function scope is correct" + ); +}); diff --git a/testing/mochitest/tests/browser/test-dir/test-file b/testing/mochitest/tests/browser/test-dir/test-file new file mode 100644 index 0000000000..257cc5642c --- /dev/null +++ b/testing/mochitest/tests/browser/test-dir/test-file @@ -0,0 +1 @@ +foo diff --git a/testing/mochitest/tests/browser/waitForFocusPage.html b/testing/mochitest/tests/browser/waitForFocusPage.html new file mode 100644 index 0000000000..286ad7849c --- /dev/null +++ b/testing/mochitest/tests/browser/waitForFocusPage.html @@ -0,0 +1,4 @@ +<body> + <input> + <iframe id="f" src="data:text/plain,Test" width=80 height=80></iframe> +</body> |