Skip to content

Commit 57d1a89

Browse files
authored
Add table element finder in private API (robotframework#912)
* Added TableElementFinder in the private API Also added test for ElementFinder and TableElementFinder in API
1 parent 43e8158 commit 57d1a89

File tree

8 files changed

+103
-97
lines changed

8 files changed

+103
-97
lines changed

src/SeleniumLibrary/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
SelectElementKeywords,
3232
TableElementKeywords,
3333
WaitingKeywords)
34-
from SeleniumLibrary.locators import ElementFinder
34+
from SeleniumLibrary.locators import ElementFinder, TableElementFinder
3535
from SeleniumLibrary.utils import (BrowserCache, Deprecated, LibraryListener,
3636
timestr_to_secs)
3737

@@ -260,6 +260,7 @@ def __init__(self,
260260
DynamicCore.__init__(self, libraries)
261261
self.ROBOT_LIBRARY_LISTENER = LibraryListener()
262262
self.element_finder = ElementFinder(self)
263+
self._table_element_finder = TableElementFinder(self)
263264

264265
_speed_in_secs = Deprecated('_speed_in_secs', 'speed')
265266
_timeout_in_secs = Deprecated('_timeout_in_secs', 'timeout')

src/SeleniumLibrary/base/context.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,11 @@ def browser(self):
2727
@property
2828
def browsers(self):
2929
return self.ctx._browsers
30+
31+
@property
32+
def element_finder(self):
33+
return self.ctx.element_finder
34+
35+
@property
36+
def table_element_finder(self):
37+
return self.ctx._table_element_finder

src/SeleniumLibrary/base/librarycomponent.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,6 @@ class LibraryComponent(ContextAware):
3131
def __init__(self, ctx):
3232
ContextAware.__init__(self, ctx)
3333

34-
@property
35-
def element_finder(self):
36-
return self.ctx.element_finder
37-
3834
def info(self, msg, html=False):
3935
logger.info(msg, html)
4036

src/SeleniumLibrary/keywords/tableelement.py

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,10 @@
1515
# limitations under the License.
1616

1717
from SeleniumLibrary.base import LibraryComponent, keyword
18-
from SeleniumLibrary.locators import TableElementFinder
1918

2019

2120
class TableElementKeywords(LibraryComponent):
2221

23-
def __init__(self, ctx):
24-
LibraryComponent.__init__(self, ctx)
25-
self._table_element_finder = TableElementFinder(ctx)
26-
2722
@keyword
2823
def get_table_cell(self, table_locator, row, column, loglevel='INFO'):
2924
"""Returns the content from a table cell.
@@ -44,7 +39,7 @@ def get_table_cell(self, table_locator, row, column, loglevel='INFO'):
4439
column_index = column
4540
if column > 0:
4641
column_index = column - 1
47-
table = self._table_element_finder.find(table_locator)
42+
table = self.table_element_finder.find(table_locator)
4843
if table:
4944
rows = table.find_elements_by_xpath("./thead/tr")
5045
if row_index >= len(rows) or row_index < 0:
@@ -113,8 +108,8 @@ def table_column_should_contain(self, table_locator, col, expected, loglevel='IN
113108
See `Page Should Contain Element` for explanation about
114109
`loglevel` argument.
115110
"""
116-
element = self._table_element_finder.find_by_col(table_locator, col,
117-
expected)
111+
element = self.table_element_finder.find_by_col(table_locator, col,
112+
expected)
118113
if element is None:
119114
self.ctx.log_source(loglevel)
120115
raise AssertionError("Column #%s in table identified by '%s' "
@@ -132,8 +127,8 @@ def table_footer_should_contain(self, table_locator, expected, loglevel='INFO'):
132127
See `Page Should Contain Element` for explanation about
133128
`loglevel` argument.
134129
"""
135-
element = self._table_element_finder.find_by_footer(table_locator,
136-
expected)
130+
element = self.table_element_finder.find_by_footer(table_locator,
131+
expected)
137132
if element is None:
138133
self.ctx.log_source(loglevel)
139134
raise AssertionError("Footer in table identified by '%s' "
@@ -150,8 +145,8 @@ def table_header_should_contain(self, table_locator, expected, loglevel='INFO'):
150145
See `Page Should Contain Element` for explanation about
151146
`loglevel` argument.
152147
"""
153-
element = self._table_element_finder.find_by_header(table_locator,
154-
expected)
148+
element = self.table_element_finder.find_by_header(table_locator,
149+
expected)
155150
if element is None:
156151
self.ctx.log_source(loglevel)
157152
raise AssertionError("Header in table identified by '%s' should "
@@ -176,8 +171,8 @@ def table_row_should_contain(self, table_locator, row, expected, loglevel='INFO'
176171
177172
See `Page Should Contain Element` for explanation about `loglevel` argument.
178173
"""
179-
element = self._table_element_finder.find_by_row(table_locator,
180-
row, expected)
174+
element = self.table_element_finder.find_by_row(table_locator,
175+
row, expected)
181176
if element is None:
182177
self.ctx.log_source(loglevel)
183178
raise AssertionError("Row #%s in table identified by '%s' "
@@ -194,8 +189,8 @@ def table_should_contain(self, table_locator, expected, loglevel='INFO'):
194189
See `Page Should Contain Element` for explanation about
195190
`loglevel` argument.
196191
"""
197-
element = self._table_element_finder.find_by_content(table_locator,
198-
expected)
192+
element = self.table_element_finder.find_by_content(table_locator,
193+
expected)
199194
if element is None:
200195
self.ctx.log_source(loglevel)
201196
raise AssertionError("Table identified by '%s' should have "

src/SeleniumLibrary/locators/tableelementfinder.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,11 @@
1616

1717
from SeleniumLibrary.base import ContextAware
1818

19-
from .elementfinder import ElementFinder
20-
2119

2220
class TableElementFinder(ContextAware):
2321

2422
def __init__(self, ctx):
2523
ContextAware.__init__(self, ctx)
26-
self.element_finder = ElementFinder(ctx)
27-
2824
self._locator_suffixes = {
2925
('css', 'default'): [''],
3026
('css', 'content'): [''],

test/unit/api/__init__.py

Whitespace-only changes.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import unittest
2+
3+
from SeleniumLibrary import SeleniumLibrary
4+
from SeleniumLibrary.locators import ElementFinder, TableElementFinder
5+
6+
7+
class TableElementFinderInAPITest(unittest.TestCase):
8+
9+
def test_table_finder(self):
10+
sl = SeleniumLibrary()
11+
self.assertIsInstance(sl._table_element_finder, TableElementFinder)
12+
13+
14+
class ElementFinderInAPITest(unittest.TestCase):
15+
16+
def test_table_finder(self):
17+
sl = SeleniumLibrary()
18+
self.assertIsInstance(sl.element_finder, ElementFinder)

test/unit/locators/test_tableelementfinder.py

Lines changed: 64 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -9,129 +9,121 @@ class ElementFinderTests(unittest.TestCase):
99

1010
def setUp(self):
1111
self.ctx = mock()
12-
self.ctx.browser = self.browser = mock()
12+
self.ctx.element_finder = mock()
1313
self.finder = TableElementFinder(self.ctx)
14+
self.args = {'first_only': False, 'required': False}
1415

1516
def tearDown(self):
1617
unstub()
1718

1819
def test_find_with_implicit_css_locator(self):
19-
when(self.browser).find_elements_by_css_selector(
20-
"table#test1").thenReturn([])
20+
when(self.ctx.element_finder).find("css=table#test1",
21+
**self.args).thenReturn([])
2122
self.finder.find("test1")
22-
verify(self.browser).find_elements_by_css_selector("table#test1")
23+
verify(self.ctx.element_finder).find("css=table#test1", **self.args)
2324

2425
def test_find_with_css_selector(self):
2526
elements = self._make_mock_elements('table', 'table', 'table')
26-
when(self.browser).find_elements_by_css_selector(
27-
"table#test1").thenReturn(elements)
28-
self.assertEqual(
29-
self.finder.find("css=table#test1"),
30-
elements[0])
31-
verify(self.browser).find_elements_by_css_selector("table#test1")
27+
when(self.ctx.element_finder).find("css=table#test1",
28+
**self.args).thenReturn(elements)
29+
self.assertEqual(self.finder.find("css=table#test1"),
30+
elements[0])
31+
verify(self.ctx.element_finder).find("css=table#test1", **self.args)
3232

3333
def test_find_with_xpath_selector(self):
3434
elements = self._make_mock_elements('table', 'table', 'table')
35-
when(self.browser).find_elements_by_xpath(
36-
"//table[@id='test1']").thenReturn(elements)
37-
self.assertEqual(
38-
self.finder.find("xpath=//table[@id='test1']"),
39-
elements[0])
40-
verify(self.browser).find_elements_by_xpath(
41-
"//table[@id='test1']")
35+
when(self.ctx.element_finder).find("xpath=//table[@id='test1']",
36+
**self.args).thenReturn(elements)
37+
self.assertEqual(self.finder.find("xpath=//table[@id='test1']"),
38+
elements[0])
39+
verify(self.ctx.element_finder).find("xpath=//table[@id='test1']",
40+
**self.args)
4241

4342
def test_find_with_content_constraint(self):
4443
elements = self._make_mock_elements('td', 'td', 'td')
4544
elements[1].text = 'hi'
46-
when(self.browser).find_elements_by_css_selector(
47-
"table#test1").thenReturn(elements)
48-
self.assertEqual(
49-
self.finder.find_by_content("test1", 'hi'),
50-
elements[1])
51-
verify(self.browser).find_elements_by_css_selector("table#test1")
45+
when(self.ctx.element_finder).find("css=table#test1",
46+
**self.args).thenReturn(elements)
47+
self.assertEqual(self.finder.find_by_content("test1", 'hi'),
48+
elements[1])
49+
verify(self.ctx.element_finder).find("css=table#test1",
50+
**self.args)
5251

5352
def test_find_with_null_content_constraint(self):
5453
elements = self._make_mock_elements('td', 'td', 'td')
5554
elements[1].text = 'hi'
56-
when(self.browser).find_elements_by_css_selector(
57-
"table#test1").thenReturn(elements)
58-
self.assertEqual(
59-
self.finder.find_by_content("test1", None),
60-
elements[0])
61-
verify(self.browser).find_elements_by_css_selector("table#test1")
55+
when(self.ctx.element_finder).find("css=table#test1",
56+
**self.args).thenReturn(elements)
57+
self.assertEqual(self.finder.find_by_content("test1", None),
58+
elements[0])
59+
verify(self.ctx.element_finder).find("css=table#test1", **self.args)
6260

6361
def test_find_by_content_with_css_locator(self):
64-
when(self.browser).find_elements_by_css_selector(
65-
"table#test1").thenReturn([])
62+
when(self.ctx.element_finder).find("css=table#test1",
63+
**self.args).thenReturn([])
6664
self.finder.find_by_content("css=table#test1", 'hi')
67-
verify(self.browser).find_elements_by_css_selector("table#test1")
65+
verify(self.ctx.element_finder).find("css=table#test1", **self.args)
6866

6967
def test_find_by_content_with_xpath_locator(self):
70-
when(self.browser).find_elements_by_xpath(
71-
"//table[@id='test1']//*").thenReturn([])
68+
when(self.ctx.element_finder).find("xpath=//table[@id='test1']//*",
69+
**self.args).thenReturn([])
7270
self.finder.find_by_content("xpath=//table[@id='test1']", 'hi')
73-
verify(self.browser).find_elements_by_xpath("//table[@id='test1']//*")
71+
verify(self.ctx.element_finder).find("xpath=//table[@id='test1']//*",
72+
**self.args)
7473

7574
def test_find_by_header_with_css_locator(self):
76-
when(self.browser).find_elements_by_css_selector(
77-
"table#test1 th").thenReturn([])
75+
when(self.ctx.element_finder).find("css=table#test1 th",
76+
**self.args).thenReturn([])
7877
self.finder.find_by_header("css=table#test1", 'hi')
79-
verify(self.browser).find_elements_by_css_selector("table#test1 th")
78+
verify(self.ctx.element_finder).find("css=table#test1 th", **self.args)
8079

8180
def test_find_by_header_with_xpath_locator(self):
82-
when(self.browser).find_elements_by_xpath(
83-
"//table[@id='test1']//th").thenReturn([])
81+
when(self.ctx.element_finder).find("xpath=//table[@id='test1']//th",
82+
**self.args).thenReturn([])
8483
self.finder.find_by_header("xpath=//table[@id='test1']", 'hi')
85-
verify(self.browser).find_elements_by_xpath(
86-
"//table[@id='test1']//th")
84+
verify(self.ctx.element_finder).find("xpath=//table[@id='test1']//th",
85+
**self.args)
8786

8887
def test_find_by_footer_with_css_locator(self):
89-
when(self.browser).find_elements_by_css_selector(
90-
"table#test1 tfoot td").thenReturn([])
88+
when(self.ctx.element_finder).find("css=table#test1 tfoot td",
89+
**self.args).thenReturn([])
9190
self.finder.find_by_footer("css=table#test1", 'hi')
92-
verify(self.browser).find_elements_by_css_selector(
93-
"table#test1 tfoot td")
91+
verify(self.ctx.element_finder).find("css=table#test1 tfoot td",
92+
**self.args)
9493

9594
def test_find_by_footer_with_xpath_locator(self):
96-
when(self.browser).find_elements_by_xpath(
97-
"//table[@id='test1']//tfoot//td").thenReturn([])
95+
xpath = "xpath=//table[@id='test1']//tfoot//td"
96+
when(self.ctx.element_finder).find(xpath, **self.args).thenReturn([])
9897
self.finder.find_by_footer("xpath=//table[@id='test1']", 'hi')
99-
verify(self.browser).find_elements_by_xpath("//table[@id='test1']"
100-
"//tfoot//td")
98+
verify(self.ctx.element_finder).find(xpath, **self.args)
10199

102100
def test_find_by_row_with_css_locator(self):
103-
when(self.browser).find_elements_by_css_selector(
104-
"table#test1 tr:nth-child(2)").thenReturn([])
101+
when(self.ctx.element_finder).find("css=table#test1 tr:nth-child(2)",
102+
**self.args).thenReturn([])
105103
self.finder.find_by_row("css=table#test1", 2, 'hi')
106-
verify(self.browser).find_elements_by_css_selector("table#test1 "
107-
"tr:nth-child(2)")
104+
verify(self.ctx.element_finder).find("css=table#test1 tr:nth-child(2)",
105+
**self.args)
108106

109107
def test_find_by_row_with_xpath_locator(self):
110-
when(self.browser).find_elements_by_xpath(
111-
"//table[@id='test1']//tr[2]//*").thenReturn([])
108+
xpath = "xpath=//table[@id='test1']//tr[2]//*"
109+
when(self.ctx.element_finder).find(xpath, **self.args).thenReturn([])
112110
self.finder.find_by_row("xpath=//table[@id='test1']", 2, 'hi')
113-
verify(self.browser).find_elements_by_xpath("//table[@id='test1']"
114-
"//tr[2]//*")
111+
verify(self.ctx.element_finder).find(xpath, **self.args)
115112

116113
def test_find_by_col_with_css_locator(self):
117-
when(self.browser).find_elements_by_css_selector(
118-
"table#test1 tr td:nth-child(2)").thenReturn([])
119-
when(self.browser).find_elements_by_css_selector(
120-
"table#test1 tr th:nth-child(2)").thenReturn([])
114+
css1 = "css=table#test1 tr td:nth-child(2)"
115+
css2 = "css=table#test1 tr th:nth-child(2)"
116+
when(self.ctx.element_finder).find(css1, **self.args).thenReturn([])
117+
when(self.ctx.element_finder).find(css2, **self.args).thenReturn([])
121118
self.finder.find_by_col("css=table#test1", 2, 'hi')
122-
verify(self.browser).find_elements_by_css_selector(
123-
"table#test1 tr td:nth-child(2)")
124-
verify(self.browser).find_elements_by_css_selector(
125-
"table#test1 tr th:nth-child(2)")
119+
verify(self.ctx.element_finder).find(css1, **self.args)
120+
verify(self.ctx.element_finder).find(css2, **self.args)
126121

127122
def test_find_by_col_with_xpath_locator(self):
128-
when(self.browser).find_elements_by_xpath("//table[@id='test1']//tr//"
129-
"*[self::td or self"
130-
"::th][2]").thenReturn([])
123+
xpath = "xpath=//table[@id='test1']//tr//*[self::td or self::th][2]"
124+
when(self.ctx.element_finder).find(xpath, **self.args).thenReturn([])
131125
self.finder.find_by_col("xpath=//table[@id='test1']", 2, 'hi')
132-
verify(self.browser).find_elements_by_xpath("//table[@id='test1']"
133-
"//tr//*[self::td or self"
134-
"::th][2]")
126+
verify(self.ctx.element_finder).find(xpath, **self.args)
135127

136128
def _make_mock_elements(self, *tags):
137129
elements = []

0 commit comments

Comments
 (0)