Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTML: Add tests for optional window.open position, size features #5390

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions common/PrefixedPostMessage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/**
* Supports pseudo-"namespacing" for window-posted messages for a given test
* by generating and using a unique prefix that gets wrapped into message
* objects. This makes it more feasible to have multiple tests that use
* `window.postMessage` in a single test file. Basically, make it possible
* for the each test to listen for only the messages that are pertinent to it.
*
* 'Prefix' not an elegant term to use here but this models itself after
* PrefixedLocalStorage.
*
* PrefixedMessageTest: Instantiate in testharness.js tests to generate
* a new unique-ish prefix that can be used by other test support files
* PrefixedMessageResource: Instantiate in supporting test resource
* files to use/share a prefix generated by a test.
*/
var PrefixedMessage = function () {
this.prefix = '';
this.param = 'prefixedMessage'; // Param to use in querystrings
};

/**
* Generate a URL that adds/replaces param with this object's prefix
* Use to link to test support files that make use of
* PrefixedMessageResource.
*/
PrefixedMessage.prototype.url = function (uri) {
function updateUrlParameter (uri, key, value) {
var i = uri.indexOf('#');
var hash = (i === -1) ? '' : uri.substr(i);
uri = (i === -1) ? uri : uri.substr(0, i);
var re = new RegExp(`([?&])${key}=.*?(&|$)`, 'i');
var separator = uri.indexOf('?') !== -1 ? '&' : '?';
uri = (uri.match(re)) ? uri.replace(re, `$1${key}=${value}$2`) :
`${uri}${separator}${key}=${value}`;
return uri + hash;
}
return updateUrlParameter(uri, this.param, this.prefix);
};

/**
* Add an eventListener on `message` but only invoke the given callback
* for messages whose object contains this object's prefix. Remove the
* event listener once the anticipated message has been received.
*/
PrefixedMessage.prototype.onMessage = function (fn) {
window.addEventListener('message', e => {
if (typeof e.data === 'object' && e.data.hasOwnProperty('prefix')) {
if (e.data.prefix === this.prefix) {
// Only invoke callback when `data` is an object containing
// a `prefix` key with this object's prefix value
// Note fn is invoked with "unwrapped" data first, then the event `e`
// (which contains the full, wrapped e.data should it be needed)
fn.call(this, e.data.data, e);
window.removeEventListener('message', fn);
}
}
});
};

/**
* Instantiate in a test file (e.g. during `setup`) to create a unique-ish
* prefix that can be shared by support files
*/
var PrefixedMessageTest = function () {
PrefixedMessage.call(this);
this.prefix = `${document.location.pathname}-${Math.random()}-${Date.now()}-`;
};
PrefixedMessageTest.prototype = Object.create(PrefixedMessage.prototype);
PrefixedMessageTest.prototype.constructor = PrefixedMessageTest;

/**
* Instantiate in a test support script to use a "prefix" generated by a
* PrefixedMessageTest in a controlling test file. It will look for
* the prefix in a URL param (see also PrefixedMessage#url)
*/
var PrefixedMessageResource = function () {
PrefixedMessage.call(this);
// Check URL querystring for prefix to use
var regex = new RegExp(`[?&]${this.param}(=([^&#]*)|&|#|$)`),
results = regex.exec(document.location.href);
if (results && results[2]) {
this.prefix = results[2];
}
};
PrefixedMessageResource.prototype = Object.create(PrefixedMessage.prototype);
PrefixedMessageResource.prototype.constructor = PrefixedMessageResource;

/**
* This is how a test resource document can "send info" to its
* opener context. It will whatever message is being sent (`data`) in
* an object that injects the prefix.
*/
PrefixedMessageResource.prototype.postToOpener = function (data) {
if (window.opener) {
window.opener.postMessage({
prefix: this.prefix,
data: data
}, '*');
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>HTML: window.open `features`: negative values for legacy `innerwidth`, `innerheight`</title>
<meta name=timeout content=long>
<link rel="help" href="https://html.spec.whatwg.org/multipage/#apis-for-creating-and-navigating-browsing-contexts-by-name">

<!-- user agents are not required to support open features other than `noopener`
and on some platforms position and size features don't make sense -->
<meta name="flags" content="may" />

<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/PrefixedPostMessage.js"></script>
<script>
var windowURL = 'resources/message-opener.html';
var featuresPrefix = `top=0,left=0,`;

// https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-integers

setup (() => {
// Before running tests, open a window using features that mimic
// what would happen if the features tested here were set to invalid
// values in later tests.
// In cases where the value for `innerwidth` or `innerheight` is
// is less than the browser's minimum allowed value for that dimension,
// but NOT 0, the value affected will become the browser's minimum allowed value.

// This should result in a minimally-sized window for later comparison
var featureString = `${featuresPrefix}innerwidth=1,innerheight=1`;
var prefixedMessage = new PrefixedMessageTest();
prefixedMessage.onMessage((data, e) => {
e.source.close();
runWindowTests(data);
});
var win = window.open(prefixedMessage.url(windowURL), '', featureString);
});

function runWindowTests (baselineDimensions) {

// Negative values for `innerwidth` should result in a window with minimum
// valid allowed width
[ 'innerwidth=-404',
'innerwidth=-404.5',
'innerwidth=-404e1'
].forEach(feature => {
async_test(t => {
var prefixedMessage = new PrefixedMessageTest();
var featureString = `${featuresPrefix}height=405,${feature}`;
prefixedMessage.onMessage(t.step_func_done((data, e) => {
e.source.close();
assert_equals(data.width, baselineDimensions.width, `"${feature} is negative and should result in a minimally-wide window"`);
}));
var win = window.open(prefixedMessage.url(windowURL), '', featureString);
}, `features "${feature}" should NOT set "width=404"`);
});

// Negative values for `innerheight` should result in a window with minimum
// valid allowed height
[ 'innerheight=-404',
'innerheight=-404.5',
'innerheight=-404e1'
].forEach(feature => {
async_test(t => {
var prefixedMessage = new PrefixedMessageTest();
var featureString = `${featuresPrefix}width=404,${feature}`;
prefixedMessage.onMessage(t.step_func_done((data, e) => {
e.source.close();
assert_equals(data.height, baselineDimensions.height, `"${feature} is negative and should result in a minimal-height window"`);
}));
var win = window.open(prefixedMessage.url(windowURL), '', featureString);
}, `features "${feature}" should NOT set "height=404"`);
});
}

</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>HTML: window.open `features`: negative values for legacy `screenx`, `screeny`</title>
<meta name=timeout content=long>
<link rel="help" href="https://html.spec.whatwg.org/multipage/#apis-for-creating-and-navigating-browsing-contexts-by-name">

<!-- user agents are not required to support open features other than `noopener`
and on some platforms position and size features don't make sense -->
<meta name="flags" content="may" />

<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/PrefixedPostMessage.js"></script>
<script>
var featuresPrefix = `width=401,height=404,`;
var windowURL = 'resources/message-opener.html';

// https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-integers

setup (() => {
// Before running tests, open a window using features that mimic
// what would happen if the feature tested here were set to 0
// for comparison later.
var featureString = `${featuresPrefix}top=0,left=0`;
var prefixedMessage = new PrefixedMessageTest();
prefixedMessage.onMessage((data, e) => {
e.source.close();
runWindowTests(data);
});
var win = window.open(prefixedMessage.url(windowURL), '', featureString);
});

function runWindowTests (baselineDimensions) {
// Negative values should be interpreted as 0
[ 'screeny=-204',
'screeny=-204.5',
'screeny=-0'
].forEach(feature => {
async_test(t => {
var prefixedMessage = new PrefixedMessageTest();
var featureString = `${featuresPrefix}left=0,${feature}`;
prefixedMessage.onMessage(t.step_func_done((data, e) => {
e.source.close();
assert_equals(data.top, baselineDimensions.top, `"${feature} is negative and should be set to 0"`);
}));
var win = window.open(prefixedMessage.url(windowURL), '', featureString);
}, `features "${feature}" should NOT set "top=204"`);
});

// Negative values should be interpreted as 0
[ 'screenx=-204',
'screenx=-204.5',
'screenx=-0'
].forEach(feature => {
async_test(t => {
var prefixedMessage = new PrefixedMessageTest();
var featureString = `${featuresPrefix}top=0,${feature}`;
prefixedMessage.onMessage(t.step_func_done((data, e) => {
e.source.close();
assert_equals(data.left, baselineDimensions.left, `"${feature} is negative and should be set to 0"`);
}));
var win = window.open(prefixedMessage.url(windowURL), '', featureString);
}, `features "${feature}" should NOT set "left=204"`);
});
}

</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>HTML: window.open `features`: negative values for `top`, `left`</title>
<meta name=timeout content=long>
<link rel="help" href="https://html.spec.whatwg.org/multipage/#apis-for-creating-and-navigating-browsing-contexts-by-name">

<!-- user agents are not required to support open features other than `noopener`
and on some platforms position and size features don't make sense -->
<meta name="flags" content="may" />

<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/PrefixedPostMessage.js"></script>
<script>
var featuresPrefix = `width=401,height=404,`;
var windowURL = 'resources/message-opener.html';

// https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-integers

setup (() => {
// Before running tests, open a window using features that mimic
// what would happen if the feature tested here were set to 0
// for comparison later.
var featureString = `${featuresPrefix}top=0,left=0`;
var prefixedMessage = new PrefixedMessageTest();
prefixedMessage.onMessage((data, e) => {
e.source.close();
runWindowTests(data);
});
var win = window.open(prefixedMessage.url(windowURL), '', featureString);
});

function runWindowTests (baselineDimensions) {

// Negative values for `top`, `left` should be interpreted as 0
[ 'top=-204',
'top=-204.5',
'top=-0'
].forEach(feature => {
async_test(t => {
var prefixedMessage = new PrefixedMessageTest();
var featureString = `${featuresPrefix}left=0,${feature}`;
prefixedMessage.onMessage(t.step_func_done((data, e) => {
e.source.close();
assert_equals(data.top, baselineDimensions.top, `"${feature} is negative and should be set to 0"`);
}));
var win = window.open(prefixedMessage.url(windowURL), '', featureString);
}, `features "${feature}" should NOT set "top=204"`);
});

// Negative values for `top`, `left` should be interpreted as 0
[ 'left=-204',
'left=-204.5',
'left=-0'
].forEach(feature => {
async_test(t => {
var prefixedMessage = new PrefixedMessageTest();
var featureString = `${featuresPrefix}top=0,${feature}`;
prefixedMessage.onMessage(t.step_func_done((data, e) => {
e.source.close();
assert_equals(data.left, baselineDimensions.left, `"${feature} is negative and should be set to 0"`);
}));
var win = window.open(prefixedMessage.url(windowURL), '', featureString);
}, `features "${feature}" should NOT set "left=204"`);
});
}

</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>HTML: window.open `features`: negative values for `width`, `height`</title>
<meta name=timeout content=long>
<link rel="help" href="https://html.spec.whatwg.org/multipage/#apis-for-creating-and-navigating-browsing-contexts-by-name">

<!-- user agents are not required to support open features other than `noopener`
and on some platforms position and size features don't make sense -->
<meta name="flags" content="may" />

<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/PrefixedPostMessage.js"></script>
<script>
var featuresPrefix = `top=0,left=0,`;
var windowURL = 'resources/message-opener.html';

// https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-integers

setup (() => {
// Before running tests, open a window using features that mimic
// what would happen if the features tested here were set to invalid
// values in later tests.
// In cases where the value for `width` or `height` is
// is less than the browser's minimum allowed value for that dimension,
// but NOT 0, the value affected will become the browser's minimum allowed value.

// This should result in a minimally-sized window for later comparison
var featureString = `${featuresPrefix}width=1,height=1`;
var prefixedMessage = new PrefixedMessageTest();
prefixedMessage.onMessage((data, e) => {
e.source.close();
runWindowTests(data);
});
var win = window.open(prefixedMessage.url(windowURL), '', featureString);
});

function runWindowTests (baselineDimensions) {

// Negative values for `width` should result in a window with minimum
// valid allowed width
[ 'width=-404',
'width=-404.5',
'width=-404e1'
].forEach(feature => {
async_test(t => {
var prefixedMessage = new PrefixedMessageTest();
var featureString = `${featuresPrefix}height=405,${feature}`;
prefixedMessage.onMessage(t.step_func_done((data, e) => {
e.source.close();
assert_equals(data.width, baselineDimensions.width, `"${feature} is negative and should result in a minimally-wide window"`);
}));
var win = window.open(prefixedMessage.url(windowURL), '', featureString);
}, `features "${feature}" should NOT set "width=404"`);
});

// Negative values for `height` should result in a window with minimum
// valid allowed height
[ 'height=-404',
'height=-404.5',
'height=-404e1'
].forEach(feature => {
async_test(t => {
var prefixedMessage = new PrefixedMessageTest();
var featureString = `${featuresPrefix}width=404,${feature}`;
prefixedMessage.onMessage(t.step_func_done((data, e) => {
e.source.close();
assert_equals(data.height, baselineDimensions.height, `"${feature} is negative and should result in a minimal-height window"`);
}));
var win = window.open(prefixedMessage.url(windowURL), '', featureString);
}, `features "${feature}" should NOT set "height=404"`);
});
}

</script>
Loading