blob: c96c219c0248f100c3f7b363a2aeca79cdebdec7 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Expire" content="0"/>
<meta charset="utf-8">
<title>click_link_test.html</title>
<link rel="stylesheet" href="/filez/_main/third_party/js/qunit/qunit.css">
<script src="/filez/_main/third_party/js/qunit/qunit.js"></script>
<script src="/filez/_main/third_party/js/qunit/qunit_test_runner.js"></script>
<script src="test_bootstrap.js"></script>
<script type="text/javascript">
goog.require('bot.action');
goog.require('bot.locators');
goog.require('bot.userAgent');
goog.require('goog.Promise');
goog.require('goog.Uri');
goog.require('goog.debug.DivConsole');
goog.require('goog.log');
goog.require('goog.dom');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('goog.math.Coordinate');
goog.require('goog.style');
goog.require('goog.userAgent');
goog.require('goog.userAgent.product');
</script>
<script type="text/javascript">
var divConsole;
var iframe, iframeWindow, other, otherWindow;
var link, link2;
var findElement = bot.locators.findElement;
var findElements = bot.locators.findElements;
var log = goog.log.getLogger('click_link_test');
QUnit.testStart(function() {
iframe = bot.locators.findElement({id: 'iframe'});
iframeWindow = goog.dom.getFrameContentWindow(iframe);
otherFrame = bot.locators.findElement({id: 'other'});
otherFrameWindow = goog.dom.getFrameContentWindow(otherFrame);
iframeWindow.location = resolveUrl('testdata/click_iframe.html');
link = bot.locators.findElement({id: 'link'});
link2 = bot.locators.findElement({id: 'link2'});
goog.events.removeAll(link);
goog.events.removeAll(link2);
link.blur();
link2.blur();
window.focus();
});
function checkActionCompatibility(action) {
if (action == bot.action.tap) {
return bot.events.SUPPORTS_TOUCH_EVENTS;
}
return true;
}
function waitForLoad(iframe) {
return new goog.Promise(function(done) {
goog.events.listenOnce(iframe, 'load', done);
});
}
function timeout() {
return new goog.Promise(function(done) {
setTimeout(done, 0);
});
}
function resolveUrl(url) {
return goog.Uri.resolve(window.location.href, url).toString();
}
function getClickTarget(url) {
var doc = goog.dom.getFrameContentDocument(iframe);
var target = bot.locators.findElement({'id': 'iframeClickTarget'}, doc);
target.href = resolveUrl(url);
return target;
}
function executesDefaultHandler(assert, action) {
if (!checkActionCompatibility(action)) {
assert.ok(true, 'Action not supported, skipping');
return;
}
var clickTarget = findElement({id: 'clickTarget'});
goog.events.removeAll(clickTarget);
var targetHref = '#' + Math.random();
clickTarget.href = targetHref;
action(clickTarget);
var done = assert.async();
timeout().then(function() {
assert.strictEqual(window.location.hash, targetHref);
done();
});
}
QUnit.test('click executes default handler', function(assert) {
executesDefaultHandler(assert, bot.action.click);
});
QUnit.test('tap executes default handler', function(assert) {
executesDefaultHandler(assert, bot.action.tap);
});
function nestedElementExecutesDefaultHandler(assert, action) {
if (!checkActionCompatibility(action)) {
assert.ok(true, 'Action not supported, skipping');
return;
}
var parent = findElement({id: 'clickTargetWithAChild'});
var targetHref = '#' + Math.random();
parent.href = targetHref;
var clickTarget = goog.dom.getFirstElementChild(parent);
action(clickTarget);
var done = assert.async();
timeout().then(function() {
assert.strictEqual(window.location.hash, targetHref);
done();
});
}
QUnit.test('click nested element executes default handler', function(assert) {
nestedElementExecutesDefaultHandler(assert, bot.action.click);
});
QUnit.test('tap nested element executes default handler', function(assert) {
nestedElementExecutesDefaultHandler(assert, bot.action.tap);
});
function correctlyResolvesEmptyFragment(assert, action) {
if (!checkActionCompatibility(action)) {
assert.ok(true, 'Action not supported, skipping');
return;
}
var clickTarget = findElement({id: 'clickTarget'});
goog.events.removeAll(clickTarget);
clickTarget.href = '#';
action(clickTarget);
var done = assert.async();
timeout().then(function() {
var windowHref = window.location.href;
assert.strictEqual(windowHref.charAt(windowHref.length - 1), '#');
done();
});
}
QUnit.test('click correctly resolves empty fragment', function(assert) {
correctlyResolvesEmptyFragment(assert, bot.action.click);
});
QUnit.test('tap correctly resolves empty fragment', function(assert) {
correctlyResolvesEmptyFragment(assert, bot.action.tap);
});
function absoluteUrlInAnIframeExecutesDefaultHandler(assert, action) {
if (!checkActionCompatibility(action)) {
assert.ok(true, 'Action not supported, skipping');
return;
}
var done = assert.async();
waitForLoad(iframe).then(function() {
var domHelper = goog.dom.getDomHelper(iframeWindow);
var clickTarget = domHelper.getElement('iframeClickTarget');
var targetHref = goog.Uri.resolve(iframeWindow.location,
'#' + Math.random()).toString();
assert.ok(targetHref.indexOf('http') !== -1);
clickTarget.href = targetHref;
action(clickTarget);
timeout().then(function() {
assert.strictEqual(iframeWindow.location.href, targetHref);
done();
});
});
}
QUnit.test('click absolute url in an iframe executes default handler', function(assert) {
absoluteUrlInAnIframeExecutesDefaultHandler(assert, bot.action.click);
});
QUnit.test('tap absolute url in an iframe executes default handler', function(assert) {
absoluteUrlInAnIframeExecutesDefaultHandler(assert, bot.action.tap);
});
function absoluteServerPathAnchorInAnIframeExecutesDefaultHandler(assert, action) {
if (!checkActionCompatibility(action)) {
assert.ok(true, 'Action not supported, skipping');
return;
}
var done = assert.async();
waitForLoad(iframe).then(function() {
var domHelper = goog.dom.getDomHelper(iframeWindow);
var clickTarget = domHelper.getElement('iframeClickTarget');
var testPath = window.location.pathname;
var targetHref = testPath.substring(0, testPath.lastIndexOf('/')) +
'/testdata/click_iframe.html#' + Math.random();
clickTarget.href = targetHref;
action(clickTarget);
timeout().then(function() {
assert.ok(iframeWindow.location.href.indexOf(targetHref) !== -1);
done();
});
});
}
QUnit.test('click absolute server path anchor in an iframe executes default handler', function(assert) {
absoluteServerPathAnchorInAnIframeExecutesDefaultHandler(assert, bot.action.click);
});
QUnit.test('tap absolute server path anchor in an iframe executes default handler', function(assert) {
absoluteServerPathAnchorInAnIframeExecutesDefaultHandler(assert, bot.action.tap);
});
function relativeServerPathAnchorInAnIframeExecutesDefaultHandler(assert, action) {
if (!checkActionCompatibility(action)) {
assert.ok(true, 'Action not supported, skipping');
return;
}
var done = assert.async();
waitForLoad(iframe).then(function() {
var domHelper = goog.dom.getDomHelper(iframeWindow);
var clickTarget = domHelper.getElement('iframeClickTarget');
var targetHref = 'click_iframe.html#' + Math.random();
clickTarget.href = targetHref;
action(clickTarget);
timeout().then(function() {
assert.ok(iframeWindow.location.href.indexOf(targetHref) !== -1);
done();
});
});
}
QUnit.test('click relative server path anchor in an iframe executes default handler', function(assert) {
relativeServerPathAnchorInAnIframeExecutesDefaultHandler(assert, bot.action.click);
});
QUnit.test('tap relative server path anchor in an iframe executes default handler', function(assert) {
relativeServerPathAnchorInAnIframeExecutesDefaultHandler(assert, bot.action.tap);
});
function hashOnlyAnchorInAnIframeExecutesDefaultHandler(assert, action) {
if (!checkActionCompatibility(action)) {
assert.ok(true, 'Action not supported, skipping');
return;
}
var done = assert.async();
waitForLoad(iframe).then(function() {
var domHelper = goog.dom.getDomHelper(iframeWindow);
var clickTarget = domHelper.getElement('iframeClickTarget');
var targetHref = '#' + Math.random();
clickTarget.href = targetHref;
action(clickTarget);
timeout().then(function() {
assert.strictEqual(iframeWindow.location.hash, targetHref);
done();
});
});
}
QUnit.test('click hash only anchor in an iframe executes default handler', function(assert) {
hashOnlyAnchorInAnIframeExecutesDefaultHandler(assert, bot.action.click);
});
QUnit.test('tap hash only anchor in an iframe executes default handler', function(assert) {
hashOnlyAnchorInAnIframeExecutesDefaultHandler(assert, bot.action.tap);
});
function nestedElementInAnIframeExecutesDefaultHandler(assert, action) {
if (!checkActionCompatibility(action)) {
assert.ok(true, 'Action not supported, skipping');
return;
}
var done = assert.async();
waitForLoad(iframe).then(function() {
var domHelper = goog.dom.getDomHelper(iframeWindow);
var parent = domHelper.getElement('iframeClickTargetWithAChild');
var clickTarget = goog.dom.getFirstElementChild(parent);
var targetHref = '#' + Math.random();
parent.href = targetHref;
action(clickTarget);
timeout().then(function() {
assert.strictEqual(iframeWindow.location.hash, targetHref);
done();
});
});
}
QUnit.test('click nested element in an iframe executes default handler', function(assert) {
nestedElementInAnIframeExecutesDefaultHandler(assert, bot.action.click);
});
QUnit.test('tap hash nested element in an iframe executes default handler', function(assert) {
nestedElementInAnIframeExecutesDefaultHandler(assert, bot.action.tap);
});
function doesNotFollowLinkWhenEventDefaultPrevented(assert, action) {
if (!checkActionCompatibility(action)) {
assert.ok(true, 'Action not supported, skipping');
return;
}
var clickTarget = findElement({id: 'clickTarget'});
goog.events.removeAll(clickTarget);
var previousLocation = window.location.href;
clickTarget.href = '#' + Math.random();
goog.events.listen(clickTarget, goog.events.EventType.CLICK, function(e) {
e.preventDefault();
});
action(clickTarget);
var done = assert.async();
timeout().then(function() {
assert.strictEqual(window.location.href, previousLocation);
done();
});
}
QUnit.test('click does not follow link when event default prevented', function(assert) {
doesNotFollowLinkWhenEventDefaultPrevented(assert, bot.action.click);
});
QUnit.test('tap does not follow link when event default prevented', function(assert) {
doesNotFollowLinkWhenEventDefaultPrevented(assert, bot.action.tap);
});
function doNotFollowLinkWhenEventDefaultPreventedWithInlineHandler(assert, action) {
if (!checkActionCompatibility(action)) {
assert.ok(true, 'Action not supported, skipping');
return;
}
var clickTarget = findElement({id: 'clickTargetWithInlineHandler'});
var previousLocation = window.location.href;
clickTarget.href = '#' + Math.random();
action(clickTarget);
var done = assert.async();
timeout().then(function() {
assert.strictEqual(window.location.href, previousLocation);
done();
});
}
QUnit.test('click do not follow link when event default prevented with inline handler', function(assert) {
doNotFollowLinkWhenEventDefaultPreventedWithInlineHandler(assert, bot.action.click);
});
QUnit.test('tap do not follow link when event default prevented with inline handler', function(assert) {
doNotFollowLinkWhenEventDefaultPreventedWithInlineHandler(assert, bot.action.tap);
});
function doesNotFollowLinkWhenNoHrefIsGiven(assert, action) {
if (!checkActionCompatibility(action)) {
assert.ok(true, 'Action not supported, skipping');
return;
}
var clickTarget = findElement({id: 'clickTargetWithNoHref'});
goog.events.removeAll(clickTarget);
var previousLocation = window.location.href;
action(clickTarget);
var done = assert.async();
timeout().then(function() {
assert.strictEqual(window.location.href, previousLocation);
done();
});
}
QUnit.test('click does not follow link when no href is given', function(assert) {
doesNotFollowLinkWhenNoHrefIsGiven(assert, bot.action.click);
});
QUnit.test('tap does not follow link when no href is given', function(assert) {
doesNotFollowLinkWhenNoHrefIsGiven(assert, bot.action.tap);
});
function nestedElelementDoesNotFollowLinkWhenNoHrefIsGiven(assert, action) {
if (!checkActionCompatibility(action)) {
assert.ok(true, 'Action not supported, skipping');
return;
}
var clickTarget = findElement({id: 'clickTargetWithAChildAndNoHref'});
var previousLocation = window.location.href;
action(clickTarget);
assert.ok(window.location.href.indexOf(previousLocation) !== -1);
}
QUnit.test('click nested elelment does not follow link when no href is given', function(assert) {
nestedElelementDoesNotFollowLinkWhenNoHrefIsGiven(assert, bot.action.click);
});
QUnit.test('tap nested elelment does not follow link when no href is given', function(assert) {
nestedElelementDoesNotFollowLinkWhenNoHrefIsGiven(assert, bot.action.tap);
});
function doesNotEncodeReservedButAllowedCharactersInQuery(assert, action) {
if (!checkActionCompatibility(action)) {
assert.ok(true, 'Action not supported, skipping');
return;
}
var done = assert.async();
waitForLoad(iframe).then(function() {
var domHelper = goog.dom.getDomHelper(iframeWindow);
var clickTarget = domHelper.getElement('iframeClickTarget');
var targetHref = '?a=?/+';
clickTarget.href = targetHref;
action(clickTarget);
waitForLoad(iframe).then(function() {
assert.strictEqual(iframeWindow.location.search, targetHref);
done();
});
});
}
QUnit.test('click does not encode reserved but allowed characters in query', function(assert) {
doesNotEncodeReservedButAllowedCharactersInQuery(assert, bot.action.click);
});
QUnit.test('tap does not encode reserved but allowed characters in query', function(assert) {
doesNotEncodeReservedButAllowedCharactersInQuery(assert, bot.action.tap);
});
function absoluteAnchorInAnIframeExecutesDefaultHandler(assert, action) {
if (!checkActionCompatibility(action)) {
assert.ok(true, 'Action not supported, skipping');
return;
}
var done = assert.async();
waitForLoad(iframe).then(function() {
var clickTarget = getClickTarget('testdata/click_destination.html');
var targetHref = clickTarget.href;
action(clickTarget);
waitForLoad(iframe).then(function() {
assert.strictEqual(iframeWindow.location.href, targetHref);
done();
});
});
}
QUnit.test('click absolute anchor in an iframe executes default handler', function(assert) {
absoluteAnchorInAnIframeExecutesDefaultHandler(assert, bot.action.click);
});
QUnit.test('tap absolute anchor in an iframe executes default handler', function(assert) {
absoluteAnchorInAnIframeExecutesDefaultHandler(assert, bot.action.tap);
});
function linkThatCausesContentToLoadInAnotherFrame(assert, action) {
if (!checkActionCompatibility(action)) {
assert.ok(true, 'Action not supported, skipping');
return;
}
var done = assert.async();
waitForLoad(iframe).then(function() {
var clickTarget = getClickTarget('testdata/click_destination.html');
var targetHref = clickTarget.href;
clickTarget.target = 'other';
action(clickTarget);
waitForLoad(otherFrame).then(function() {
assert.strictEqual(otherFrameWindow.location.href, targetHref);
done();
});
});
}
QUnit.test('click link that causes content to load in another frame', function(assert) {
linkThatCausesContentToLoadInAnotherFrame(assert, bot.action.click);
});
QUnit.test('tap link that causes content to load in another frame', function(assert) {
linkThatCausesContentToLoadInAnotherFrame(assert, bot.action.tap);
});
function onSelfPageReloadsPage(assert, action) {
if (!checkActionCompatibility(action)) {
assert.ok(true, 'Action not supported, skipping');
return;
}
var done = assert.async();
waitForLoad(iframe).then(function() {
var clickTarget = getClickTarget(iframeWindow.location.href);
var targetHref = clickTarget.href;
action(clickTarget);
waitForLoad(iframe).then(function() {
assert.strictEqual(iframeWindow.location.href, targetHref);
done();
});
});
}
QUnit.test('click on self page reloads page', function(assert) {
onSelfPageReloadsPage(assert, bot.action.click);
});
QUnit.test('tap on self page reloads page', function(assert) {
onSelfPageReloadsPage(assert, bot.action.tap);
});
function actionOnHashDoesNotReloadThePage(assert, action) {
if (!checkActionCompatibility(action)) {
assert.ok(true, 'Action not supported, skipping');
return;
}
var done = assert.async();
waitForLoad(iframe).then(function() {
var clickTarget = getClickTarget('');
clickTarget.href = '#';
var id = goog.events.listenOnce(iframe, 'load', function() {
assert.ok(false, 'Did not expect iframe to load a new page');
done();
});
action(clickTarget);
window.setTimeout(function() {
goog.events.unlistenByKey(id);
assert.ok(true);
done();
}, 250);
});
}
QUnit.test('click on hash does not reload the page', function(assert) {
actionOnHashDoesNotReloadThePage(assert, bot.action.click);
});
QUnit.test('tap on hash does not reload the page', function(assert) {
onSelfPageReloadsPage(assert, bot.action.tap);
});
function focusOnAnElementBeforeFinishingClickSequence(assert, action) {
if (!checkActionCompatibility(action)) {
assert.ok(true, 'Action not supported, skipping');
return;
}
var done = assert.async();
goog.events.listenOnce(link, goog.events.EventType.FOCUS, function() {
assert.ok(true);
done();
});
action(link);
}
QUnit.test('click focus on an element before finishing click sequence', function(assert) {
focusOnAnElementBeforeFinishingClickSequence(assert, bot.action.click);
});
QUnit.test('tap focus on an element before finishing click sequence', function(assert) {
focusOnAnElementBeforeFinishingClickSequence(assert, bot.action.tap);
});
function focusOnAnElementWhenMousedownChangesFocus(assert, action) {
if (!checkActionCompatibility(action)) {
assert.ok(true, 'Action not supported, skipping');
return;
}
var mousedownPreemptsFocus = action == bot.action.tap ? false :
goog.userAgent.GECKO || goog.userAgent.IE;
goog.events.listen(link, goog.events.EventType.MOUSEDOWN, function() {
link2.focus();
});
var done = assert.async();
var resolved = false;
goog.events.listen(link, goog.events.EventType.FOCUS, function() {
if (resolved) return;
if (mousedownPreemptsFocus) {
assert.ok(false, 'Did not expect link to be focused');
resolved = true;
done();
} else {
assert.ok(true);
resolved = true;
done();
}
});
goog.events.listen(link2, goog.events.EventType.FOCUS, function() {
if (resolved) return;
if (mousedownPreemptsFocus) {
window.setTimeout(function() {
if (resolved) return;
assert.ok(true);
resolved = true;
done();
}, 100);
}
});
action(link);
}
QUnit.test('click focus on an element when mousedown changes focus', function(assert) {
focusOnAnElementWhenMousedownChangesFocus(assert, bot.action.click);
});
QUnit.test('tap focus on an element when mousedown changes focus', function(assert) {
focusOnAnElementWhenMousedownChangesFocus(assert, bot.action.tap);
});
</script>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<form action="javascript:void(0)">
<div id="log"></div>
<script>
divConsole = new goog.debug.DivConsole(goog.dom.$('log'));
divConsole.setCapturing(true);
</script>
</form>
<a id="clickTarget">Click me!</a>
<a id="clickTargetWithNoHref">Click me!</a>
<a id="clickTargetWithAChild">Click <strong>the nested</strong> element</a>
<a id="clickTargetWithAChildAndNoHref">Click <strong>the nested</strong> element with no href</a>
<a id="clickTargetWithInlineHandler" onclick="return false;">Click me, I will not follow the link!</a>
<div>
<div style="width:200px; height:100px;
border:1px solid black; padding:10px">Click Me</div>
</div>
<iframe id="iframe"></iframe>
<iframe id="other" name="other"></iframe>
<a id="link" href="javascript:void(0)">link</a>
<a id="link2" href="javascript:void(0)">link2</a>
</body>
</html>