Skip to content

Commit

Permalink
[py] update implementation for submitting forms
Browse files Browse the repository at this point in the history
  • Loading branch information
titusfortner committed May 25, 2022
1 parent 7c77d06 commit 6ff3693
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 45 deletions.
99 changes: 60 additions & 39 deletions py/selenium/webdriver/remote/webelement.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,12 @@
from io import BytesIO
from typing import Union

from selenium.common.exceptions import WebDriverException
from selenium.common.exceptions import WebDriverException, JavascriptException
from selenium.webdriver.common.by import By
from selenium.webdriver.common.utils import keys_to_typing
from .command import Command
from .shadowroot import ShadowRoot


# TODO: When moving to supporting python 3.9 as the minimum version we can
# use built in importlib_resources.files.
getAttribute_js = None
Expand Down Expand Up @@ -91,11 +90,20 @@ def click(self) -> None:

def submit(self):
"""Submits a form."""
form = self.find_element(By.XPATH, "./ancestor-or-self::form")
self._parent.execute_script(
"var e = arguments[0].ownerDocument.createEvent('Event');"
"e.initEvent('submit', true, true);"
"if (arguments[0].dispatchEvent(e)) { arguments[0].submit() }", form)
script = "var form = arguments[0];\n" \
"while (form.nodeName != \"FORM\" && form.parentNode) {\n" \
" form = form.parentNode;\n" \
"}\n" \
"if (!form) { throw Error('Unable to find containing form element'); }\n" \
"if (!form.ownerDocument) { throw Error('Unable to find owning document'); }\n" \
"var e = form.ownerDocument.createEvent('Event');\n" \
"e.initEvent('submit', true, true);\n" \
"if (form.dispatchEvent(e)) { HTMLFormElement.prototype.submit.call(form) }\n"

try:
self._parent.execute_script(script, self)
except JavascriptException:
raise WebDriverException("To submit an element, it must be nested inside a form element")

def clear(self) -> None:
"""Clears the text if it's a text entry element."""
Expand Down Expand Up @@ -280,9 +288,10 @@ def find_element_by_link_text(self, link_text):
element = element.find_element_by_link_text('Sign In')
"""
warnings.warn("find_element_by_link_text is deprecated. Please use find_element(by=By.LINK_TEXT, value=link_text) instead",
DeprecationWarning,
stacklevel=2)
warnings.warn(
"find_element_by_link_text is deprecated. Please use find_element(by=By.LINK_TEXT, value=link_text) instead",
DeprecationWarning,
stacklevel=2)
return self.find_element(by=By.LINK_TEXT, value=link_text)

def find_elements_by_link_text(self, link_text):
Expand All @@ -300,9 +309,10 @@ def find_elements_by_link_text(self, link_text):
elements = element.find_elements_by_link_text('Sign In')
"""
warnings.warn("find_elements_by_link_text is deprecated. Please use find_elements(by=By.LINK_TEXT, value=text) instead",
DeprecationWarning,
stacklevel=2)
warnings.warn(
"find_elements_by_link_text is deprecated. Please use find_elements(by=By.LINK_TEXT, value=text) instead",
DeprecationWarning,
stacklevel=2)
return self.find_elements(by=By.LINK_TEXT, value=link_text)

def find_element_by_partial_link_text(self, link_text):
Expand All @@ -322,9 +332,10 @@ def find_element_by_partial_link_text(self, link_text):
element = element.find_element_by_partial_link_text('Sign')
"""
warnings.warn("find_element_by_partial_link_text is deprecated. Please use find_element(by=By.PARTIAL_LINK_TEXT, value=link_text) instead",
DeprecationWarning,
stacklevel=2)
warnings.warn(
"find_element_by_partial_link_text is deprecated. Please use find_element(by=By.PARTIAL_LINK_TEXT, value=link_text) instead",
DeprecationWarning,
stacklevel=2)
return self.find_element(by=By.PARTIAL_LINK_TEXT, value=link_text)

def find_elements_by_partial_link_text(self, link_text):
Expand All @@ -342,9 +353,10 @@ def find_elements_by_partial_link_text(self, link_text):
elements = element.find_elements_by_partial_link_text('Sign')
"""
warnings.warn("find_elements_by_partial_link_text is deprecated. Please use find_elements(by=By.PARTIAL_LINK_TEXT, value=link_text) instead",
DeprecationWarning,
stacklevel=2)
warnings.warn(
"find_elements_by_partial_link_text is deprecated. Please use find_elements(by=By.PARTIAL_LINK_TEXT, value=link_text) instead",
DeprecationWarning,
stacklevel=2)
return self.find_elements(by=By.PARTIAL_LINK_TEXT, value=link_text)

def find_element_by_tag_name(self, name):
Expand All @@ -364,9 +376,10 @@ def find_element_by_tag_name(self, name):
element = element.find_element_by_tag_name('h1')
"""
warnings.warn("find_element_by_tag_name is deprecated. Please use find_element(by=By.TAG_NAME, value=name) instead",
DeprecationWarning,
stacklevel=2)
warnings.warn(
"find_element_by_tag_name is deprecated. Please use find_element(by=By.TAG_NAME, value=name) instead",
DeprecationWarning,
stacklevel=2)
return self.find_element(by=By.TAG_NAME, value=name)

def find_elements_by_tag_name(self, name):
Expand All @@ -384,9 +397,10 @@ def find_elements_by_tag_name(self, name):
elements = element.find_elements_by_tag_name('h1')
"""
warnings.warn("find_elements_by_tag_name is deprecated. Please use find_elements(by=By.TAG_NAME, value=name) instead",
DeprecationWarning,
stacklevel=2)
warnings.warn(
"find_elements_by_tag_name is deprecated. Please use find_elements(by=By.TAG_NAME, value=name) instead",
DeprecationWarning,
stacklevel=2)
return self.find_elements(by=By.TAG_NAME, value=name)

def find_element_by_xpath(self, xpath):
Expand Down Expand Up @@ -455,9 +469,10 @@ def find_elements_by_xpath(self, xpath):
elements = element.find_elements_by_xpath("//div[contains(@class, 'foo')]")
"""
warnings.warn("find_elements_by_xpath is deprecated. Please use find_elements(by=By.XPATH, value=xpath) instead",
DeprecationWarning,
stacklevel=2)
warnings.warn(
"find_elements_by_xpath is deprecated. Please use find_elements(by=By.XPATH, value=xpath) instead",
DeprecationWarning,
stacklevel=2)
return self.find_elements(by=By.XPATH, value=xpath)

def find_element_by_class_name(self, name):
Expand All @@ -477,9 +492,10 @@ def find_element_by_class_name(self, name):
element = element.find_element_by_class_name('foo')
"""
warnings.warn("find_element_by_class_name is deprecated. Please use find_element(by=By.CLASS_NAME, value=name) instead",
DeprecationWarning,
stacklevel=2)
warnings.warn(
"find_element_by_class_name is deprecated. Please use find_element(by=By.CLASS_NAME, value=name) instead",
DeprecationWarning,
stacklevel=2)
return self.find_element(by=By.CLASS_NAME, value=name)

def find_elements_by_class_name(self, name):
Expand All @@ -497,7 +513,9 @@ def find_elements_by_class_name(self, name):
elements = element.find_elements_by_class_name('foo')
"""
warnings.warn("find_elements_by_class_name is deprecated. Please use find_elements(by=By.CLASS_NAME, value=name) instead", DeprecationWarning)
warnings.warn(
"find_elements_by_class_name is deprecated. Please use find_elements(by=By.CLASS_NAME, value=name) instead",
DeprecationWarning)
return self.find_elements(by=By.CLASS_NAME, value=name)

def find_element_by_css_selector(self, css_selector):
Expand All @@ -517,9 +535,10 @@ def find_element_by_css_selector(self, css_selector):
element = element.find_element_by_css_selector('#foo')
"""
warnings.warn("find_element_by_css_selector is deprecated. Please use find_element(by=By.CSS_SELECTOR, value=css_selector) instead",
DeprecationWarning,
stacklevel=2)
warnings.warn(
"find_element_by_css_selector is deprecated. Please use find_element(by=By.CSS_SELECTOR, value=css_selector) instead",
DeprecationWarning,
stacklevel=2)
return self.find_element(by=By.CSS_SELECTOR, value=css_selector)

def find_elements_by_css_selector(self, css_selector):
Expand All @@ -537,9 +556,10 @@ def find_elements_by_css_selector(self, css_selector):
elements = element.find_elements_by_css_selector('.foo')
"""
warnings.warn("find_elements_by_css_selector is deprecated. Please use find_elements(by=By.CSS_SELECTOR, value=css_selector) instead",
DeprecationWarning,
stacklevel=2)
warnings.warn(
"find_elements_by_css_selector is deprecated. Please use find_elements(by=By.CSS_SELECTOR, value=css_selector) instead",
DeprecationWarning,
stacklevel=2)
return self.find_elements(by=By.CSS_SELECTOR, value=css_selector)

def send_keys(self, *value) -> None:
Expand Down Expand Up @@ -593,7 +613,8 @@ def shadow_root(self) -> ShadowRoot:
- NoSuchShadowRoot - if no shadow root was attached to element
"""
browser_main_version = int(self._parent.caps["browserVersion"].split(".")[0])
assert self._parent.caps["browserName"].lower() not in ["firefox", "safari"], "This only currently works in Chromium based browsers"
assert self._parent.caps["browserName"].lower() not in ["firefox",
"safari"], "This only currently works in Chromium based browsers"
assert not browser_main_version <= 95, f"Please use Chromium based browsers with version 96 or later. Version used {self._parent.caps['browserVersion']}"
return self._execute(Command.GET_SHADOW_ROOT)['value']

Expand Down
24 changes: 18 additions & 6 deletions py/test/selenium/webdriver/common/form_handling_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,28 +41,40 @@ def test_should_be_able_to_click_image_buttons(driver, pages):
WebDriverWait(driver, 3).until(EC.title_is("We Arrive Here"))


def test_should_be_able_to_submit_forms(driver, pages):
def test_should_submit_input_in_form(driver, pages):
pages.load("formPage.html")
driver.find_element(By.NAME, "login").submit()
WebDriverWait(driver, 3).until(EC.title_is("We Arrive Here"))


def test_should_submit_aform_when_any_input_element_within_that_form_is_submitted(driver, pages):
def test_should_submit_any_input_element_within_form(driver, pages):
pages.load("formPage.html")
driver.find_element(By.ID, "checky").submit()
WebDriverWait(driver, 3).until(EC.title_is("We Arrive Here"))


def test_should_submit_aform_when_any_element_within_that_form_is_submitted(driver, pages):
def test_should_submit_any_element_within_form(driver, pages):
pages.load("formPage.html")
driver.find_element(By.XPATH, "//form/p").submit()
WebDriverWait(driver, 5).until(EC.title_is("We Arrive Here"))


def test_should_not_be_able_to_submit_aform_that_does_not_exist(driver, pages):
def test_should_submit_element_with_id_submit(driver, pages):
pages.load("formPage.html")
with pytest.raises(NoSuchElementException):
driver.find_element(By.NAME, "there is no spoon").submit()
driver.find_element(By.ID, "submit").submit()
WebDriverWait(driver, 5).until(EC.title_is("We Arrive Here"))


def test_should_submit_element_with_name_submit(driver, pages):
pages.load("formPage.html")
driver.find_element(By.NAME, "submit").submit()
WebDriverWait(driver, 5).until(EC.title_is("We Arrive Here"))


def test_should_not_submit_button_outside_form(driver, pages):
pages.load("formPage.html")
with pytest.raises(WebDriverException):
driver.find_element(By.NAME, "SearchableText").submit()


def test_should_be_able_to_enter_text_into_atext_area_by_setting_its_value(driver, pages):
Expand Down

0 comments on commit 6ff3693

Please sign in to comment.