From 21e7bc5128b42c54b204cf7558aff65889850d11 Mon Sep 17 00:00:00 2001 From: Jay Zoldak <jzoldak@edx.org> Date: Thu, 7 Mar 2013 11:01:15 -0500 Subject: [PATCH] More robust handling for finding and clicking on objects by css. Tag tests not working under PhantomJS to skip for now. --- .gitignore | 3 +- .../features/advanced-settings.feature | 3 + .../features/advanced-settings.py | 57 +++++++++++-------- .../contentstore/features/common.py | 41 ++++--------- .../contentstore/features/section.feature | 1 + .../studio-overview-togglesection.feature | 1 + .../contentstore/features/subsection.feature | 1 + common/djangoapps/terrain/browser.py | 3 +- 8 files changed, 55 insertions(+), 55 deletions(-) diff --git a/.gitignore b/.gitignore index 493df5a7fdd..b13a128a637 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,5 @@ nosetests.xml cover_html/ .idea/ .redcar/ -chromedriver.log \ No newline at end of file +chromedriver.log +ghostdriver.log diff --git a/cms/djangoapps/contentstore/features/advanced-settings.feature b/cms/djangoapps/contentstore/features/advanced-settings.feature index 4708a60be1b..779d44e4b2c 100644 --- a/cms/djangoapps/contentstore/features/advanced-settings.feature +++ b/cms/djangoapps/contentstore/features/advanced-settings.feature @@ -7,6 +7,7 @@ Feature: Advanced (manual) course policy When I select the Advanced Settings Then I see only the display name + @skip-phantom Scenario: Test if there are no policy settings without existing UI controls Given I am on the Advanced Course Settings page in Studio When I delete the display name @@ -14,6 +15,7 @@ Feature: Advanced (manual) course policy And I reload the page Then there are no advanced policy settings + @skip-phantom Scenario: Test cancel editing key name Given I am on the Advanced Course Settings page in Studio When I edit the name of a policy key @@ -32,6 +34,7 @@ Feature: Advanced (manual) course policy And I press the "Cancel" notification button Then the policy key value is unchanged + @skip-phantom Scenario: Test editing key value Given I am on the Advanced Course Settings page in Studio When I edit the value of a policy key diff --git a/cms/djangoapps/contentstore/features/advanced-settings.py b/cms/djangoapps/contentstore/features/advanced-settings.py index 4ce9421ad3b..dbbe769b8e1 100644 --- a/cms/djangoapps/contentstore/features/advanced-settings.py +++ b/cms/djangoapps/contentstore/features/advanced-settings.py @@ -2,9 +2,9 @@ from lettuce import world, step from common import * import time from selenium.common.exceptions import WebDriverException +from selenium.webdriver.support import expected_conditions as EC -from nose.tools import assert_equal -from nose.tools import assert_true +from nose.tools import assert_true, assert_false, assert_equal """ http://selenium.googlecode.com/svn/trunk/docs/api/py/webdriver/selenium.webdriver.common.keys.html @@ -20,6 +20,7 @@ def i_select_advanced_settings(step): css_click(expand_icon_css) link_css = 'li.nav-course-settings-advanced a' css_click(link_css) + # world.browser.click_link_by_text('Advanced Settings') @step('I am on the Advanced Course Settings page in Studio$') @@ -43,12 +44,20 @@ def edit_the_name_of_a_policy_key(step): @step(u'I press the "([^"]*)" notification button$') def press_the_notification_button(step, name): + def is_visible(driver): + return EC.visibility_of_element_located((By.CSS_SELECTOR,css,)) + def is_invisible(driver): + return EC.invisibility_of_element_located((By.CSS_SELECTOR,css,)) + + css = 'a.%s-button' % name.lower() + wait_for(is_visible) + try: - world.browser.click_link_by_text(name) + css_click_at(css) + wait_for(is_invisible) except WebDriverException, e: - css = 'a.%s-button' % name.lower() css_click_at(css) - + wait_for(is_invisible) @step(u'I edit the value of a policy key$') def edit_the_value_of_a_policy_key(step): @@ -104,29 +113,29 @@ def it_is_formatted(step): @step(u'the policy key name is unchanged$') def the_policy_key_name_is_unchanged(step): policy_key_css = 'input.policy-key' - e = css_find(policy_key_css).first - assert_equal(e.value, 'display_name') + val = css_find(policy_key_css).first.value + assert_equal(val, 'display_name') @step(u'the policy key name is changed$') def the_policy_key_name_is_changed(step): policy_key_css = 'input.policy-key' - e = css_find(policy_key_css).first - assert_equal(e.value, 'new') + val = css_find(policy_key_css).first.value + assert_equal(val, 'new') @step(u'the policy key value is unchanged$') def the_policy_key_value_is_unchanged(step): policy_value_css = 'li.course-advanced-policy-list-item div.value textarea' - e = css_find(policy_value_css).first - assert_equal(e.value, '"Robot Super Course"') + val = css_find(policy_value_css).first.value + assert_equal(val, '"Robot Super Course"') @step(u'the policy key value is changed$') def the_policy_key_value_is_unchanged(step): policy_value_css = 'li.course-advanced-policy-list-item div.value textarea' - e = css_find(policy_value_css).first - assert_equal(e.value, '"Robot Super Course X"') + val = css_find(policy_value_css).first.value + assert_equal(val, '"Robot Super Course X"') ############# HELPERS ############### @@ -149,7 +158,7 @@ def delete_entry(index): """ Delete the nth entry where index is 0-based """ - css = '.delete-button' + css = 'a.delete-button' assert_true(world.browser.is_element_present_by_css(css, 5)) delete_buttons = css_find(css) assert_true(len(delete_buttons) > index, "no delete button exists for entry " + str(index)) @@ -170,16 +179,16 @@ def assert_entries(css, expected_values): def click_save(): - css = ".save-button" - - def is_shown(driver): - visible = css_find(css).first.visible - if visible: - # Even when waiting for visible, this fails sporadically. Adding in a small wait. - time.sleep(float(1)) - return visible - wait_for(is_shown) - css_click(css) + css = "a.save-button" + + # def is_shown(driver): + # visible = css_find(css).first.visible + # if visible: + # # Even when waiting for visible, this fails sporadically. Adding in a small wait. + # time.sleep(float(1)) + # return visible + # wait_for(is_shown) + css_click_at(css) def fill_last_field(value): diff --git a/cms/djangoapps/contentstore/features/common.py b/cms/djangoapps/contentstore/features/common.py index b6e2b2b4292..f7e76ecf7f8 100644 --- a/cms/djangoapps/contentstore/features/common.py +++ b/cms/djangoapps/contentstore/features/common.py @@ -3,7 +3,9 @@ from lettuce.django import django_url from nose.tools import assert_true from nose.tools import assert_equal from selenium.webdriver.support.ui import WebDriverWait -from selenium.common.exceptions import WebDriverException +from selenium.common.exceptions import WebDriverException, StaleElementReferenceException +from selenium.webdriver.support import expected_conditions as EC +from selenium.webdriver.common.by import By from terrain.factories import UserFactory, RegistrationFactory, UserProfileFactory from terrain.factories import CourseFactory, GroupFactory @@ -15,8 +17,6 @@ from logging import getLogger logger = getLogger(__name__) ########### STEP HELPERS ############## - - @step('I (?:visit|access|open) the Studio homepage$') def i_visit_the_studio_homepage(step): # To make this go to port 8001, put @@ -54,9 +54,8 @@ def i_have_opened_a_new_course(step): log_into_studio() create_a_course() -####### HELPER FUNCTIONS ############## - +####### HELPER FUNCTIONS ############## def create_studio_user( uname='robot', email='robot+studio@edx.org', @@ -97,35 +96,15 @@ def assert_css_with_text(css, text): def css_click(css): ''' -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> Catch WebDriverException First try to use the regular click method, but if clicking in the middle of an element doesn't work it might be that it thinks some other element is on top of it there so click in the upper left -<<<<<<< HEAD ''' try: - assert_true(world.browser.is_element_present_by_css(css, 5)) - world.browser.find_by_css(css).first.click() + css_find(css).first.click() except WebDriverException, e: css_click_at(css) -======= - Rather than click in the middle of an element, - click in the upper left - ''' - css_click_at(css) ->>>>>>> Click in the upper left of an element instead of the middle. -======= - ''' - try: - assert_true(world.browser.is_element_present_by_css(css, 5)) - world.browser.find_by_css(css).first.click() - except WebDriverException, e: - css_click_at(css) ->>>>>>> Catch WebDriverException def css_click_at(css, x=10, y=10): @@ -133,8 +112,7 @@ def css_click_at(css, x=10, y=10): A method to click at x,y coordinates of the element rather than in the center of the element ''' - assert_true(world.browser.is_element_present_by_css(css, 5)) - e = world.browser.find_by_css(css).first + e = css_find(css).first e.action_chains.move_to_element_with_offset(e._element, x, y) e.action_chains.click() e.action_chains.perform() @@ -145,11 +123,16 @@ def css_fill(css, value): def css_find(css): + def is_visible(driver): + return EC.visibility_of_element_located((By.CSS_SELECTOR,css,)) + + assert_true(world.browser.is_element_present_by_css(css, 5)) + wait_for(is_visible) return world.browser.find_by_css(css) def wait_for(func): - WebDriverWait(world.browser.driver, 10).until(func) + WebDriverWait(world.browser.driver, 5).until(func) def id_find(id): diff --git a/cms/djangoapps/contentstore/features/section.feature b/cms/djangoapps/contentstore/features/section.feature index 75e7a4af10c..93ff1ca2476 100644 --- a/cms/djangoapps/contentstore/features/section.feature +++ b/cms/djangoapps/contentstore/features/section.feature @@ -26,6 +26,7 @@ Feature: Create Section And I save a new section release date Then the section release date is updated + @skip-phantom Scenario: Delete section Given I have opened a new course in Studio And I have added a new section diff --git a/cms/djangoapps/contentstore/features/studio-overview-togglesection.feature b/cms/djangoapps/contentstore/features/studio-overview-togglesection.feature index 5276b90d124..52c10e41a86 100644 --- a/cms/djangoapps/contentstore/features/studio-overview-togglesection.feature +++ b/cms/djangoapps/contentstore/features/studio-overview-togglesection.feature @@ -21,6 +21,7 @@ Feature: Overview Toggle Section Then I see the "Collapse All Sections" link And all sections are expanded + @skip-phantom Scenario: Collapse link is not removed after last section of a course is deleted Given I have a course with 1 section And I navigate to the course overview page diff --git a/cms/djangoapps/contentstore/features/subsection.feature b/cms/djangoapps/contentstore/features/subsection.feature index 4b5f5b869d5..1be5f4aeb92 100644 --- a/cms/djangoapps/contentstore/features/subsection.feature +++ b/cms/djangoapps/contentstore/features/subsection.feature @@ -17,6 +17,7 @@ Feature: Create Subsection And I click to edit the subsection name Then I see the complete subsection name with a quote in the editor + @skip-phantom Scenario: Delete a subsection Given I have opened a new course section in Studio And I have added a new subsection diff --git a/common/djangoapps/terrain/browser.py b/common/djangoapps/terrain/browser.py index 8c2a8ba7a52..ddd39196de8 100644 --- a/common/djangoapps/terrain/browser.py +++ b/common/djangoapps/terrain/browser.py @@ -12,7 +12,8 @@ from django.core.management import call_command @before.harvest def initial_setup(server): # Launch the browser app (choose one of these below) - world.browser = Browser('chrome') + # world.browser = Browser('chrome') + world.browser = Browser('phantomjs') # world.browser = Browser('firefox') -- GitLab