Commit a296761f by Ben Patterson Committed by Ned Batchelder

Cherry-pick all of PR #14491:

Fix lettuce tests for Xenial compatibility and newer Chrome version.

(cherry-picked from c3887b0b)

Properly wait for LTI stub's buttons to render

(cherry-picked from c58e5142)

Workaround for intermittent chromedriver hangs upon start.

(cherry-picked from 840efb23)

Refactor click since it was resulting in timeout errors; use correct id for one of the LTI stub's buttons.

(cherry-picked from 452a1f1f)

Solve open sans quotation issue with tests.

(cherry-picked from 0e7e9468)

Fixes for chrome reliability in selenium.

Fix for rendering timing issue. See https://bugs.chromium.org/p/chromedriver/issues/detail?id=1552

(cherry-picked from e7b0c28d)

Multi-thread stub servers.

(cherry-picked from 0e596dd5)

Lettuce-on-Xenial CMS fix. Iterate through a list to avoid quotation string confusion.

Also change some selenium settings (they were not necessary at this time).

(cherry-picked from c0dd2b87)
parent 6b4e2e34
......@@ -110,7 +110,7 @@ Feature: CMS.HTML Editor
When I edit the page
And I click font selection dropdown
Then I should see a list of available fonts
And "Default" option sets "'Open Sans', Verdana, Arial, Helvetica, sans-serif" font family
And "Default" option sets the expected font family
And all standard tinyMCE fonts should be available
# Skipping in master due to brittleness JZ 05/22/2014
......
......@@ -229,41 +229,45 @@ def font_selector_dropdown_is_shown(step):
assert_equal(actual_fonts, expected_fonts)
@step('"Default" option sets "(.*)" font family')
def default_options_sets_expected_font_family(step, expected_font_family):
@step('"Default" option sets the expected font family')
def default_options_sets_expected_font_family(step): # pylint: disable=unused-argument, redefined-outer-name
fonts = get_available_fonts(get_fonts_list_panel(world))
assert_equal(fonts.get("Default", None), expected_font_family)
fonts_found = fonts.get("Default", None)
expected_font_family = CUSTOM_FONTS.get('Default')
for expected_font in expected_font_family:
assert_in(expected_font, fonts_found)
@step('all standard tinyMCE fonts should be available')
def check_standard_tinyMCE_fonts(step):
fonts = get_available_fonts(get_fonts_list_panel(world))
for label, expected_font in TINYMCE_FONTS.items():
assert_equal(fonts.get(label, None), expected_font)
for label, expected_fonts in TINYMCE_FONTS.items():
for expected_font in expected_fonts:
assert_in(expected_font, fonts.get(label, None))
TINYMCE_FONTS = OrderedDict([
("Andale Mono", "'andale mono', times"),
("Arial", "arial, helvetica, sans-serif"),
("Arial Black", "'arial black', 'avant garde'"),
("Book Antiqua", "'book antiqua', palatino"),
("Comic Sans MS", "'comic sans ms', sans-serif"),
("Courier New", "'courier new', courier"),
("Georgia", "georgia, palatino"),
("Helvetica", "helvetica"),
("Impact", "impact, chicago"),
("Symbol", "symbol"),
("Tahoma", "tahoma, arial, helvetica, sans-serif"),
("Terminal", "terminal, monaco"),
("Times New Roman", "'times new roman', times"),
("Trebuchet MS", "'trebuchet ms', geneva"),
("Verdana", "verdana, geneva"),
("Andale Mono", ['andale mono', 'times']),
("Arial", ['arial', 'helvetica', 'sans-serif']),
("Arial Black", ['arial black', 'avant garde']),
("Book Antiqua", ['book antiqua', 'palatino']),
("Comic Sans MS", ['comic sans ms', 'sans-serif']),
("Courier New", ['courier new', 'courier']),
("Georgia", ['georgia', 'palatino']),
("Helvetica", ['helvetica']),
("Impact", ['impact', 'chicago']),
("Symbol", ['symbol']),
("Tahoma", ['tahoma', 'arial', 'helvetica', 'sans-serif']),
("Terminal", ['terminal', 'monaco']),
("Times New Roman", ['times new roman', 'times']),
("Trebuchet MS", ['trebuchet ms', 'geneva']),
("Verdana", ['verdana', 'geneva']),
# tinyMCE does not set font-family on dropdown span for these two fonts
("Webdings", ""), # webdings
("Wingdings", ""), # wingdings, 'zapf dingbats'
("Webdings", [""]), # webdings
("Wingdings", [""]), # wingdings, 'zapf dingbats'
])
CUSTOM_FONTS = OrderedDict([
('Default', "'Open Sans', Verdana, Arial, Helvetica, sans-serif"),
('Default', ['Open Sans', 'Verdana', 'Arial', 'Helvetica', 'sans-serif']),
])
......
......@@ -279,10 +279,9 @@ def after_each_step(step):
@after.harvest
def teardown_browser(total):
def saucelabs_status(total):
"""
Quit the browser after executing the tests.
Collect data for saucelabs.
"""
if world.LETTUCE_SELENIUM_CLIENT == 'saucelabs':
set_saucelabs_job_status(world.jobid, total.scenarios_ran == total.scenarios_passed)
world.browser.quit()
......@@ -56,12 +56,19 @@ def stop_video_server(_total):
video_server.shutdown()
@before.all # pylint: disable=no-member
def start_stub_servers():
"""
Start all stub servers
"""
for stub in SERVICES.keys():
start_stub(stub)
@before.each_scenario # pylint: disable=no-member
def process_requires_tags(scenario):
def skip_youtube_if_not_available(scenario):
"""
Process the scenario tags to make sure that any
requirements are met prior to that scenario
being executed.
Scenario tags must be named with this convention:
@requires_stub_bar, where 'bar' is the name of the stub service to start
......@@ -85,7 +92,7 @@ def process_requires_tags(scenario):
scenario.steps = []
return
start_stub(requires.group('server'))
return
def start_stub(name):
......@@ -124,11 +131,13 @@ def is_youtube_available(urls):
return True
@after.each_scenario # pylint: disable=no-member
@after.all # pylint: disable=no-member
def stop_stubs(_scenario):
"""
Shut down any stub services that were started up for the scenario.
Shut down any stub services.
"""
# close browser to ensure no open connections to the stub servers
world.browser.quit()
for name in SERVICES.keys():
stub_server = getattr(world, name, None)
if stub_server is not None:
......
......@@ -3,6 +3,7 @@ Stub implementation of an HTTP service.
"""
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from SocketServer import ThreadingMixIn
import urllib
import urlparse
import threading
......@@ -233,7 +234,7 @@ class StubHttpRequestHandler(BaseHTTPRequestHandler, object):
self.send_response(200)
class StubHttpService(HTTPServer, object):
class StubHttpService(ThreadingMixIn, HTTPServer, object):
"""
Stub HTTP service implementation.
"""
......
......@@ -191,13 +191,13 @@ class StubLtiHandler(StubHttpRequestHandler):
if submit_url:
submit_form = textwrap.dedent("""
<form action="{submit_url}/grade" method="post">
<input type="submit" name="submit-button" value="Submit">
<input type="submit" name="submit-button" value="Submit" id="submit-button">
</form>
<form action="{submit_url}/lti2_outcome" method="post">
<input type="submit" name="submit-lti2-button" value="Submit">
<input type="submit" name="submit-lti2-button" value="Submit" id="submit-lti2-button">
</form>
<form action="{submit_url}/lti2_delete" method="post">
<input type="submit" name="submit-lti2-delete-button" value="Submit">
<input type="submit" name="submit-lti2-delete-button" value="Submit" id="submit-lti-delete-button">
</form>
""").format(submit_url=submit_url)
else:
......
......@@ -359,7 +359,10 @@ def click_grade(_step, version):
location = world.scenario_dict['LTI'].location.html_id()
iframe_name = 'ltiFrame-' + location
with world.browser.get_iframe(iframe_name) as iframe:
iframe.find_by_name(version_map[version]['selector']).first.click()
css_ele = version_map[version]['selector']
css_loc = '#' + css_ele
world.wait_for_visible(css_loc)
world.css_click(css_loc)
assert iframe.is_text_present(version_map[version]['expected_text'])
......
......@@ -93,6 +93,8 @@ class AcceptanceTest(TestSuite):
report_file = self.report_dir / "{}.xml".format(self.system)
report_args = ["--xunit-file {}".format(report_file)]
return [
# set DBUS_SESSION_BUS_ADDRESS to avoid hangs on Chrome
"DBUS_SESSION_BUS_ADDRESS=/dev/null",
"DEFAULT_STORE={}".format(self.default_store),
"./manage.py",
self.system,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment