Codebase list splinter / 6b67b0d3-6c6d-423a-847e-1d5c396c3c17/upstream
Import upstream version 0.14.0 Kali Janitor 3 years ago
21 changed file(s) with 248 addition(s) and 136 deletion(s). Raw diff Collapse all Expand all
3333 - DJANGO_VERSION=1.7.11 DRIVER=tests/test_djangoclient.py
3434 - DRIVER=tests/test_zopetestbrowser.py
3535 - python: 3.6
36 env: DJANGO_VERSION=2.0.6 DRIVER=tests/test_djangoclient.py
36 env:
37 - DJANGO_VERSION=2.0.6 DRIVER=tests/test_djangoclient.py
38 - DRIVER=tests/test_zopetestbrowser.py
3739 - python: 3.7
38 env: DJANGO_VERSION=2.0.6 DRIVER=tests/test_djangoclient.py
40 env:
41 - DJANGO_VERSION=2.0.6 DRIVER=tests/test_djangoclient.py
42 - DRIVER=tests/test_zopetestbrowser.py
3943 - python: 3.8
40 env: DJANGO_VERSION=2.0.6 DRIVER=tests/test_djangoclient.py
44 env:
45 - DJANGO_VERSION=2.0.6 DRIVER=tests/test_djangoclient.py
46 - DRIVER=tests/test_zopetestbrowser.py
4147 install:
4248 - export PATH=$HOME:$PATH
4349 - make dependencies
0 0.13.0
0 0.14.0
5151 # built documents.
5252 #
5353 # The short X.Y version.
54 version = "0.13.0"
54 version = "0.14.0"
5555 # The full version, including alpha/beta/rc tags.
56 release = "0.13.0"
56 release = "0.14.0"
5757
5858 # The language for content autogenerated by Sphinx. Refer to documentation
5959 # for a list of supported languages.
88 what's new in splinter 0.1.1?
99 =============================
1010
11 - compability with Firefox 5
11 - compatibility with Firefox 5
0 .. Copyright 2020 splinter authors. All rights reserved.
1 Use of this source code is governed by a BSD-style
2 license that can be found in the LICENSE file.
3
4 .. meta::
5 :description: New splinter features on version 0.14.0.
6 :keywords: splinter 0.14.0, news
7
8 whats's new in splinter 0.14.0?
9 ===============================
10
11 * Add FindLinks api to non-webdrivers (https://github.com/cobrateam/splinter/pull/762)
12 * Add support for zope in python3 (https://github.com/cobrateam/splinter/pull/771)
13 * Fix WebDriverElement.screenshot when parent is a WebDriverElement (https://github.com/cobrateam/splinter/pull/769)
14 * Improve firefox headless support (https://github.com/cobrateam/splinter/pull/768)
15 * Fix mouse out on elements in the left corner of the viewport (https://github.com/cobrateam/splinter/pull/766)
16 * Fix fullscreen argument for firefox (https://github.com/cobrateam/splinter/pull/765)
17 * Fix unexpected keyword argument 'original_find' (https://github.com/cobrateam/splinter/pull/758)
18 * Fix incorrect error thrown when missing chrome/geckodriver (https://github.com/cobrateam/splinter/pull/749)
19 * Make find_by_value works with button elements (https://github.com/cobrateam/splinter/pull/746)
1111
1212 See below the changes for each splinter release.
1313
14 - :doc:`what's new in splinter 0.14.0 </news/0.14.0>`
1415 - :doc:`what's new in splinter 0.13.0 </news/0.13.0>`
1516 - :doc:`what's new in splinter 0.12.0 </news/0.12.0>`
1617 - :doc:`what's new in splinter 0.11.0 </news/0.11.0>`
1010
1111 setup(
1212 name="splinter",
13 version="0.13.0",
13 version="0.14.0",
1414 url="https://github.com/cobrateam/splinter",
1515 description="browser abstraction for web acceptance testing",
1616 long_description=README,
44 from splinter.browser import Browser # NOQA
55
66
7 __version__ = "0.13.0"
7 __version__ = "0.14.0"
2626 "chrome": ChromeWebDriver,
2727 }
2828
29 if sys.version_info[0] <= 2:
30 try:
31 from splinter.driver.zopetestbrowser import ZopeTestBrowser
3229
33 _DRIVERS["zope.testbrowser"] = ZopeTestBrowser
34 except ImportError:
35 pass
30 try:
31 from splinter.driver.zopetestbrowser import ZopeTestBrowser
32
33 _DRIVERS["zope.testbrowser"] = ZopeTestBrowser
34 except ImportError:
35 pass
3636
3737 try:
3838 import django # noqa
5858 This can mitigate issues running on Remote WebDriver.
5959
6060 """
61 err = None
62
6163 for _ in range(retry_count):
6264 try:
6365 return driver(*args, **kwargs)
6466 except (IOError, HTTPException, WebDriverException, MaxRetryError) as e:
65 pass
67 err = e
6668
67 raise e
69 raise err
6870
6971
7072 def Browser(driver_name="firefox", retry_count=3, *args, **kwargs):
0 class FindLinks(object):
1 """Contains methods for finding links in a parent.
2
3 Accessed through the browser object or an element via the links attribute.
4
5 Example:
6
7 browser.links.find_by_href('foobar')
8
9 """
10 def __init__(self, parent):
11 self.parent = parent
12
13 def find_by_href(self, href):
14 return self.parent.find_by_xpath(
15 '//a[@href="{}"]'.format(href),
16 original_find="link by href",
17 original_query=href,
18 )
19
20 def find_by_partial_href(self, partial_href):
21 return self.parent.find_by_xpath(
22 '//a[contains(@href, "{}")]'.format(partial_href),
23 original_find="link by partial href",
24 original_query=partial_href,
25 )
26
27 def find_by_partial_text(self, partial_text):
28 return self.parent.find_by_xpath(
29 '//a[contains(normalize-space(.), "{}")]'.format(partial_text),
30 original_find="link by partial text",
31 original_query=partial_text,
32 )
33
34 def find_by_text(self, text):
35 return self.parent.find_by_xpath(
36 '//a[text()="{}"]'.format(text),
37 original_find="link by text",
38 original_query=text,
39 )
1313 import lxml.html
1414 from lxml.cssselect import CSSSelector
1515 from splinter.driver import DriverAPI, ElementAPI
16 from splinter.driver.find_links import FindLinks
1617 from splinter.driver.element_present import ElementPresentMixIn
1718 from splinter.driver.xpath_utils import _concat_xpath_from_str
1819 from splinter.element_list import ElementList
2829 self._history = []
2930 self._last_urls = []
3031 self._forms = {}
32
33 self.links = FindLinks(self)
3134
3235 def __enter__(self):
3336 return self
147150 def find_by_css(self, selector):
148151 xpath = CSSSelector(selector).path
149152 return self.find_by_xpath(
150 xpath, original_find="css", original_selector=selector
151 )
152
153 def find_by_xpath(self, xpath, original_find=None, original_selector=None):
153 xpath, original_find="css", original_query=selector
154 )
155
156 def find_by_xpath(self, xpath, original_find=None, original_query=None):
154157 html = self.htmltree
155158
156159 elements = []
164167 elements.append((LxmlElement, xpath_element))
165168
166169 find_by = original_find or "xpath"
167 query = original_selector or xpath
170 query = original_query or xpath
168171
169172 return ElementList(
170173 [element_class(element, self) for element_class, element in elements],
174177
175178 def find_by_tag(self, tag):
176179 return self.find_by_xpath(
177 "//%s" % tag, original_find="tag", original_selector=tag
180 "//%s" % tag, original_find="tag", original_query=tag
178181 )
179182
180183 def find_by_value(self, value):
181 return self.find_by_xpath(
182 '//*[@value="%s"]' % value, original_find="value", original_selector=value
183 )
184 elem = self.find_by_xpath(
185 '//*[@value="%s"]' % value, original_find="value", original_query=value
186 )
187 if elem:
188 return elem
189 return self.find_by_xpath('//*[.="%s"]' % value)
184190
185191 def find_by_text(self, text):
186192 xpath_str = _concat_xpath_from_str(text)
187193 return self.find_by_xpath(
188194 xpath_str,
189195 original_find="text",
190 original_selector=text,
196 original_query=text,
191197 )
192198
193199 def find_by_id(self, id_value):
194200 return self.find_by_xpath(
195201 '//*[@id="%s"][1]' % id_value,
196202 original_find="id",
197 original_selector=id_value,
203 original_query=id_value,
198204 )
199205
200206 def find_by_name(self, name):
411417
412418 @property
413419 def value(self):
414 return self._control.value
420 try:
421 return self._control.value
422 except AttributeError:
423 return self._control.text
415424
416425 @property
417426 def checked(self):
1313 import warnings
1414
1515 from selenium.webdriver.common.alert import Alert
16 from selenium.common.exceptions import ElementClickInterceptedException, NoSuchElementException, WebDriverException, StaleElementReferenceException, TimeoutException
16 from selenium.common.exceptions import (
17 ElementClickInterceptedException,
18 NoSuchElementException,
19 WebDriverException,
20 StaleElementReferenceException,
21 TimeoutException,
22 MoveTargetOutOfBoundsException,
23 )
1724 from selenium.webdriver.common.action_chains import ActionChains
1825 from selenium.webdriver.support import expected_conditions as EC
1926 from selenium.webdriver.support.ui import WebDriverWait
2128 from six import BytesIO
2229
2330 from splinter.driver import DriverAPI, ElementAPI
31 from splinter.driver.find_links import FindLinks
2432 from splinter.driver.xpath_utils import _concat_xpath_from_str
2533 from splinter.element_list import ElementList
2634
180188 )
181189
182190
183 class FindLinks(object):
184 """Contains methods for finding links in a parent.
185
186 Accessed through the browser object or an element via the links attribute.
187
188 Example:
189
190 browser.links.find_by_href('foobar')
191
192 """
193 def __init__(self, parent):
194 self.parent = parent
195
196 def find_by_href(self, href):
197 return self.parent.find_by_xpath(
198 '//a[@href="{}"]'.format(href),
199 original_find="link by href",
200 original_query=href,
201 )
202
203 def find_by_partial_href(self, partial_href):
204 return self.parent.find_by_xpath(
205 '//a[contains(@href, "{}")]'.format(partial_href),
206 original_find="link by partial href",
207 original_query=partial_href,
208 )
209
210 def find_by_partial_text(self, partial_text):
211 return self.parent.find_by_xpath(
212 '//a[contains(normalize-space(.), "{}")]'.format(partial_text),
213 original_find="link by partial text",
214 original_query=partial_text,
215 )
216
217 def find_by_text(self, text):
218 return self.parent.find_by_xpath(
219 '//a[text()="{}"]'.format(text),
220 original_find="link by text",
221 original_query=text,
222 )
223
224
225191 def _find(self, finder, selector):
226192 """Search for elements. Returns a list of results.
227193
291257
292258 def __init__(self, wait_time=2):
293259 self.wait_time = wait_time
294 self.ori_window_size = None
295260
296261 self.links = FindLinks(self)
297262
571536 )
572537
573538 def find_by_value(self, value, wait_time=None):
574 return self.find_by_xpath(
539 elem = self.find_by_xpath(
575540 '//*[@value="{}"]'.format(value),
576541 original_find="value",
577542 original_query=value,
578543 wait_time=wait_time,
579544 )
545 if elem:
546 return elem
547 return self.find_by_xpath('//*[.="%s"]' % value)
580548
581549 def find_by_text(self, text=None, wait_time=None):
582550 xpath_str = _concat_xpath_from_str(text)
661629 os.close(fd)
662630
663631 if full:
632 ori_window_size = self.driver.get_window_size()
664633 self.full_screen()
665634
666635 self.driver.get_screenshot_as_file(filename)
667 self.recover_screen()
636
637 if full:
638 self.recover_screen(ori_window_size)
639
668640 return filename
669641
670642 def select(self, name, value):
684656 pass
685657
686658 def full_screen(self):
687 self.ori_window_size = self.driver.get_window_size()
688659 width = self.driver.execute_script("return Math.max(document.body.scrollWidth, document.body.offsetWidth);")
689660 height = self.driver.execute_script("return Math.max(document.body.scrollHeight, document.body.offsetHeight);")
690661 self.driver.set_window_size(width, height)
691662
692 def recover_screen(self):
693 if self.ori_window_size:
694 width = self.ori_window_size.get('width')
695 height = self.ori_window_size.get('height')
696 self.driver.set_window_size(width, height)
697 self.ori_window_size = None
663 def recover_screen(self, size):
664 width = size.get('width')
665 height = size.get('height')
666 self.driver.set_window_size(width, height)
698667
699668 def html_snapshot(self, name="", suffix=".html", encoding='utf-8'):
700669 """Write the current html to a file."""
851820 wait_time=wait_time,
852821 )
853822
854 def find_by_xpath(self, selector, wait_time=None):
823 def find_by_xpath(self, selector, wait_time=None, original_find="xpath", original_query=None):
855824 return self.find_by(
856825 self._element.find_elements_by_xpath,
857826 selector,
858 original_find="xpath",
827 original_find=original_find,
828 original_query=original_query,
859829 wait_time=wait_time,
860830 )
861831
929899
930900 """
931901 self.scroll_to()
932 ActionChains(self.driver).move_to_element_with_offset(
933 self._element, -10, -10).click().perform()
902 size = self._element.size
903
904 try:
905 # Fails on left edge of viewport
906 ActionChains(self.driver).move_to_element_with_offset(
907 self._element, -10, -10).click().perform()
908 except MoveTargetOutOfBoundsException:
909 ActionChains(self.driver).move_to_element_with_offset(
910 self._element, size['width'] + 10, 10).click().perform()
934911
935912 def double_click(self):
936913 """
955932 """
956933 self.scroll_to()
957934 ActionChains(self.driver).drag_and_drop(self._element, droppable._element).perform()
935
936 def _full_screen():
937 width = self.driver.execute_script("return Math.max(document.body.scrollWidth, document.body.offsetWidth);")
938 height = self.driver.execute_script("return Math.max(document.body.scrollHeight, document.body.offsetHeight);")
939 self.driver.set_window_size(width, height)
958940
959941 def screenshot(self, name='', suffix='.png', full=False):
960942 name = name or ''
964946 os.close(fd)
965947
966948 if full:
967 self.parent.full_screen()
949 ori_window_size = self.driver.get_window_size()
950 self._full_screen()
951
968952 target = self.screenshot_as_png()
969 self.parent.recover_screen()
953
954 if full:
955 # Restore screen size
956 width = ori_window_size.get('width')
957 height = ori_window_size.get('height')
958 self.driver.set_window_size(width, height)
959
970960 target.save(filename)
971961
972962 return filename
1212 WebDriverElement as WebDriverElement,
1313 )
1414 from splinter.driver.webdriver.cookie_manager import CookieManager
15 from selenium.webdriver.common.keys import Keys
16 from selenium.webdriver.common.action_chains import ActionChains
17 from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
1815 from selenium.webdriver.firefox.options import Options
1916
2017
6259 firefox_profile.add_extension(extension)
6360
6461 if headless:
65 os.environ.update({"MOZ_HEADLESS": "1"})
66 if 'firefox_binary' in kwargs:
67 if isinstance(kwargs['firefox_binary'], six.string_types):
68 binary = FirefoxBinary(kwargs['firefox_binary'])
69 else:
70 binary = kwargs['firefox_binary']
71 else:
72 binary = FirefoxBinary()
73 binary.add_command_line_options("-headless")
74 kwargs["firefox_binary"] = binary
75 else:
76 if "MOZ_HEADLESS" in os.environ:
77 del os.environ["MOZ_HEADLESS"]
62 firefox_options.add_argument("--headless")
7863
7964 if incognito:
8065 firefox_options.add_argument("-private")
8873 )
8974
9075 if fullscreen:
91 ActionChains(self.driver).send_keys(Keys.F11).perform()
76 self.driver.fullscreen_window()
9277
9378 self.element_class = WebDriverElement
9479
33 # Use of this source code is governed by a BSD-style
44 # license that can be found in the LICENSE file.
55
6 from __future__ import unicode_literals
7
8 import mimetypes
69 import re
7
10 import time
11
12 import lxml.html
813 from lxml.cssselect import CSSSelector
914 from zope.testbrowser.browser import Browser, ListControl, SubmitControl
1015 from splinter.element_list import ElementList
1116 from splinter.exceptions import ElementDoesNotExist
1217 from splinter.driver import DriverAPI, ElementAPI
1318 from splinter.driver.element_present import ElementPresentMixIn
19 from splinter.driver.find_links import FindLinks
1420 from splinter.driver.xpath_utils import _concat_xpath_from_str
1521 from splinter.cookie_manager import CookieManagerAPI
16
17 import mimetypes
18 import lxml.html
19 import time
2022
2123
2224 class CookieManager(CookieManagerAPI):
7173 self._cookie_manager = CookieManager(self._browser)
7274 self._last_urls = []
7375
76 self.links = FindLinks(self)
77
7478 def __enter__(self):
7579 return self
7680
98102
99103 @property
100104 def htmltree(self):
101 return lxml.html.fromstring(self.html.decode("utf-8"))
105 try:
106 html = self.html.decode("utf-8")
107 except AttributeError:
108 html = self.html
109
110 return lxml.html.fromstring(html)
102111
103112 @property
104113 def title(self):
131140 def find_by_css(self, selector):
132141 xpath = CSSSelector(selector).path
133142 return self.find_by_xpath(
134 xpath, original_find="css", original_selector=selector
143 xpath, original_find="css", original_query=selector
135144 )
136145
137146 def get_control(self, xpath_element):
138147 return xpath_element
139148
140 def find_by_xpath(self, xpath, original_find=None, original_selector=None):
149 def find_by_xpath(self, xpath, original_find=None, original_query=None):
141150 html = self.htmltree
142151
143152 elements = []
151160 elements.append(self.get_control(xpath_element))
152161
153162 find_by = original_find or "xpath"
154 query = original_selector or xpath
163 query = original_query or xpath
155164
156165 return ElementList(
157166 [ZopeTestBrowserElement(element, self) for element in elements],
161170
162171 def find_by_tag(self, tag):
163172 return self.find_by_xpath(
164 "//%s" % tag, original_find="tag", original_selector=tag
173 "//%s" % tag, original_find="tag", original_query=tag
165174 )
166175
167176 def find_by_value(self, value):
168 return self.find_by_xpath(
169 '//*[@value="%s"]' % value, original_find="value", original_selector=value
170 )
177 elem = self.find_by_xpath(
178 '//*[@value="%s"]' % value, original_find="value", original_query=value
179 )
180 if elem:
181 return elem
182 return self.find_by_xpath('//*[.="%s"]' % value)
171183
172184 def find_by_text(self, text):
173185 xpath_str = _concat_xpath_from_str(text)
174186 return self.find_by_xpath(
175187 xpath_str,
176188 original_find="text",
177 original_selector=text,
189 original_query=text,
178190 )
179191
180192 def find_by_id(self, id_value):
181193 return self.find_by_xpath(
182194 '//*[@id="%s"][1]' % id_value,
183195 original_find="id",
184 original_selector=id_value,
196 original_query=id_value,
185197 )
186198
187199 def find_by_name(self, name):
258270 filename = file_path.split("/")[-1]
259271 control = self._browser.getControl(name=name)
260272 content_type, _ = mimetypes.guess_type(file_path)
261 control.add_file(open(file_path), content_type, filename)
273 with open(file_path, 'rb') as f:
274 control.add_file(f, content_type, filename)
262275
263276 def _find_links_by_xpath(self, xpath):
264277 html = self.htmltree
0 zope.testbrowser==5.2.4; python_version < '3.0'
0 zope.testbrowser==5.5.1
11 lxml==4.2.4
22 Flask==1.0.2
33 selenium==3.141.0
1010 six==1.11.0
1111 twine==1.11.0
1212 pytest==4.6.4
13 Pillow==6.2.2
3232 u'inner <div class="inner-html">inner text</div> html test</div>',
3333 )
3434
35 def test_element_html_with_breakline(self):
36 self.assertEqual(
37 self.browser.find_by_id("html-property-with-breakline").html,
38 u'\\n some text here\\n',
39 )
40
3541 def test_element_html(self):
3642 self.assertEqual(
3743 self.browser.find_by_id("html-property").html,
2424 value = self.browser.find_by_value("M").value
2525 id = self.browser.find_by_id("gender-m")
2626 self.assertEqual(id.value, value)
27
28 def test_finding_by_value_in_btn_elements(self):
29 value = self.browser.find_by_value("some value").value
30 btn = self.browser.find_by_id("button-value")
31 self.assertEqual(btn.value, value)
2732
2833 def test_finding_by_text(self):
2934 element = self.browser.find_by_text("Complex")
88
99 class ScreenshotTest(object):
1010 def test_take_screenshot(self):
11 "should take a screenshot of the current page"
11 """Should take a screenshot of the current page"""
1212 filename = self.browser.screenshot()
13 self.assertTrue(tempfile.gettempdir() in filename)
13 assert tempfile.gettempdir() in filename
1414
1515 def test_take_screenshot_with_prefix(self):
16 "should add the prefix to the screenshot file name"
16 """Should add the prefix to the screenshot file name"""
1717 filename = self.browser.screenshot(name="foobar")
18 self.assertTrue("foobar" in filename)
18 assert "foobar" in filename
1919
2020 def test_take_screenshot_with_suffix(self):
21 "should add the suffix to the screenshot file name"
22 filename = self.browser.screenshot(suffix="jpeg")
23 self.assertEqual("jpeg", filename[-4:])
21 """Should add the suffix to the screenshot file name"""
22 filename = self.browser.screenshot(suffix=".jpg")
23 assert ".jpg" in filename[-4:]
24
25 def test_take_element_screenshot(self):
26 elem = self.browser.find_by_tag("body")
27 filename = elem.screenshot()
28 assert tempfile.gettempdir() in filename
29
30 def test_take_element_screenshot_with_prefix(self):
31 """Should add the prefix to the screenshot file name"""
32 elem = self.browser.find_by_tag("body")
33 filename = elem.screenshot(name="foobar")
34 assert "foobar" in filename
35
36 def test_take_nested_element_screenshot(self):
37 elem = self.browser.find_by_tag("body").find_by_css("h1")
38 filename = elem.screenshot()
39 assert tempfile.gettempdir() in filename
7979 <body>
8080 <h1 id="firstheader">Example Header</h1>
8181 <h1 id="firstheader">Example Last Header</h1>
82 <button id="button-value">some value</button>
8283 <form action="name" method="GET">
8384 <label for="query">Query</label>
8485 <input type="text" name="q" />
186187 <div class="dragged">no</div>
187188 <div class="has-class-first has-class-middle has-class-end"></div>
188189 <div id="html-property" class="outer html classes">inner <div class="inner-html">inner text</div> html test</div>
190 <p id="html-property-with-breakline">\n some text here\n</p>
189191 <a id="open-popup" href="javascript:poptastic('/popup')">Open pop-up window</a>
190192 <script>
191193 function poptastic(url) {
1111 from imp import reload
1212
1313 from splinter.exceptions import DriverNotFoundError
14
15 from selenium.common.exceptions import WebDriverException
16
17 import pytest
1418
1519 from .fake_webapp import EXAMPLE_APP
1620
5660 from splinter import Browser
5761
5862 Browser("unknown-driver")
63
64
65 @pytest.mark.parametrize('browser_name', ['chrome', 'firefox'])
66 def test_local_driver_not_present(browser_name):
67 """When chromedriver/geckodriver are not present on the system."""
68 from splinter import Browser
69
70 with pytest.raises(WebDriverException) as e:
71 Browser(browser_name, executable_path='failpath')
72
73 assert "Message: 'failpath' executable needs to be in PATH." in str(e.value)
77 import unittest
88 import sys
99
10 import six
11
1012 from splinter import Browser
1113 from .base import BaseBrowserTests
1214 from .fake_webapp import EXAMPLE_APP
1315 from .is_element_present_nojs import IsElementPresentNoJSTest
1416
1517
16 @unittest.skipIf(
17 sys.version_info[0] > 2,
18 "zope.testbrowser is not currently compatible with Python 3",
19 )
2018 class ZopeTestBrowserDriverTest(
2119 BaseBrowserTests, IsElementPresentNoJSTest, unittest.TestCase
2220 ):
4442 self.browser.find_by_name("upload").click()
4543
4644 html = self.browser.html
47 self.assertIn("text/plain", html)
48 self.assertIn(open(file_path).read().encode("utf-8"), html)
45
46 assert "text/plain" in html
47
48 with open(file_path) as f:
49 assert f.read() in html
4950
5051 def test_forward_to_none_page(self):
5152 "should not fail when trying to forward to none"
139140 "pangram_ru": u"В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!",
140141 "pangram_eo": u"Laŭ Ludoviko Zamenhof bongustas freŝa ĉeĥa manĝaĵo kun spicoj.",
141142 }
142 for key, text in non_ascii_encodings.iteritems():
143 for key, text in six.iteritems(non_ascii_encodings):
143144 link = self.browser.find_link_by_text(text)
144145 self.assertEqual(key, link["id"])