| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <title>action_test.html</title> | |
| <script src="test_bootstrap.js"></script> | |
| <script type="text/javascript"> | |
| goog.require('bot.action'); | |
| goog.require('bot.locators'); | |
| goog.require('goog.Promise'); | |
| goog.require('goog.Uri'); | |
| goog.require('goog.dom'); | |
| goog.require('goog.dom.forms'); | |
| goog.require('goog.events'); | |
| goog.require('goog.events.EventType'); | |
| goog.require('goog.testing.jsunit'); | |
| </script> | |
| <script type="text/javascript"> | |
| var submitted = goog.nullFunction; | |
| var counts; | |
| var listeningTo; | |
| function setUp() { | |
| counts = {}; | |
| listeningTo = []; | |
| } | |
| function tearDown() { | |
| while (listeningTo.length) { | |
| goog.events.removeAll(listeningTo.shift()); | |
| } | |
| submitted = goog.nullFunction; | |
| } | |
| function expectAndCancelEvent(eventType, expectedTarget) { | |
| counts[eventType] = 0; | |
| listeningTo.push(expectedTarget); | |
| goog.events.listen(expectedTarget, eventType, | |
| function(e) { | |
| assertEquals('Not the expected ' + eventType + ' event target', | |
| expectedTarget, e.target); | |
| e.stopPropagation(); | |
| e.preventDefault(); | |
| counts[eventType] += 1; | |
| }); | |
| } | |
| function expectEvent(eventType, expectedTarget) { | |
| counts[eventType] = 0; | |
| listeningTo.push(expectedTarget); | |
| goog.events.listen(expectedTarget, eventType, | |
| function(e) { | |
| assertEquals('Not the expected ' + eventType + ' event target', | |
| expectedTarget, e.target); | |
| counts[eventType] += 1; | |
| }); | |
| } | |
| var expectBlurEvent = goog.partial(expectEvent, | |
| goog.events.EventType.BLUR); | |
| var expectChangeEvent = goog.partial(expectEvent, | |
| goog.events.EventType.CHANGE); | |
| var expectSubmitEvent = goog.partial(expectEvent, | |
| goog.events.EventType.SUBMIT); | |
| function assertEventFired(eventType, opt_count) { | |
| var count = opt_count || 1; | |
| assertEquals(eventType + ' event not fired expected # of times!', | |
| count, counts[eventType]); | |
| } | |
| var assertBlurFired = goog.partial(assertEventFired, | |
| goog.events.EventType.BLUR); | |
| var assertChangeFired = goog.partial(assertEventFired, | |
| goog.events.EventType.CHANGE); | |
| var assertSubmitFired = goog.partial(assertEventFired, | |
| goog.events.EventType.SUBMIT); | |
| function doNotExpectEvent(eventType, expectedTarget) { | |
| listeningTo.push(expectedTarget); | |
| goog.events.listen(expectedTarget, eventType, goog.partial(fail, | |
| 'Was not expecting a ' + eventType + ' event to be fired')); | |
| } | |
| var doNotExpectChangeEvent = goog.partial(doNotExpectEvent, | |
| goog.events.EventType.CHANGE); | |
| var doNotExpectSubmitEvent = goog.partial(doNotExpectEvent, | |
| goog.events.EventType.SUBMIT); | |
| function testClearingANonTextualElementThrows() { | |
| assertThrows(goog.partial(bot.action.clear, document.body)); | |
| } | |
| function forEachClearableElement(fn) { | |
| var ids = ['textField', 'textArea', 'passwordField']; | |
| for (var i = 0; i < ids.length; i++) { | |
| fn(goog.dom.$(ids[i])); | |
| } | |
| } | |
| function testClearingAnEmptyElementShouldNoOp() { | |
| forEachClearableElement(function(e) { | |
| e.value = ''; | |
| e.disabled = false; | |
| e.readOnly = false; | |
| doNotExpectChangeEvent(e); | |
| bot.action.clear(e); | |
| assertEquals('', e.value); | |
| }); | |
| } | |
| function testClearingANonEmptyElement() { | |
| forEachClearableElement(function(e) { | |
| e.value = 'foobar'; | |
| e.disabled = false; | |
| e.readOnly = false; | |
| expectBlurEvent(e); | |
| expectChangeEvent(e); | |
| bot.action.clear(e); | |
| if (goog.userAgent.IE) { | |
| assertBlurFired(); | |
| } | |
| assertChangeFired(); | |
| assertEquals('', e.value); | |
| }); | |
| } | |
| function testClearingADisabledElementThrows() { | |
| forEachClearableElement(function(e) { | |
| e.value = 'foobar'; | |
| e.disabled = true; | |
| e.readOnly = false; | |
| doNotExpectChangeEvent(e); | |
| assertThrows(goog.partial(bot.action.clear, e)); | |
| assertEquals('foobar', e.value); | |
| // Even when element is initially empty. | |
| e.value = ''; | |
| doNotExpectChangeEvent(e); | |
| assertThrows(goog.partial(bot.action.clear, e)); | |
| }); | |
| } | |
| function testClearingAReadOnlyElementThrows() { | |
| forEachClearableElement(function(e) { | |
| e.value = 'foobar'; | |
| e.disabled = false; | |
| e.readOnly = true; | |
| doNotExpectChangeEvent(e); | |
| assertThrows(goog.partial(bot.action.clear, e)); | |
| assertEquals('foobar', e.value); | |
| // Even when element is initially empty. | |
| e.value = ''; | |
| doNotExpectChangeEvent(e); | |
| assertThrows(goog.partial(bot.action.clear, e)); | |
| }); | |
| } | |
| function testClearingAContentEditableArea() { | |
| var e = goog.dom.getElement('content-editable'); | |
| bot.action.clear(e); | |
| assertEquals('', bot.dom.getVisibleText(e)); | |
| } | |
| function testClearingAChildContentEditableArea() { | |
| var e = goog.dom.getElement('child-content-editable'); | |
| bot.action.clear(e); | |
| assertEquals('', bot.dom.getVisibleText(e)); | |
| } | |
| function testClearingANotContentEditableArea() { | |
| var e = goog.dom.getElement('not-content-editable'); | |
| assertThrows(goog.partial(bot.action.clear, e)); | |
| } | |
| function testClearingAChildNotContentEditableArea() { | |
| var e = goog.dom.getElement('child-not-content-editable'); | |
| assertThrows(goog.partial(bot.action.clear, e)); | |
| } | |
| function testClearingAFileInputShouldBeNoOp() { | |
| var e = goog.dom.getElement('fileField'); | |
| doNotExpectChangeEvent(e); | |
| bot.action.clear(e); | |
| assertEquals('', e.value); | |
| } | |
| function testClearingNumberInputWithInvalidData() { | |
| var e = goog.dom.getElement('numberField'); | |
| bot.action.type(e, "e"); | |
| bot.action.clear(e); | |
| bot.action.type(e, "3"); | |
| assertEquals("3", goog.dom.forms.getValue(e)); | |
| } | |
| function testClearingAIframeContentEditableArea() { | |
| var iframe = goog.dom.getElement('iframe'); | |
| var iframeDoc = goog.dom.getFrameContentDocument(iframe); | |
| var e = bot.locators.findElement({ id: 'content-editable' }, iframeDoc); | |
| bot.action.clear(e); | |
| assertEquals('', bot.dom.getVisibleText(e)); | |
| } | |
| function testSubmittingANonFormElementShouldResultInAnError() { | |
| assertThrows(goog.partial(bot.action.submit, document.body)); | |
| } | |
| function testShouldNotSubmitIfSubmitEventIsCancelled() { | |
| var form = goog.dom.$('form_one'); | |
| expectAndCancelEvent(goog.events.EventType.SUBMIT, form); | |
| var wasSubmitted = false; | |
| goog.global.submitted = function() { | |
| wasSubmitted = true; | |
| }; | |
| bot.action.submit(form); | |
| assertSubmitFired(); | |
| assertFalse(wasSubmitted); | |
| } | |
| function testShouldSubmitIfSubmitEventIsNotCancelled() { | |
| var form = goog.dom.$('form_one'); | |
| expectSubmitEvent(form); | |
| // Firefox executes submit() in the next event loop, so we must go async. | |
| return new goog.Promise(function(done) { | |
| goog.global.submitted = done; | |
| bot.action.submit(form); | |
| assertSubmitFired(); | |
| }); | |
| } | |
| function testShouldBeAbleToSubmitFromAnyElementThatIsAChildOfTheForm() { | |
| var form = goog.dom.$('form_one'); | |
| expectSubmitEvent(form); | |
| // Firefox executes submit() in the next event loop, so we must go async. | |
| return new goog.Promise(function(done) { | |
| goog.global.submitted = done; | |
| bot.action.submit(goog.dom.$('typer')); | |
| assertSubmitFired(); | |
| }); | |
| } | |
| function testShouldBeAbleToSubmitFromAFormWithAnElementNamedSubmit() { | |
| var form = goog.dom.getElement('form_two'); | |
| var submitButton = goog.dom.getElement('submit'); | |
| expectSubmitEvent(form); | |
| // Firefox executes submit() in the next event loop, so we must go async. | |
| return new goog.Promise(function(done) { | |
| goog.global.submitted = done; | |
| bot.action.submit(goog.dom.getElement('typer2')); | |
| assertSubmitFired(); | |
| // Make sure the submit button is returned to normal. | |
| assertEquals(submitButton.id, 'submit'); | |
| assertEquals(submitButton.name, 'submit'); | |
| }); | |
| } | |
| </script> | |
| </head> | |
| <body> | |
| <form id="form_one" action="javascript:submitted()"> | |
| <label for="typer">Type here: </label><input type="text" id="typer"/> | |
| <input type="submit" id="submit-button" value="Submit!"/> | |
| </form> | |
| <form id="form_two" action="javascript:submitted()"> | |
| <label for="typer2">Type here: </label><input type="text" id="typer2"/> | |
| <input type="submit" id="submit" name="submit" value="Submit!"/> | |
| </form> | |
| <form action="javascript:void(0)"> | |
| <div> | |
| <label for="textField">Text field</label> | |
| <input type="text" id="textField"/> | |
| </div> | |
| <div> | |
| <label for="textArea">Text area</label> | |
| <textarea id="textArea"></textarea> | |
| </div> | |
| <label for="passwordField">Password field</label> | |
| <input type="password" id="passwordField"> | |
| </div> | |
| </div> | |
| <label for="fileField">File field</label> | |
| <input type="file" id="fileField"> | |
| </div> | |
| <div> | |
| <label for="numberField">Number field</label> | |
| <input type="number" id="numberField"> | |
| </div> | |
| </form> | |
| <div id="log"> | |
| </div> | |
| <div id="content-editable" contentEditable="true">This is a contentEditable area | |
| <div id="child-content-editable">child content editable | |
| </div> | |
| </div> | |
| <div id="not-content-editable" contentEditable="false">This is not a contentEditable area | |
| <div id="child-not-content-editable">child not content editable | |
| </div> | |
| </div> | |
| <iframe id="iframe" src="testdata/trusted_types_iframe.html"> | |
| </iframe> | |
| </body> | |
| </html> |