Skip to content

Commit

Permalink
test: Flatten test environment for Chromecast (shaka-project#6640)
Browse files Browse the repository at this point in the history
Chromecast WebDriver Server and Karma both used iframes, which caused
complications when testing on Chromecast. The test environment couldn't
directly access `cast.__platform__` APIs, and more recently stopped
being able to access EME due to presumed mistakes in the platform's
implementation of iframe permission policies.

This resolves the issue by removing iframes at both levels.

- Flatten Karma's environment using "useIframe: false" and "runInParent: true"
- Remove test flag --single-run; not supported in combination with Karma's "useIframe: false" option
- Add a test boot file to force closure to use dynamic script tags instead of document.write; required with Karma's "useIframe: false" option
 - Adjust screenshot tests not to assume an iframe host
 - Fix compatibilty between Tizen and Karma's useIframe:false
- joeyparrish/karma@32e8735
- joeyparrish/karma@f2132cc
  • Loading branch information
joeyparrish committed May 22, 2024
1 parent 7ab0691 commit c48e435
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 34 deletions.
12 changes: 0 additions & 12 deletions build/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,17 +166,6 @@ def __init__(self, description):
help='Instead of Karma starting browsers, Karma will wait for a '
'browser to connect to it.',
action='store_true')
running_commands.add_argument(
'--single-run',
help='Run the test when browsers capture and exit.',
dest='single_run',
action='store_true',
default=True)
running_commands.add_argument(
'--no-single-run',
help='Do not shut down Karma when tests are complete.',
dest='single_run',
action='store_false')
running_commands.add_argument(
'--random',
help='Run the tests in a random order. This can be used with --seed '
Expand Down Expand Up @@ -412,7 +401,6 @@ def ParseArguments(self, args):
'reporters',
'report_slower_than',
'seed',
'single_run',
'spec_hide_passed',
'test_custom_asset',
'test_custom_license_server',
Expand Down
12 changes: 10 additions & 2 deletions karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ module.exports = (config) => {
'node_modules/eme-encryption-scheme-polyfill/dist/eme-encryption-scheme-polyfill.js',

// load closure base, the deps tree, and the uncompiled library
'test/test/closure-boot.js',
'node_modules/google-closure-library/closure/goog/base.js',
'dist/deps.js',
'shaka-player.uncompiled.js',
Expand Down Expand Up @@ -309,6 +310,12 @@ module.exports = (config) => {
// Hide the list of connected clients in Karma, to make screenshots more
// stable.
clientDisplayNone: true,
// Run directly in the top frame, instead of in an iframe. This makes it
// easier to work around cross-origin frame issues or frame permissions
// issues when testing platforms like Chromecast, where there is already
// an iframe involved in the test framework.
useIframe: false, // No iframe
runInParent: true, // No new window
// Only capture the client's logs if the settings want logging.
captureConsole: !!settings.logging && settings.logging != 'none',
// |args| must be an array; pass a key-value map as the sole client
Expand Down Expand Up @@ -369,8 +376,9 @@ module.exports = (config) => {
autoWatch: settings.auto_watch,

// Do a single run of the tests on captured browsers and then quit.
// Defaults to true.
singleRun: settings.single_run,
// This is required when running tests without Karma's iframe.
// (See useIframe above.)
singleRun: true,

// Set the time limit (ms) that should be used to identify slow tests.
reportSlowerThan: settings.report_slower_than,
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions test/test/closure-boot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*! @license
* Shaka Player
* Copyright 2016 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

// These definitions will override the defaults when the Closure base library
// is loaded. This is necessary to get Closure to load dependencies by
// creating DOM elements in JavaScript, rather than the legacy default of using
// document.write(). This is more compatible with a wider variety of setups,
// and allows us to enable Karma options {useIframe: false, runInParent: true}
// to test in a single frame.
window['CLOSURE_UNCOMPILED_DEFINES'] = {
'goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING': true,
};
29 changes: 11 additions & 18 deletions test/test/util/layout_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ shaka.test.LayoutTests = class {
// We need our own ID for Karma to look up the WebDriver connection.
// For manually-connected browsers, this ID may not exist. In those cases,
// this method is expected to return false.
const parentUrlParams = window.parent.location.search;
const urlParams = location.search;

const buffer = await shaka.test.Util.fetch(
'/screenshot/isSupported' + parentUrlParams);
'/screenshot/isSupported' + urlParams);
const json = shaka.util.StringUtils.fromUTF8(buffer);
const ok = /** @type {boolean} */(JSON.parse(json));
return ok;
Expand Down Expand Up @@ -96,18 +96,12 @@ shaka.test.LayoutTests = class {
// We need our own ID for Karma to look up the WebDriver connection.
// By this point, we should have passed supportsScreenshots(), so the ID
// should definitely be there.
const parentUrlParams = window.parent.location.search;
goog.asserts.assert(parentUrlParams.includes('id='), 'No ID in URL!');

// Tests run in an iframe. So we also need the coordinates of that iframe
// within the page, so that the screenshot can be consistently cropped to
// the element we care about.
const iframe = /** @type {HTMLIFrameElement} */(
window.parent.document.getElementById('context'));
const iframeRect = iframe.getBoundingClientRect();
const urlParams = location.search;
goog.asserts.assert(urlParams.includes('id='), 'No ID in URL!');

const elementRect = element.getBoundingClientRect();
const x = iframeRect.left + elementRect.left;
const y = iframeRect.top + elementRect.top;
const x = elementRect.left;
const y = elementRect.top;
const width = elementRect.width;
const height = elementRect.height;

Expand All @@ -116,8 +110,8 @@ shaka.test.LayoutTests = class {
// so it can convert coordinates before cropping. This value, as opposed to
// document.body.getBoundingClientRect(), seems to most accurately reflect
// the size of the screenshot area.
const bodyWidth = window.parent.innerWidth;
const bodyHeight = window.parent.innerHeight;
const bodyWidth = window.innerWidth;
const bodyHeight = window.innerHeight;

// In addition to the id param from the top-level window, pass these
// parameters to the screenshot endpoint in Karma.
Expand All @@ -129,7 +123,7 @@ shaka.test.LayoutTests = class {
}

const buffer = await shaka.test.Util.fetch(
'/screenshot/diff' + parentUrlParams + paramsString);
'/screenshot/diff' + urlParams + paramsString);
const json = shaka.util.StringUtils.fromUTF8(buffer);
const similarity = /** @type {number} */(JSON.parse(json));

Expand All @@ -154,8 +148,7 @@ shaka.test.LayoutTests = class {
// cropping issues.
element.style.backgroundColor = 'green';

// Make sure the element is in the top-left corner of the iframe that
// contains the tests.
// Make sure the element is in the top-left corner of the window.
element.style.top = '0';
element.style.left = '0';
element.style.position = 'fixed';
Expand Down

0 comments on commit c48e435

Please sign in to comment.