Skip to content

Commit 4ba475b

Browse files
authored
Merge pull request #1850 from emanlove/new-attribute-property-keywords-1822
New attribute property keywords 1822
2 parents fe01706 + 085fc64 commit 4ba475b

File tree

3 files changed

+120
-1
lines changed

3 files changed

+120
-1
lines changed

atest/acceptance/keywords/elements.robot

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ Documentation Tests elements
33
Test Setup Go To Page "links.html"
44
Resource ../resource.robot
55
Library String
6+
Library DebugLibrary
67

78
*** Test Cases ***
89
Get Many Elements
@@ -60,6 +61,92 @@ Get Element Attribute
6061
${class}= Get Element Attribute ${second_div} class
6162
Should Be Equal ${class} Second Class
6263

64+
# About DOM Attributes and Properties
65+
# -----------------------------------
66+
# When implementing the new `Get DOM Attirbute` and `Get Property` keywords (#1822), several
67+
# questions were raised. Fundamentally what is the difference between a DOM attribute and
68+
# a Property. As [1] explains "Attributes are defined by HTML. Properties are defined by the
69+
# DOM (Document Object Model)."
70+
#
71+
# Below are some references which talk to some descriptions and oddities of DOM attributes
72+
# and properties.
73+
#
74+
# References:
75+
# [1] HTML attributes and DOM properties:
76+
# https://angular.io/guide/binding-syntax#html-attribute-vs-dom-property
77+
# [2] W3C HTML Specification - Section 13.1.2.3 Attributes:
78+
# https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
79+
# [3] JavaScript.Info - Attributes and properties:
80+
# https://javascript.info/dom-attributes-and-properties
81+
# [4] "Which CSS properties are inherited?" - StackOverflow
82+
# https://stackoverflow.com/questions/5612302/which-css-properties-are-inherited
83+
# [5] MDN Web Docs: Attribute
84+
# https://developer.mozilla.org/en-US/docs/Glossary/Attribute
85+
# [6] MDN Web Docs: HTML attribute reference
86+
# https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
87+
88+
Get DOM Attribute
89+
# Test get DOM attribute
90+
${id}= Get DOM Attribute link:Link with id id
91+
Should Be Equal ${id} some_id
92+
# Test custom attribute
93+
${existing_custom_attr}= Get DOM Attribute id:emptyDiv data-id
94+
Should Be Equal ${existing_custom_attr} my_id
95+
${doesnotexist_custom_attr}= Get DOM Attribute id:emptyDiv data-doesnotexist
96+
Should Be Equal ${doesnotexist_custom_attr} ${None}
97+
# Get non existing DOM Attribute
98+
${class}= Get DOM Attribute link:Link with id class
99+
Should Be Equal ${class} ${NONE}
100+
101+
More DOM Attributes
102+
[Setup] Go To Page "forms/enabled_disabled_fields_form.html"
103+
# Test get empty boolean attribute
104+
${disabled}= Get DOM Attribute css:input[name="disabled_input"] disabled
105+
Should Be Equal ${disabled} true
106+
# Test boolean attribute whose value is a string
107+
${disabled}= Get DOM Attribute css:input[name="disabled_password"] disabled
108+
Should Be Equal ${disabled} true
109+
# Test empty string as the value for the attribute
110+
${empty_value}= Get DOM Attribute css:input[name="disabled_password"] value
111+
Should Be Equal ${empty_value} ${EMPTY}
112+
# Test non-existing attribute
113+
${disabled}= Get DOM Attribute css:input[name="enabled_password"] disabled
114+
Should Be Equal ${disabled} ${NONE}
115+
116+
Get Property
117+
[Setup] Go To Page "forms/enabled_disabled_fields_form.html"
118+
${tagName_prop}= Get Property css:input[name="readonly_empty"] tagName
119+
Should Be Equal ${tagName_prop} INPUT
120+
# Get a boolean property
121+
${isConnected}= Get Property css:input[name="readonly_empty"] isConnected
122+
Should Be Equal ${isConnected} ${True}
123+
# Test property which returns webelement
124+
${children_prop}= Get Property id:table1 children
125+
Length Should Be ${children_prop} ${1}
126+
${isWebElement}= Evaluate isinstance($children_prop[0], selenium.webdriver.remote.webelement.WebElement) modules=selenium
127+
Should Be Equal ${isWebElement} ${True}
128+
# ToDo: need to test own versus inherited property
129+
# ToDo: Test enumerated property
130+
131+
Get "Attribute" That Is Both An DOM Attribute and Property
132+
[Setup] Go To Page "forms/enabled_disabled_fields_form.html"
133+
${value_property}= Get Property css:input[name="readonly_empty"] value
134+
${value_attribute}= Get DOM Attribute css:input[name="readonly_empty"] value
135+
Should Be Equal ${value_property} ${value_attribute}
136+
137+
Modify "Attribute" That Is Both An DOM Attribute and Property
138+
[Setup] Go To Page "forms/prefilled_email_form.html"
139+
${initial_value_property}= Get Property css:input[name="email"] value
140+
${initial_value_attribute}= Get DOM Attribute css:input[name="email"] value
141+
Should Be Equal ${initial_value_property} ${initial_value_attribute}
142+
Should Be Equal ${initial_value_attribute} Prefilled Email
143+
Input Text css:input[name="email"] [email protected]
144+
${changed_value_property}= Get Property css:input[name="email"] value
145+
${changed_value_attribute}= Get DOM Attribute css:input[name="email"] value
146+
Should Not Be Equal ${changed_value_property} ${changed_value_attribute}
147+
Should Be Equal ${changed_value_attribute} Prefilled Email
148+
Should Be Equal ${changed_value_property} [email protected]
149+
63150
Get Element Attribute Value Should Be Should Be Succesfull
64151
Element Attribute Value Should Be link=Absolute external link href http://www.google.com/
65152
Element Attribute Value Should Be link=Absolute external link nothere ${None}

src/SeleniumLibrary/keywords/element.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,38 @@ def get_element_attribute(
409409
"""
410410
return self.find_element(locator).get_attribute(attribute)
411411

412+
@keyword
413+
def get_dom_attribute(
414+
self, locator: Union[WebElement, str], attribute: str
415+
) -> str:
416+
"""Returns the value of ``attribute`` from the element ``locator``. `Get DOM Attribute` keyword
417+
only returns attributes declared within the element's HTML markup. If the requested attribute
418+
is not there, the keyword returns ${None}.
419+
420+
See the `Locating elements` section for details about the locator
421+
syntax.
422+
423+
Example:
424+
| ${id}= | `Get DOM Attribute` | css:h1 | id |
425+
426+
"""
427+
return self.find_element(locator).get_dom_attribute(attribute)
428+
429+
@keyword
430+
def get_property(
431+
self, locator: Union[WebElement, str], property: str
432+
) -> str:
433+
"""Returns the value of ``property`` from the element ``locator``.
434+
435+
See the `Locating elements` section for details about the locator
436+
syntax.
437+
438+
Example:
439+
| ${text_length}= | `Get Property` | css:h1 | text_length |
440+
441+
"""
442+
return self.find_element(locator).get_property(property)
443+
412444
@keyword
413445
def element_attribute_value_should_be(
414446
self,

utest/test/api/test_plugins.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def setUpClass(cls):
2222
def test_no_libraries(self):
2323
for item in [None, "None", ""]:
2424
sl = SeleniumLibrary(plugins=item)
25-
self.assertEqual(len(sl.get_keyword_names()), 178)
25+
self.assertEqual(len(sl.get_keyword_names()), 180)
2626

2727
def test_parse_library(self):
2828
plugin = "path.to.MyLibrary"

0 commit comments

Comments
 (0)