| <!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> |