Bug 1381519 - Find element for (partial) link text has to use rendered content. r=ato

To retrieve links via "link text" or "partial link text" the rendered
content of the element has to be used. This can be the case for CSS
transformations like "uppercase".

MozReview-Commit-ID: fxaHEuWnbf

--HG--
extra : rebase_source : d283275a538662e1f199fd5646997f302c4b8ac7
This commit is contained in:
Henrik Skupin 2017-12-05 13:25:09 +01:00
Родитель eb0a672707
Коммит 30775ef148
7 изменённых файлов: 187 добавлений и 99 удалений

Просмотреть файл

@ -441,7 +441,8 @@ element.findByXPathAll = function* (document, startNode, expression) {
* Sequence of link elements which text is <var>s</var>.
*/
element.findByLinkText = function(startNode, linkText) {
return filterLinks(startNode, link => link.text.trim() === linkText);
return filterLinks(startNode,
link => atom.getElementText(link).trim() === linkText);
};
/**
@ -458,7 +459,8 @@ element.findByLinkText = function(startNode, linkText) {
* <var>linkText</var>.
*/
element.findByPartialLinkText = function(startNode, linkText) {
return filterLinks(startNode, link => link.text.includes(linkText));
return filterLinks(startNode,
link => atom.getElementText(link).includes(linkText));
};
/**
@ -551,7 +553,7 @@ function findElement(strategy, selector, document, startNode = undefined) {
case element.Strategy.LinkText:
for (let link of startNode.getElementsByTagName("a")) {
if (link.text.trim() === selector) {
if (atom.getElementText(link).trim() === selector) {
return link;
}
}
@ -559,7 +561,7 @@ function findElement(strategy, selector, document, startNode = undefined) {
case element.Strategy.PartialLinkText:
for (let link of startNode.getElementsByTagName("a")) {
if (link.text.includes(selector)) {
if (atom.getElementText(link).includes(selector)) {
return link;
}
}

Просмотреть файл

@ -42,9 +42,6 @@ class_html = inline("<p class='foo bar'>", doctype="html")
class_xhtml = inline('<p class="foo bar"></p>', doctype="xhtml")
name_html = inline("<p name=foo>", doctype="html")
name_xhtml = inline('<p name="foo"></p>', doctype="xhtml")
link_html = inline("<p><a href=#>foo bar</a>", doctype="html")
link_html_with_trailing_space = inline("<p><a href=#>a link with a trailing space </a>")
link_xhtml = inline('<p><a href="#">foo bar</a></p>', doctype="xhtml")
class TestFindElementHTML(MarionetteTestCase):
@ -100,27 +97,6 @@ class TestFindElementHTML(MarionetteTestCase):
with self.assertRaises(InvalidSelectorException):
self.marionette.find_element(By.CSS_SELECTOR, "#")
def test_link_text(self):
self.marionette.navigate(link_html)
el = self.marionette.execute_script("return document.querySelector('a')")
found = self.marionette.find_element(By.LINK_TEXT, "foo bar")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(el, found)
def test_link_text_with_trailing_space(self):
self.marionette.navigate(link_html_with_trailing_space)
el = self.marionette.execute_script("return document.querySelector('a')")
found = self.marionette.find_element(By.LINK_TEXT, "a link with a trailing space")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(el, found)
def test_partial_link_text(self):
self.marionette.navigate(link_html)
el = self.marionette.execute_script("return document.querySelector('a')")
found = self.marionette.find_element(By.PARTIAL_LINK_TEXT, "foo")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(el, found)
def test_xpath(self):
self.marionette.navigate(id_html)
el = self.marionette.execute_script("return document.querySelector('#foo')")
@ -264,20 +240,6 @@ class TestFindElementXHTML(MarionetteTestCase):
self.assertIsInstance(found, HTMLElement)
self.assertEqual(el, found)
def test_link_text(self):
self.marionette.navigate(link_xhtml)
el = self.marionette.execute_script("return document.querySelector('a')")
found = self.marionette.find_element(By.LINK_TEXT, "foo bar")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(el, found)
def test_partial_link_text(self):
self.marionette.navigate(link_xhtml)
el = self.marionette.execute_script("return document.querySelector('a')")
found = self.marionette.find_element(By.PARTIAL_LINK_TEXT, "foo")
self.assertIsInstance(found, HTMLElement)
self.assertEqual(el, found)
def test_xpath(self):
self.marionette.navigate(id_xhtml)
el = self.marionette.execute_script("return document.querySelector('#foo')")
@ -347,28 +309,6 @@ class TestFindElementsHTML(MarionetteTestCase):
with self.assertRaises(InvalidSelectorException):
self.marionette.find_elements(By.CSS_SELECTOR, "#")
def test_link_text(self):
self.marionette.navigate(link_html)
els = self.marionette.execute_script("return document.querySelectorAll('a')")
found = self.marionette.find_elements(By.LINK_TEXT, "foo bar")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(els, found)
def test_link_text_with_trailing_space(self):
self.marionette.navigate(link_html_with_trailing_space)
els = self.marionette.execute_script("return document.querySelectorAll('a')")
found = self.marionette.find_elements(By.LINK_TEXT, "a link with a trailing space")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(els, found)
def test_partial_link_text(self):
self.marionette.navigate(link_html)
els = self.marionette.execute_script("return document.querySelectorAll('a')")
found = self.marionette.find_elements(By.PARTIAL_LINK_TEXT, "foo")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(els, found)
def test_xpath(self):
self.marionette.navigate(children_html)
els = self.marionette.execute_script("return document.querySelectorAll('p')")
@ -455,20 +395,6 @@ class TestFindElementsXHTML(MarionetteTestCase):
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(els, found)
def test_link_text(self):
self.marionette.navigate(link_xhtml)
els = self.marionette.execute_script("return document.querySelectorAll('a')")
found = self.marionette.find_elements(By.LINK_TEXT, "foo bar")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(els, found)
def test_partial_link_text(self):
self.marionette.navigate(link_xhtml)
els = self.marionette.execute_script("return document.querySelectorAll('a')")
found = self.marionette.find_elements(By.PARTIAL_LINK_TEXT, "foo")
self.assertItemsIsInstance(found, HTMLElement)
self.assertSequenceEqual(els, found)
@skip("XHTML namespace not yet supported")
def test_xpath(self):
self.marionette.navigate(children_xhtml)

Просмотреть файл

@ -500894,27 +500894,27 @@
"testharness"
],
"css/css-scoping/shadow-disabled-sheet-001.html": [
"a3ddf0fe7fa422f5e712b8771669be76b0e3a798",
"3de2d23c1b3339b964ec2c009832a3207a3b9dc4",
"reftest"
],
"css/css-scoping/shadow-fallback-dynamic-001.html": [
"062c99df18077a0205d0170d641b1d1e61199657",
"741cd9e29067a4634aa5beb6bd06afa540895d22",
"reftest"
],
"css/css-scoping/shadow-fallback-dynamic-002.html": [
"2f66c8bca48c2ce5c9e82c5d67b152e2d143f4c6",
"e9a0d8178387901404030dde1b7ae7b2842f2eca",
"reftest"
],
"css/css-scoping/shadow-fallback-dynamic-003.html": [
"f054b0974277fbee38a96a26559c9a15400266db",
"0b75fadbaee366349576e2d6f3ca8d6a49069f66",
"reftest"
],
"css/css-scoping/shadow-fallback-dynamic-004.html": [
"fc33527eaaa7711ecb2c7cd9523e793bce2503f2",
"71dcc60c4ff59690927c1575fff2eecf85ee558f",
"reftest"
],
"css/css-scoping/shadow-fallback-dynamic-005.html": [
"46d78b6d6931505bbc4bfc2f83e2bd0bac0d3472",
"ab3c3d205e59df800ba5b4217245b83685521c31",
"reftest"
],
"css/css-scoping/shadow-root-insert-into-document.html": [
@ -593514,19 +593514,19 @@
"support"
],
"webdriver/tests/element_retrieval/find_element.py": [
"699b97bd31eed625e2f0bed145aaf94c3e646853",
"8c9ed3ac2169f4b65a2e172a6e77b9586d83afa2",
"wdspec"
],
"webdriver/tests/element_retrieval/find_element_from_element.py": [
"34f356f2579391289edb31adf5b4d4eb88ffc643",
"ecb74fc793a35481e2aa2456544b8b8f32d08546",
"wdspec"
],
"webdriver/tests/element_retrieval/find_elements.py": [
"284ae53c5c94d02fb46b26dcd70af02d7917e7b4",
"fa8c2de1ffd12432bf14368b9c72000567ab8d20",
"wdspec"
],
"webdriver/tests/element_retrieval/find_elements_from_element.py": [
"b062b9f044268f0d9e092def81afae1277a91cd8",
"6099bab098d03c0ac17134014b0acaf0b977731a",
"wdspec"
],
"webdriver/tests/element_retrieval/get_active_element.py": [
@ -594658,7 +594658,7 @@
"testharness"
],
"websockets/Create-on-worker-shutdown.html": [
"75112264efdc3b310f4ba2ab4517b7608aacf2f2",
"213d7b23d154b930cc20985c2a86509fcdc09a9a",
"testharness"
],
"websockets/Create-protocol-with-space.htm": [

Просмотреть файл

@ -51,6 +51,39 @@ def test_find_element(session, using, value):
assert_success(response)
@pytest.mark.parametrize("document,value", [
("<a href=#>link text</a>", "link text"),
("<a href=#>&nbsp;link text&nbsp;</a>", "link text"),
("<a href=#>link<br>text</a>", "link\ntext"),
("<a href=#>link&amp;text</a>", "link&text"),
("<a href=#>LINK TEXT</a>", "LINK TEXT"),
("<a href=# style='text-transform: uppercase'>link text</a>", "LINK TEXT"),
])
def test_find_element_link_text(session, document, value):
# Step 8 - 9
session.url = inline(document)
response = find_element(session, "link text", value)
assert_success(response)
@pytest.mark.parametrize("document,value", [
("<a href=#>partial link text</a>", "link"),
("<a href=#>&nbsp;partial link text&nbsp;</a>", "link"),
("<a href=#>partial link text</a>", "k t"),
("<a href=#>partial link<br>text</a>", "k\nt"),
("<a href=#>partial link&amp;text</a>", "k&t"),
("<a href=#>PARTIAL LINK TEXT</a>", "LINK"),
("<a href=# style='text-transform: uppercase'>partial link text</a>", "LINK"),
])
def test_find_element_partial_link_text(session, document, value):
# Step 8 - 9
session.url = inline(document)
response = find_element(session, "partial link text", value)
assert_success(response)
@pytest.mark.parametrize("using,value", [("css selector", "#wontExist")])
def test_no_element(session, using, value):
# Step 8 - 9
@ -65,7 +98,8 @@ def test_no_element(session, using, value):
("tag name", "a"),
("xpath", "//*[name()='a']")])
def test_xhtml_namespace(session, using, value):
session.url = inline("""<a href="#" id="linkText">full link text</a>""", doctype="xhtml")
session.url = inline("""<a href="#" id="linkText">full link text</a>""",
doctype="xhtml")
expected = session.execute_script("return document.links[0]")
response = find_element(session, using, value)

Просмотреть файл

@ -31,7 +31,6 @@ def test_closed_context(session, create_window):
session.close()
response = find_element(session, "notReal", "css selector", "foo")
assert_error(response, "no such window")
@ -49,6 +48,41 @@ def test_find_element(session, using, value):
assert_success(response)
@pytest.mark.parametrize("document,value", [
("<a href=#>link text</a>", "link text"),
("<a href=#>&nbsp;link text&nbsp;</a>", "link text"),
("<a href=#>link<br>text</a>", "link\ntext"),
("<a href=#>link&amp;text</a>", "link&text"),
("<a href=#>LINK TEXT</a>", "LINK TEXT"),
("<a href=# style='text-transform: uppercase'>link text</a>", "LINK TEXT"),
])
def test_find_element_link_text(session, document, value):
# Step 8 - 9
session.url = inline("<div>{0}</div>".format(document))
element = session.find.css("div", all=False)
response = find_element(session, element.id, "link text", value)
assert_success(response)
@pytest.mark.parametrize("document,value", [
("<a href=#>partial link text</a>", "link"),
("<a href=#>&nbsp;partial link text&nbsp;</a>", "link"),
("<a href=#>partial link text</a>", "k t"),
("<a href=#>partial link<br>text</a>", "k\nt"),
("<a href=#>partial link&amp;text</a>", "k&t"),
("<a href=#>PARTIAL LINK TEXT</a>", "LINK"),
("<a href=# style='text-transform: uppercase'>partial link text</a>", "LINK"),
])
def test_find_element_partial_link_text(session, document, value):
# Step 8 - 9
session.url = inline("<div>{0}</div>".format(document))
element = session.find.css("div", all=False)
response = find_element(session, element.id, "partial link text", value)
assert_success(response)
@pytest.mark.parametrize("using,value",[("css selector", "#wontExist")])
def test_no_element(session, using, value):
# Step 8 - 9
@ -65,7 +99,8 @@ def test_no_element(session, using, value):
("tag name", "a"),
("xpath", "//*[name()='a']")])
def test_xhtml_namespace(session, using, value):
session.url = inline("""<p><a href="#" id="linkText">full link text</a></p>""", doctype="xhtml")
session.url = inline("""<p><a href="#" id="linkText">full link text</a></p>""",
doctype="xhtml")
from_element = session.execute_script("""return document.querySelector("p")""")
expected = session.execute_script("return document.links[0]")

Просмотреть файл

@ -30,10 +30,7 @@ def test_closed_context(session, create_window):
session.window_handle = new_window
session.close()
response = session.transport.send("POST",
"session/%s/elements" % session.session_id,
{"using": "css selector", "value": "foo"})
response = find_elements(session, "css selector", "foo")
assert_error(response, "no such window")
@ -52,6 +49,51 @@ def test_find_elements(session, using, value):
assert len(response.body["value"]) == 1
@pytest.mark.parametrize("document,value", [
("<a href=#>link text</a>", "link text"),
("<a href=#>&nbsp;link text&nbsp;</a>", "link text"),
("<a href=#>link<br>text</a>", "link\ntext"),
("<a href=#>link&amp;text</a>", "link&text"),
("<a href=#>LINK TEXT</a>", "LINK TEXT"),
("<a href=# style='text-transform: uppercase'>link text</a>", "LINK TEXT"),
])
def test_find_elements_link_text(session, document, value):
# Step 8 - 9
session.url = inline("<a href=#>not wanted</a><br/>{0}".format(document))
expected = session.execute_script("return document.links[1];")
response = find_elements(session, "link text", value)
value = assert_success(response)
assert isinstance(value, list)
assert len(value) == 1
found_element = value[0]
assert_same_element(session, found_element, expected)
@pytest.mark.parametrize("document,value", [
("<a href=#>partial link text</a>", "link"),
("<a href=#>&nbsp;partial link text&nbsp;</a>", "link"),
("<a href=#>partial link text</a>", "k t"),
("<a href=#>partial link<br>text</a>", "k\nt"),
("<a href=#>partial link&amp;text</a>", "k&t"),
("<a href=#>PARTIAL LINK TEXT</a>", "LINK"),
("<a href=# style='text-transform: uppercase'>partial link text</a>", "LINK"),
])
def test_find_elements_partial_link_text(session, document, value):
# Step 8 - 9
session.url = inline("<a href=#>not wanted</a><br/>{0}".format(document))
expected = session.execute_script("return document.links[1];")
response = find_elements(session, "partial link text", value)
value = assert_success(response)
assert isinstance(value, list)
assert len(value) == 1
found_element = value[0]
assert_same_element(session, found_element, expected)
@pytest.mark.parametrize("using,value", [("css selector", "#wontExist")])
def test_no_element(session, using, value):
# Step 8 - 9
@ -67,8 +109,9 @@ def test_no_element(session, using, value):
("tag name", "a"),
("xpath", "//*[name()='a']")])
def test_xhtml_namespace(session, using, value):
session.url = inline("""<p><a href="#" id="linkText">full link text</a></p>""", doctype="xhtml")
expected = session.execute_script("return document.links[0]")
session.url = inline("""<a href="#" id="linkText">full link text</a>""",
doctype="xhtml")
expected = session.execute_script("return document.links[0];")
response = find_elements(session, using, value)
value = assert_success(response)

Просмотреть файл

@ -48,6 +48,53 @@ def test_find_elements(session, using, value):
assert_success(response)
@pytest.mark.parametrize("document,value", [
("<a href=#>link text</a>", "link text"),
("<a href=#>&nbsp;link text&nbsp;</a>", "link text"),
("<a href=#>link<br>text</a>", "link\ntext"),
("<a href=#>link&amp;text</a>", "link&text"),
("<a href=#>LINK TEXT</a>", "LINK TEXT"),
("<a href=# style='text-transform: uppercase'>link text</a>", "LINK TEXT"),
])
def test_find_elements_link_text(session, document, value):
# Step 8 - 9
session.url = inline("<div><a href=#>not wanted</a><br/>{0}</div>".format(document))
element = session.find.css("div", all=False)
expected = session.execute_script("return document.links[1];")
response = find_elements(session, element.id, "link text", value)
value = assert_success(response)
assert isinstance(value, list)
assert len(value) == 1
found_element = value[0]
assert_same_element(session, found_element, expected)
@pytest.mark.parametrize("document,value", [
("<a href=#>partial link text</a>", "link"),
("<a href=#>&nbsp;partial link text&nbsp;</a>", "link"),
("<a href=#>partial link text</a>", "k t"),
("<a href=#>partial link<br>text</a>", "k\nt"),
("<a href=#>partial link&amp;text</a>", "k&t"),
("<a href=#>PARTIAL LINK TEXT</a>", "LINK"),
("<a href=# style='text-transform: uppercase'>partial link text</a>", "LINK"),
])
def test_find_elements_partial_link_text(session, document, value):
# Step 8 - 9
session.url = inline("<div><a href=#>not wanted</a><br/>{0}</div>".format(document))
element = session.find.css("div", all=False)
expected = session.execute_script("return document.links[1];")
response = find_elements(session, element.id, "partial link text", value)
value = assert_success(response)
assert isinstance(value, list)
assert len(value) == 1
found_element = value[0]
assert_same_element(session, found_element, expected)
@pytest.mark.parametrize("using,value", [("css selector", "#wontExist")])
def test_no_element(session, using, value):
# Step 8 - 9
@ -64,7 +111,8 @@ def test_no_element(session, using, value):
("tag name", "a"),
("xpath", "//*[name()='a']")])
def test_xhtml_namespace(session, using, value):
session.url = inline("""<p><a href="#" id="linkText">full link text</a></p>""", doctype="xhtml")
session.url = inline("""<p><a href="#" id="linkText">full link text</a></p>""",
doctype="xhtml")
from_element = session.execute_script("""return document.querySelector("p")""")
expected = session.execute_script("return document.links[0]")