Bug 759485: Add submit to HTMLElement on Marionette to submit forms without click() or send_keys(); r=mdas

This commit is contained in:
David Burns 2013-10-15 15:40:48 +01:00
parent a9f6a4ae00
commit f1fd1112ad
6 changed files with 206 additions and 17 deletions

View File

@ -160,6 +160,11 @@ class HTMLElement(object):
return self.marionette._send_message('getElementValueOfCssProperty', 'value',
id=self.id,
propertyName=property_name)
def submit(self):
'''
Submits if the element is a form or is within a form
'''
return self.marionette._send_message('submitElement', 'ok', id=self.id)
class Actions(object):
'''

View File

@ -0,0 +1,38 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import time
from marionette_test import MarionetteTestCase
from errors import NoSuchElementException
class TestSubmit(MarionetteTestCase):
def test_should_be_able_to_submit_forms(self):
test_html = self.marionette.absolute_url("formPage.html")
self.marionette.navigate(test_html)
self.marionette.find_element("name", "login").submit()
self.assertEqual(self.marionette.title, "We Arrive Here")
def test_should_submit_a_form_when_any_input_element_within_that_form_is_submitted(self):
test_html = self.marionette.absolute_url("formPage.html")
self.marionette.navigate(test_html)
self.marionette.find_element("id", "checky").submit()
for i in range(5):
try:
self.marionette.find_element('id', 'email')
except NoSuchElementException:
time.sleep(1)
self.assertEqual(self.marionette.title, "We Arrive Here")
def test_should_submit_a_form_when_any_element_wihin_that_form_is_submitted(self):
test_html = self.marionette.absolute_url("formPage.html")
self.marionette.navigate(test_html)
self.marionette.find_element("xpath", "//form/p").submit()
for i in range(5):
try:
self.marionette.find_element('id', 'email')
except NoSuchElementException:
time.sleep(1)
self.assertEqual(self.marionette.title, "We Arrive Here")

View File

@ -93,3 +93,4 @@ b2g = false
[test_implicit_waits.py]
[test_date_time_value.py]
[test_getactiveframe_oop.py]
[test_submit.py]

View File

@ -1,16 +1,116 @@
<html>
<head>
<title>We Leave From Here</title>
<script type="text/javascript">
function changePage() {
var newLocation = '/common/page/3';
window.location = newLocation;
}
</script>
</head>
<body>
<input type='button' id='killIframe' onclick='top.remove();' value="Kill containing iframe" />
</body>
</html>
<html>
<head>
<title>We Leave From Here</title>
<script type="text/javascript">
function changePage() {
var newLocation = '/common/page/3';
window.location = newLocation;
}
</script>
</head>
<body>
There should be a form here:
<form method="get" action="resultPage.html" name="login">
<input type="email" id="email"/>
<input type="submit" id="submitButton" value="Hello there"/>
</form>
<form method="get" action="resultPage.html" name="optional" style="display: block">
Here's a checkbox:
<input type="checkbox" id="checky" name="checky" value="furrfu"/>
<input type="checkbox" id="checkedchecky" name="checkedchecky" checked="checked" />
<input type="checkbox" id="disabledchecky" disabled="disabled" name="disabledchecky" />
<input type="checkbox" id="randomly_disabled_checky" disabled="somerandomstring" checked="checked" name="randomlydisabledchecky" />
<br/>
<select name="selectomatic">
<option selected="selected" id="non_multi_option" value="one">One</option>
<option value="two">Two</option>
<option value="four">Four</option>
<option value="still learning how to count, apparently">Still learning how to count, apparently</option>
</select>
<select name="multi" id="multi" multiple="multiple">
<option selected="selected" value="eggs">Eggs</option>
<option value="ham">Ham</option>
<option selected="selected" value="sausages">Sausages</option>
<option value="onion gravy">Onion gravy</option>
</select>
<select name="no-select" disabled="disabled">
<option value="foo">Foo</option>
</select>
<select name="select_empty_multiple" multiple>
<option id="multi_1" value="select_1">select_1</option>
<option id="multi_2" value="select_2">select_2</option>
<option id="multi_3" value="select_3">select_3</option>
<option id="multi_4" value="select_4">select_4</option>
</select>
<select name="multi_true" multiple="true">
<option id="multi_true_1" value="select_1">select_1</option>
<option id="multi_true_2" value="select_2">select_2</option>
</select>
<select name="multi_false" multiple="false">
<option id="multi_false_1" value="select_1">select_1</option>
<option id="multi_false_2" value="select_2">select_2</option>
</select>
<select id="invisi_select" style="opacity:0;">
<option selected value="apples">Apples</option>
<option value="oranges">Oranges</option>
</select>
<select name="select-default">
<option>One</option>
<option>Two</option>
<option>Four</option>
<option>Still learning how to count, apparently</option>
</select>
<select name="select_with_spaces">
<option>One</option>
<option> Two </option>
<option>
Four
</option>
<option>
Still learning how to count,
apparently
</option>
</select>
<select>
<option id="blankOption"></option>
<option id="optionEmptyValueSet" value="">nothing</option>
</select>
<br/>
<input type="radio" id="cheese" name="snack" value="cheese"/>Cheese<br/>
<input type="radio" id="peas" name="snack" value="peas"/>Peas<br/>
<input type="radio" id="cheese_and_peas" name="snack" value="cheese and peas" checked/>Cheese and peas<br/>
<input type="radio" id="nothing" name="snack" value="nowt" disabled="disabled"/>Not a sausage<br/>
<input type="radio" id="randomly_disabled_nothing" name="snack" value="funny nowt" disabled="somedisablingstring"/>Not another sausage
<input type="hidden" name="hidden" value="fromage" />
<p id="cheeseLiker">I like cheese</p>
<input type="submit" value="Click!"/>
<input type="radio" id="lone_disabled_selected_radio" name="not_a_snack" value="cumberland" checked="checked" disabled="disabled" />Cumberland sausage
</form>
<input type='button' id='killIframe' onclick='top.remove();' value="Kill containing iframe" />
<form method="get" action="formPage.html">
<p>
<label for="checkbox-with-label" id="label-for-checkbox-with-label">Label</label><input type="checkbox" id="checkbox-with-label" />
</p>
</form>
<input id="vsearchGadget" name="SearchableText" type="text" size="18" value="" title="Hvad søger du?" accesskey="4" class="inputLabel" />
</body>
</html>

View File

@ -141,7 +141,8 @@ function startListeners() {
addMessageListenerId("Marionette:getElementText", getElementText);
addMessageListenerId("Marionette:getElementTagName", getElementTagName);
addMessageListenerId("Marionette:isElementDisplayed", isElementDisplayed);
addMessageListenerId("Marionette:getElementValueOfCssProperty", getElementValueOfCssProperty)
addMessageListenerId("Marionette:getElementValueOfCssProperty", getElementValueOfCssProperty);
addMessageListenerId("Marionette:submitElement", submitElement);
addMessageListenerId("Marionette:getElementSize", getElementSize);
addMessageListenerId("Marionette:isElementEnabled", isElementEnabled);
addMessageListenerId("Marionette:isElementSelected", isElementSelected);
@ -217,6 +218,7 @@ function deleteSession(msg) {
removeMessageListenerId("Marionette:getElementTagName", getElementTagName);
removeMessageListenerId("Marionette:isElementDisplayed", isElementDisplayed);
removeMessageListenerId("Marionette:getElementValueOfCssProperty", getElementValueOfCssProperty);
removeMessageListenerId("Marionette:submitElement", submitElement);
removeMessageListenerId("Marionette:getElementSize", getElementSize);
removeMessageListenerId("Marionette:isElementEnabled", isElementEnabled);
removeMessageListenerId("Marionette:isElementSelected", isElementSelected);
@ -1408,6 +1410,32 @@ function getElementValueOfCssProperty(msg){
}
}
/**
* Submit a form on a content page by either using form or element in a form
* @param object msg
* 'json' JSON object containing 'id' member of the element
*/
function submitElement (msg) {
let command_id = msg.json.command_id;
try {
let el = elementManager.getKnownElement(msg.json.id, curFrame);
while (el.parentNode != null && el.tagName.toLowerCase() != 'form') {
el = el.parentNode;
}
if (el.tagName && el.tagName.toLowerCase() == 'form') {
el.submit();
sendOk(command_id);
}
else {
sendError("Element is not a form element or in a form", 7, null, command_id);
}
}
catch (e) {
sendError(e.message, e.code, e.stack, command_id);
}
}
/**
* Get the size of the element and return it
*/

View File

@ -1696,6 +1696,22 @@ MarionetteServerConnection.prototype = {
command_id);
},
/**
* Submit a form on a content page by either using form or element in a form
* @param object aRequest
* 'id' member holds the reference id to
* the element that will be checked
*/
submitElement: function MDA_submitElement(aRequest) {
let command_id = this.command_id = this.getCommandId();
if (this.context == "chrome") {
this.sendError("Command 'submitElement' is not available in chrome context", 500, null, this.command_id);
}
else {
this.sendAsync("submitElement", {id: aRequest.parameters.id}, command_id);
}
},
/**
* Check if element is enabled
*
@ -2237,6 +2253,7 @@ MarionetteServerConnection.prototype.requestTypes = {
"getElementTagName": MarionetteServerConnection.prototype.getElementTagName,
"isElementDisplayed": MarionetteServerConnection.prototype.isElementDisplayed,
"getElementValueOfCssProperty": MarionetteServerConnection.prototype.getElementValueOfCssProperty,
"submitElement": MarionetteServerConnection.prototype.submitElement,
"getElementSize": MarionetteServerConnection.prototype.getElementSize,
"isElementEnabled": MarionetteServerConnection.prototype.isElementEnabled,
"isElementSelected": MarionetteServerConnection.prototype.isElementSelected,