diff --git a/src/SeleniumLibrary/__init__.py b/src/SeleniumLibrary/__init__.py index 07e658c12..bf1bac81f 100644 --- a/src/SeleniumLibrary/__init__.py +++ b/src/SeleniumLibrary/__init__.py @@ -31,7 +31,7 @@ SelectElementKeywords, TableElementKeywords, WaitingKeywords) -from SeleniumLibrary.locators import ElementFinder +from SeleniumLibrary.locators import ElementFinder, TableElementFinder from SeleniumLibrary.utils import (BrowserCache, Deprecated, LibraryListener, timestr_to_secs) @@ -260,6 +260,7 @@ def __init__(self, DynamicCore.__init__(self, libraries) self.ROBOT_LIBRARY_LISTENER = LibraryListener() self.element_finder = ElementFinder(self) + self._table_element_finder = TableElementFinder(self) _speed_in_secs = Deprecated('_speed_in_secs', 'speed') _timeout_in_secs = Deprecated('_timeout_in_secs', 'timeout') diff --git a/src/SeleniumLibrary/base/context.py b/src/SeleniumLibrary/base/context.py index 0dc3ebc81..c55634494 100644 --- a/src/SeleniumLibrary/base/context.py +++ b/src/SeleniumLibrary/base/context.py @@ -27,3 +27,11 @@ def browser(self): @property def browsers(self): return self.ctx._browsers + + @property + def element_finder(self): + return self.ctx.element_finder + + @property + def table_element_finder(self): + return self.ctx._table_element_finder diff --git a/src/SeleniumLibrary/base/librarycomponent.py b/src/SeleniumLibrary/base/librarycomponent.py index 949db41f3..235185e18 100644 --- a/src/SeleniumLibrary/base/librarycomponent.py +++ b/src/SeleniumLibrary/base/librarycomponent.py @@ -31,10 +31,6 @@ class LibraryComponent(ContextAware): def __init__(self, ctx): ContextAware.__init__(self, ctx) - @property - def element_finder(self): - return self.ctx.element_finder - def info(self, msg, html=False): logger.info(msg, html) diff --git a/src/SeleniumLibrary/keywords/tableelement.py b/src/SeleniumLibrary/keywords/tableelement.py index 05ab83366..c087a8086 100644 --- a/src/SeleniumLibrary/keywords/tableelement.py +++ b/src/SeleniumLibrary/keywords/tableelement.py @@ -15,15 +15,10 @@ # limitations under the License. from SeleniumLibrary.base import LibraryComponent, keyword -from SeleniumLibrary.locators import TableElementFinder class TableElementKeywords(LibraryComponent): - def __init__(self, ctx): - LibraryComponent.__init__(self, ctx) - self._table_element_finder = TableElementFinder(ctx) - @keyword def get_table_cell(self, table_locator, row, column, loglevel='INFO'): """Returns the content from a table cell. @@ -44,7 +39,7 @@ def get_table_cell(self, table_locator, row, column, loglevel='INFO'): column_index = column if column > 0: column_index = column - 1 - table = self._table_element_finder.find(table_locator) + table = self.table_element_finder.find(table_locator) if table: rows = table.find_elements_by_xpath("./thead/tr") 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 See `Page Should Contain Element` for explanation about `loglevel` argument. """ - element = self._table_element_finder.find_by_col(table_locator, col, - expected) + element = self.table_element_finder.find_by_col(table_locator, col, + expected) if element is None: self.ctx.log_source(loglevel) raise AssertionError("Column #%s in table identified by '%s' " @@ -132,8 +127,8 @@ def table_footer_should_contain(self, table_locator, expected, loglevel='INFO'): See `Page Should Contain Element` for explanation about `loglevel` argument. """ - element = self._table_element_finder.find_by_footer(table_locator, - expected) + element = self.table_element_finder.find_by_footer(table_locator, + expected) if element is None: self.ctx.log_source(loglevel) raise AssertionError("Footer in table identified by '%s' " @@ -150,8 +145,8 @@ def table_header_should_contain(self, table_locator, expected, loglevel='INFO'): See `Page Should Contain Element` for explanation about `loglevel` argument. """ - element = self._table_element_finder.find_by_header(table_locator, - expected) + element = self.table_element_finder.find_by_header(table_locator, + expected) if element is None: self.ctx.log_source(loglevel) 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' See `Page Should Contain Element` for explanation about `loglevel` argument. """ - element = self._table_element_finder.find_by_row(table_locator, - row, expected) + element = self.table_element_finder.find_by_row(table_locator, + row, expected) if element is None: self.ctx.log_source(loglevel) raise AssertionError("Row #%s in table identified by '%s' " @@ -194,8 +189,8 @@ def table_should_contain(self, table_locator, expected, loglevel='INFO'): See `Page Should Contain Element` for explanation about `loglevel` argument. """ - element = self._table_element_finder.find_by_content(table_locator, - expected) + element = self.table_element_finder.find_by_content(table_locator, + expected) if element is None: self.ctx.log_source(loglevel) raise AssertionError("Table identified by '%s' should have " diff --git a/src/SeleniumLibrary/locators/tableelementfinder.py b/src/SeleniumLibrary/locators/tableelementfinder.py index 3728ef55e..e71403286 100644 --- a/src/SeleniumLibrary/locators/tableelementfinder.py +++ b/src/SeleniumLibrary/locators/tableelementfinder.py @@ -16,15 +16,11 @@ from SeleniumLibrary.base import ContextAware -from .elementfinder import ElementFinder - class TableElementFinder(ContextAware): def __init__(self, ctx): ContextAware.__init__(self, ctx) - self.element_finder = ElementFinder(ctx) - self._locator_suffixes = { ('css', 'default'): [''], ('css', 'content'): [''], diff --git a/test/unit/api/__init__.py b/test/unit/api/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/test/unit/api/test_public_api_objects.py b/test/unit/api/test_public_api_objects.py new file mode 100644 index 000000000..10df765ff --- /dev/null +++ b/test/unit/api/test_public_api_objects.py @@ -0,0 +1,18 @@ +import unittest + +from SeleniumLibrary import SeleniumLibrary +from SeleniumLibrary.locators import ElementFinder, TableElementFinder + + +class TableElementFinderInAPITest(unittest.TestCase): + + def test_table_finder(self): + sl = SeleniumLibrary() + self.assertIsInstance(sl._table_element_finder, TableElementFinder) + + +class ElementFinderInAPITest(unittest.TestCase): + + def test_table_finder(self): + sl = SeleniumLibrary() + self.assertIsInstance(sl.element_finder, ElementFinder) diff --git a/test/unit/locators/test_tableelementfinder.py b/test/unit/locators/test_tableelementfinder.py index 823e365ee..65a7166a8 100644 --- a/test/unit/locators/test_tableelementfinder.py +++ b/test/unit/locators/test_tableelementfinder.py @@ -9,129 +9,121 @@ class ElementFinderTests(unittest.TestCase): def setUp(self): self.ctx = mock() - self.ctx.browser = self.browser = mock() + self.ctx.element_finder = mock() self.finder = TableElementFinder(self.ctx) + self.args = {'first_only': False, 'required': False} def tearDown(self): unstub() def test_find_with_implicit_css_locator(self): - when(self.browser).find_elements_by_css_selector( - "table#test1").thenReturn([]) + when(self.ctx.element_finder).find("css=table#test1", + **self.args).thenReturn([]) self.finder.find("test1") - verify(self.browser).find_elements_by_css_selector("table#test1") + verify(self.ctx.element_finder).find("css=table#test1", **self.args) def test_find_with_css_selector(self): elements = self._make_mock_elements('table', 'table', 'table') - when(self.browser).find_elements_by_css_selector( - "table#test1").thenReturn(elements) - self.assertEqual( - self.finder.find("css=table#test1"), - elements[0]) - verify(self.browser).find_elements_by_css_selector("table#test1") + when(self.ctx.element_finder).find("css=table#test1", + **self.args).thenReturn(elements) + self.assertEqual(self.finder.find("css=table#test1"), + elements[0]) + verify(self.ctx.element_finder).find("css=table#test1", **self.args) def test_find_with_xpath_selector(self): elements = self._make_mock_elements('table', 'table', 'table') - when(self.browser).find_elements_by_xpath( - "//table[@id='test1']").thenReturn(elements) - self.assertEqual( - self.finder.find("xpath=//table[@id='test1']"), - elements[0]) - verify(self.browser).find_elements_by_xpath( - "//table[@id='test1']") + when(self.ctx.element_finder).find("xpath=//table[@id='test1']", + **self.args).thenReturn(elements) + self.assertEqual(self.finder.find("xpath=//table[@id='test1']"), + elements[0]) + verify(self.ctx.element_finder).find("xpath=//table[@id='test1']", + **self.args) def test_find_with_content_constraint(self): elements = self._make_mock_elements('td', 'td', 'td') elements[1].text = 'hi' - when(self.browser).find_elements_by_css_selector( - "table#test1").thenReturn(elements) - self.assertEqual( - self.finder.find_by_content("test1", 'hi'), - elements[1]) - verify(self.browser).find_elements_by_css_selector("table#test1") + when(self.ctx.element_finder).find("css=table#test1", + **self.args).thenReturn(elements) + self.assertEqual(self.finder.find_by_content("test1", 'hi'), + elements[1]) + verify(self.ctx.element_finder).find("css=table#test1", + **self.args) def test_find_with_null_content_constraint(self): elements = self._make_mock_elements('td', 'td', 'td') elements[1].text = 'hi' - when(self.browser).find_elements_by_css_selector( - "table#test1").thenReturn(elements) - self.assertEqual( - self.finder.find_by_content("test1", None), - elements[0]) - verify(self.browser).find_elements_by_css_selector("table#test1") + when(self.ctx.element_finder).find("css=table#test1", + **self.args).thenReturn(elements) + self.assertEqual(self.finder.find_by_content("test1", None), + elements[0]) + verify(self.ctx.element_finder).find("css=table#test1", **self.args) def test_find_by_content_with_css_locator(self): - when(self.browser).find_elements_by_css_selector( - "table#test1").thenReturn([]) + when(self.ctx.element_finder).find("css=table#test1", + **self.args).thenReturn([]) self.finder.find_by_content("css=table#test1", 'hi') - verify(self.browser).find_elements_by_css_selector("table#test1") + verify(self.ctx.element_finder).find("css=table#test1", **self.args) def test_find_by_content_with_xpath_locator(self): - when(self.browser).find_elements_by_xpath( - "//table[@id='test1']//*").thenReturn([]) + when(self.ctx.element_finder).find("xpath=//table[@id='test1']//*", + **self.args).thenReturn([]) self.finder.find_by_content("xpath=//table[@id='test1']", 'hi') - verify(self.browser).find_elements_by_xpath("//table[@id='test1']//*") + verify(self.ctx.element_finder).find("xpath=//table[@id='test1']//*", + **self.args) def test_find_by_header_with_css_locator(self): - when(self.browser).find_elements_by_css_selector( - "table#test1 th").thenReturn([]) + when(self.ctx.element_finder).find("css=table#test1 th", + **self.args).thenReturn([]) self.finder.find_by_header("css=table#test1", 'hi') - verify(self.browser).find_elements_by_css_selector("table#test1 th") + verify(self.ctx.element_finder).find("css=table#test1 th", **self.args) def test_find_by_header_with_xpath_locator(self): - when(self.browser).find_elements_by_xpath( - "//table[@id='test1']//th").thenReturn([]) + when(self.ctx.element_finder).find("xpath=//table[@id='test1']//th", + **self.args).thenReturn([]) self.finder.find_by_header("xpath=//table[@id='test1']", 'hi') - verify(self.browser).find_elements_by_xpath( - "//table[@id='test1']//th") + verify(self.ctx.element_finder).find("xpath=//table[@id='test1']//th", + **self.args) def test_find_by_footer_with_css_locator(self): - when(self.browser).find_elements_by_css_selector( - "table#test1 tfoot td").thenReturn([]) + when(self.ctx.element_finder).find("css=table#test1 tfoot td", + **self.args).thenReturn([]) self.finder.find_by_footer("css=table#test1", 'hi') - verify(self.browser).find_elements_by_css_selector( - "table#test1 tfoot td") + verify(self.ctx.element_finder).find("css=table#test1 tfoot td", + **self.args) def test_find_by_footer_with_xpath_locator(self): - when(self.browser).find_elements_by_xpath( - "//table[@id='test1']//tfoot//td").thenReturn([]) + xpath = "xpath=//table[@id='test1']//tfoot//td" + when(self.ctx.element_finder).find(xpath, **self.args).thenReturn([]) self.finder.find_by_footer("xpath=//table[@id='test1']", 'hi') - verify(self.browser).find_elements_by_xpath("//table[@id='test1']" - "//tfoot//td") + verify(self.ctx.element_finder).find(xpath, **self.args) def test_find_by_row_with_css_locator(self): - when(self.browser).find_elements_by_css_selector( - "table#test1 tr:nth-child(2)").thenReturn([]) + when(self.ctx.element_finder).find("css=table#test1 tr:nth-child(2)", + **self.args).thenReturn([]) self.finder.find_by_row("css=table#test1", 2, 'hi') - verify(self.browser).find_elements_by_css_selector("table#test1 " - "tr:nth-child(2)") + verify(self.ctx.element_finder).find("css=table#test1 tr:nth-child(2)", + **self.args) def test_find_by_row_with_xpath_locator(self): - when(self.browser).find_elements_by_xpath( - "//table[@id='test1']//tr[2]//*").thenReturn([]) + xpath = "xpath=//table[@id='test1']//tr[2]//*" + when(self.ctx.element_finder).find(xpath, **self.args).thenReturn([]) self.finder.find_by_row("xpath=//table[@id='test1']", 2, 'hi') - verify(self.browser).find_elements_by_xpath("//table[@id='test1']" - "//tr[2]//*") + verify(self.ctx.element_finder).find(xpath, **self.args) def test_find_by_col_with_css_locator(self): - when(self.browser).find_elements_by_css_selector( - "table#test1 tr td:nth-child(2)").thenReturn([]) - when(self.browser).find_elements_by_css_selector( - "table#test1 tr th:nth-child(2)").thenReturn([]) + css1 = "css=table#test1 tr td:nth-child(2)" + css2 = "css=table#test1 tr th:nth-child(2)" + when(self.ctx.element_finder).find(css1, **self.args).thenReturn([]) + when(self.ctx.element_finder).find(css2, **self.args).thenReturn([]) self.finder.find_by_col("css=table#test1", 2, 'hi') - verify(self.browser).find_elements_by_css_selector( - "table#test1 tr td:nth-child(2)") - verify(self.browser).find_elements_by_css_selector( - "table#test1 tr th:nth-child(2)") + verify(self.ctx.element_finder).find(css1, **self.args) + verify(self.ctx.element_finder).find(css2, **self.args) def test_find_by_col_with_xpath_locator(self): - when(self.browser).find_elements_by_xpath("//table[@id='test1']//tr//" - "*[self::td or self" - "::th][2]").thenReturn([]) + xpath = "xpath=//table[@id='test1']//tr//*[self::td or self::th][2]" + when(self.ctx.element_finder).find(xpath, **self.args).thenReturn([]) self.finder.find_by_col("xpath=//table[@id='test1']", 2, 'hi') - verify(self.browser).find_elements_by_xpath("//table[@id='test1']" - "//tr//*[self::td or self" - "::th][2]") + verify(self.ctx.element_finder).find(xpath, **self.args) def _make_mock_elements(self, *tags): elements = []