Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Selenium2Library/keywords/_browsermanagement.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ def select_frame(self, locator):
details about locating elements.
"""
self._info("Selecting frame '%s'." % locator)
element = self._element_find(locator, True, True, tag='frame')
element = self._element_find(locator, True, True, tag=['frame','iframe'])
self._current_browser().switch_to_frame(element)

def select_window(self, locator=None):
Expand Down
4 changes: 3 additions & 1 deletion src/Selenium2Library/keywords/_element.py
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,8 @@ def _element_find(self, locator, first_only, required, tag=None):

def _frame_contains(self, locator, text):
browser = self._current_browser()
element = self._element_find(locator, True, True, 'frame')

element = self._element_find(locator, True, True, ['frame','iframe'])
browser.switch_to_frame(element)
self._info("Searching for text from frame '%s'." % locator)
found = self._is_text_present(text)
Expand Down Expand Up @@ -590,6 +591,7 @@ def _page_contains(self, text):
return True

subframes = self._element_find("tag=frame", False, False, 'frame')
subframes.extend(self._element_find("tag=iframe", False, False, 'iframe'))
self._debug('Current frame has %d subframes' % len(subframes))
for frame in subframes:
browser.switch_to_frame(frame)
Expand Down
45 changes: 30 additions & 15 deletions src/Selenium2Library/locators/elementfinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,23 +76,36 @@ def _find_by_default(self, browser, criteria, tag, constraints):
return self._find_by_xpath(browser, criteria, tag, constraints)
return self._find_by_key_attrs(browser, criteria, tag, constraints)

def _find_by_key_attrs(self, browser, criteria, tag, constraints):
def _find_by_key_attrs(self, browser, criteria, tags, constraints):
key_attrs = self._key_attrs.get(None)
if tag is not None:
key_attrs = self._key_attrs.get(tag, key_attrs)
if tags is not None and not isinstance(tags, (list, tuple)):
key_attrs = self._key_attrs.get(tags, key_attrs)

xpath_criteria = utils.escape_xpath_value(criteria)
xpath_tag = tag if tag is not None else '*'
xpath_constraints = ["@%s='%s'" % (name, constraints[name]) for name in constraints]
xpath_searchers = ["%s=%s" % (attr, xpath_criteria) for attr in key_attrs]
xpath_searchers.extend(
self._get_attrs_with_url(key_attrs, criteria, browser))
xpath = "//%s[%s(%s)]" % (
xpath_tag,
' and '.join(xpath_constraints) + ' and ' if len(xpath_constraints) > 0 else '',
' or '.join(xpath_searchers))

return browser.find_elements_by_xpath(xpath)
#if not tag:
# xpath_tag = '*'
#elif tag and not isinstance(tag,(list,tuple)):
# xpath_tag = tag
#elif isinstance(tag,(list,tuple)):
# xpath_tag = ' or '.join(t for t in tag)
if not isinstance(tags,(list,tuple)): tags =[tags]

full_xpath = ""
for tag in tags:
xpath_tag = tag if tag is not None else '*'
xpath_constraints = ["@%s='%s'" % (name, constraints[name]) for name in constraints]
xpath_searchers = ["%s=%s" % (attr, xpath_criteria) for attr in key_attrs]
xpath_searchers.extend(
self._get_attrs_with_url(key_attrs, criteria, browser))
xpath = "//%s[%s(%s)]" % (
xpath_tag,
' and '.join(xpath_constraints) + ' and ' if len(xpath_constraints) > 0 else '',
' or '.join(xpath_searchers))
if len(full_xpath) > 1:
full_xpath = "%s | %s" % (full_xpath,xpath)
else:
full_xpath = xpath
return browser.find_elements_by_xpath(full_xpath)

# Private

Expand All @@ -106,6 +119,8 @@ def _find_by_key_attrs(self, browser, criteria, tag, constraints):

def _get_tag_and_constraints(self, tag):
if tag is None: return None, {}
#we want to allow a list of tags as well
if isinstance(tag, (list,tuple)): return tag, {}

tag = tag.lower()
constraints = {}
Expand All @@ -130,7 +145,7 @@ def _get_tag_and_constraints(self, tag):
return tag, constraints

def _element_matches(self, element, tag, constraints):
if not element.tag_name.lower() == tag:
if not element.tag_name.lower() in tag:
return False
for name in constraints:
if not element.get_attribute(name) == constraints[name]:
Expand Down
5 changes: 5 additions & 0 deletions test/acceptance/keywords/frames.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ Frame Should Contain
Frame Should contain right You're looking at right.
Frame Should Contain left Links

iFrame Should Contain
Select Frame right
Frame Should contain iframe_right You're looking at iframe right.

Select And Unselect Frame
[Documentation] LOG 1 Selecting frame 'left'.
Select Frame left
Click Link foo
Unselect Frame
Select Frame right
Current Frame Contains You're looking at foo.

6 changes: 4 additions & 2 deletions test/resources/html/frames/frameset.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<html>
<frameset cols="20%, 80%">
<frame name="left" src="left.html"/>
<frame name="right" src="right.html"/>
<frame name="right" src="right.html">
<iframe name="iframe_right" src="iframe_right.html" frameborder="0" scrolling="auto" width="500" height="180" marginwidth="5" marginheight="5"/>
</frame>
</frameset>
</html>
</html>
5 changes: 5 additions & 0 deletions test/resources/html/frames/iframe_right.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<html>
<body>
<p>You're looking at iframe right</span>.</p>
</body>
</html>
3 changes: 2 additions & 1 deletion test/resources/html/frames/right.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<html>
<body>
<p>You're looking at <span id="page_identifier">right</span>.</p>
<iframe name="iframe_right" src="iframe_right.html" frameborder="2" scrolling="auto" width="500" height="180" marginwidth="5" marginheight="5"/>
</body>
</html>
</html>
2 changes: 2 additions & 0 deletions test/run_unit_tests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#!/usr/bin/env python

import env
import os, sys
import unittest
Expand Down
18 changes: 18 additions & 0 deletions test/unit/locators/test_elementfinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,24 @@ def test_find_by_name(self):
result = finder.find(browser, "name=test1", tag='a')
self.assertEqual(result, [elements[1], elements[3]])


def test_find_by_name_filter_on_multiple_tags(self):
finder = ElementFinder()
browser = mock()

elements = self._make_mock_elements('div', 'a', 'span', 'a')
when(browser).find_elements_by_name("test1").thenReturn(elements)

result = finder.find(browser, "name=test1")
self.assertEqual(result, elements)
result = finder.find(browser, "name=test1", tag=['div','span'])
self.assertEqual(result, [elements[0], elements[2]])
result = finder.find(browser, "name=test1", tag=['div','span','a'])
self.assertEqual(result, elements)




def test_find_by_xpath(self):
finder = ElementFinder()
browser = mock()
Expand Down