Commit e69931ec by Will Daly

Refactored studio lettuce tests to use terrain/ui_helpers for ui

manipulation
parent dde0d167
...@@ -2,8 +2,6 @@ from lettuce import world, step ...@@ -2,8 +2,6 @@ from lettuce import world, step
from common import * from common import *
import time import time
from terrain.steps import reload_the_page from terrain.steps import reload_the_page
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.support import expected_conditions as EC
from nose.tools import assert_true, assert_false, assert_equal from nose.tools import assert_true, assert_false, assert_equal
...@@ -22,9 +20,9 @@ DISPLAY_NAME_VALUE = '"Robot Super Course"' ...@@ -22,9 +20,9 @@ DISPLAY_NAME_VALUE = '"Robot Super Course"'
def i_select_advanced_settings(step): def i_select_advanced_settings(step):
expand_icon_css = 'li.nav-course-settings i.icon-expand' expand_icon_css = 'li.nav-course-settings i.icon-expand'
if world.browser.is_element_present_by_css(expand_icon_css): if world.browser.is_element_present_by_css(expand_icon_css):
css_click(expand_icon_css) world.css_click(expand_icon_css)
link_css = 'li.nav-course-settings-advanced a' link_css = 'li.nav-course-settings-advanced a'
css_click(link_css) world.css_click(link_css)
@step('I am on the Advanced Course Settings page in Studio$') @step('I am on the Advanced Course Settings page in Studio$')
...@@ -35,24 +33,8 @@ def i_am_on_advanced_course_settings(step): ...@@ -35,24 +33,8 @@ def i_am_on_advanced_course_settings(step):
@step(u'I press the "([^"]*)" notification button$') @step(u'I press the "([^"]*)" notification button$')
def press_the_notification_button(step, name): 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() css = 'a.%s-button' % name.lower()
wait_for(is_visible) world.css_click_at(css)
time.sleep(float(1))
css_click_at(css)
# is_invisible is not returning a boolean, not working
# try:
# css_click_at(css)
# wait_for(is_invisible)
# except WebDriverException, e:
# css_click_at(css)
# wait_for(is_invisible)
@step(u'I edit the value of a policy key$') @step(u'I edit the value of a policy key$')
...@@ -61,7 +43,7 @@ def edit_the_value_of_a_policy_key(step): ...@@ -61,7 +43,7 @@ def edit_the_value_of_a_policy_key(step):
It is hard to figure out how to get into the CodeMirror It is hard to figure out how to get into the CodeMirror
area, so cheat and do it from the policy key field :) area, so cheat and do it from the policy key field :)
""" """
e = css_find(KEY_CSS)[get_index_of(DISPLAY_NAME_KEY)] e = world.css_find(KEY_CSS)[get_index_of(DISPLAY_NAME_KEY)]
e._element.send_keys(Keys.TAB, Keys.END, Keys.ARROW_LEFT, ' ', 'X') e._element.send_keys(Keys.TAB, Keys.END, Keys.ARROW_LEFT, ' ', 'X')
...@@ -85,7 +67,7 @@ def i_see_default_advanced_settings(step): ...@@ -85,7 +67,7 @@ def i_see_default_advanced_settings(step):
@step('the settings are alphabetized$') @step('the settings are alphabetized$')
def they_are_alphabetized(step): def they_are_alphabetized(step):
key_elements = css_find(KEY_CSS) key_elements = world.css_find(KEY_CSS)
all_keys = [] all_keys = []
for key in key_elements: for key in key_elements:
all_keys.append(key.value) all_keys.append(key.value)
...@@ -118,13 +100,13 @@ def assert_policy_entries(expected_keys, expected_values): ...@@ -118,13 +100,13 @@ def assert_policy_entries(expected_keys, expected_values):
for counter in range(len(expected_keys)): for counter in range(len(expected_keys)):
index = get_index_of(expected_keys[counter]) index = get_index_of(expected_keys[counter])
assert_false(index == -1, "Could not find key: " + expected_keys[counter]) assert_false(index == -1, "Could not find key: " + expected_keys[counter])
assert_equal(expected_values[counter], css_find(VALUE_CSS)[index].value, "value is incorrect") assert_equal(expected_values[counter], world.css_find(VALUE_CSS)[index].value, "value is incorrect")
def get_index_of(expected_key): def get_index_of(expected_key):
for counter in range(len(css_find(KEY_CSS))): for counter in range(len(world.css_find(KEY_CSS))):
# Sometimes get stale reference if I hold on to the array of elements # Sometimes get stale reference if I hold on to the array of elements
key = css_find(KEY_CSS)[counter].value key = world.css_find(KEY_CSS)[counter].value
if key == expected_key: if key == expected_key:
return counter return counter
...@@ -133,14 +115,14 @@ def get_index_of(expected_key): ...@@ -133,14 +115,14 @@ def get_index_of(expected_key):
def get_display_name_value(): def get_display_name_value():
index = get_index_of(DISPLAY_NAME_KEY) index = get_index_of(DISPLAY_NAME_KEY)
return css_find(VALUE_CSS)[index].value return world.css_find(VALUE_CSS)[index].value
def change_display_name_value(step, new_value): def change_display_name_value(step, new_value):
e = css_find(KEY_CSS)[get_index_of(DISPLAY_NAME_KEY)] e = world.css_find(KEY_CSS)[get_index_of(DISPLAY_NAME_KEY)]
display_name = get_display_name_value() display_name = get_display_name_value()
for count in range(len(display_name)): for count in range(len(display_name)):
e._element.send_keys(Keys.TAB, Keys.END, Keys.BACK_SPACE) e._element.send_keys(Keys.TAB, Keys.END, Keys.BACK_SPACE)
# Must delete "" before typing the JSON value # Must delete "" before typing the JSON value
e._element.send_keys(Keys.TAB, Keys.END, Keys.BACK_SPACE, Keys.BACK_SPACE, new_value) e._element.send_keys(Keys.TAB, Keys.END, Keys.BACK_SPACE, Keys.BACK_SPACE, new_value)
press_the_notification_button(step, "Save") press_the_notification_button(step, "Save")
\ No newline at end of file
from lettuce import world, step from lettuce import world, step
from lettuce.django import django_url
from nose.tools import assert_true from nose.tools import assert_true
from nose.tools import assert_equal from nose.tools import assert_equal
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import WebDriverException, StaleElementReferenceException
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from xmodule.modulestore.django import _MODULESTORES, modulestore from xmodule.modulestore.django import _MODULESTORES, modulestore
from xmodule.templates import update_templates from xmodule.templates import update_templates
...@@ -20,9 +15,9 @@ def i_visit_the_studio_homepage(step): ...@@ -20,9 +15,9 @@ def i_visit_the_studio_homepage(step):
# To make this go to port 8001, put # To make this go to port 8001, put
# LETTUCE_SERVER_PORT = 8001 # LETTUCE_SERVER_PORT = 8001
# in your settings.py file. # in your settings.py file.
world.browser.visit(django_url('/')) world.visit('/')
signin_css = 'a.action-signin' signin_css = 'a.action-signin'
assert world.browser.is_element_present_by_css(signin_css, 10) assert world.is_css_present(signin_css)
@step('I am logged into Studio$') @step('I am logged into Studio$')
...@@ -43,7 +38,7 @@ def i_press_the_category_delete_icon(step, category): ...@@ -43,7 +38,7 @@ def i_press_the_category_delete_icon(step, category):
css = 'a.delete-button.delete-subsection-button span.delete-icon' css = 'a.delete-button.delete-subsection-button span.delete-icon'
else: else:
assert False, 'Invalid category: %s' % category assert False, 'Invalid category: %s' % category
css_click(css) world.css_click(css)
@step('I have opened a new course in Studio$') @step('I have opened a new course in Studio$')
...@@ -87,56 +82,6 @@ def flush_xmodule_store(): ...@@ -87,56 +82,6 @@ def flush_xmodule_store():
update_templates() update_templates()
def assert_css_with_text(css, text):
assert_true(world.browser.is_element_present_by_css(css, 5))
assert_equal(world.browser.find_by_css(css).text, text)
def css_click(css):
'''
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
'''
try:
css_find(css).first.click()
except WebDriverException, e:
css_click_at(css)
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
'''
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()
def css_fill(css, value):
world.browser.find_by_css(css).first.fill(value)
def css_find(css):
def is_visible(driver):
return EC.visibility_of_element_located((By.CSS_SELECTOR,css,))
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, 5).until(func)
def id_find(id):
return world.browser.find_by_id(id)
def clear_courses(): def clear_courses():
flush_xmodule_store() flush_xmodule_store()
...@@ -145,9 +90,9 @@ def fill_in_course_info( ...@@ -145,9 +90,9 @@ def fill_in_course_info(
name='Robot Super Course', name='Robot Super Course',
org='MITx', org='MITx',
num='101'): num='101'):
css_fill('.new-course-name', name) world.css_fill('.new-course-name', name)
css_fill('.new-course-org', org) world.css_fill('.new-course-org', org)
css_fill('.new-course-number', num) world.css_fill('.new-course-number', num)
def log_into_studio( def log_into_studio(
...@@ -155,21 +100,22 @@ def log_into_studio( ...@@ -155,21 +100,22 @@ def log_into_studio(
email='robot+studio@edx.org', email='robot+studio@edx.org',
password='test', password='test',
is_staff=False): is_staff=False):
create_studio_user(uname=uname, email=email, is_staff=is_staff) create_studio_user(uname=uname, email=email, is_staff=is_staff)
world.browser.cookies.delete() world.browser.cookies.delete()
world.browser.visit(django_url('/')) world.visit('/')
signin_css = 'a.action-signin'
world.browser.is_element_present_by_css(signin_css, 10)
# click the signin button signin_css = 'a.action-signin'
css_click(signin_css) world.is_css_present(signin_css)
world.css_click(signin_css)
login_form = world.browser.find_by_css('form#login_form') login_form = world.browser.find_by_css('form#login_form')
login_form.find_by_name('email').fill(email) login_form.find_by_name('email').fill(email)
login_form.find_by_name('password').fill(password) login_form.find_by_name('password').fill(password)
login_form.find_by_name('submit').click() login_form.find_by_name('submit').click()
assert_true(world.browser.is_element_present_by_css('.new-course-button', 5)) assert_true(world.is_css_present('.new-course-button'))
def create_a_course(): def create_a_course():
...@@ -184,26 +130,26 @@ def create_a_course(): ...@@ -184,26 +130,26 @@ def create_a_course():
world.browser.reload() world.browser.reload()
course_link_css = 'span.class-name' course_link_css = 'span.class-name'
css_click(course_link_css) world.css_click(course_link_css)
course_title_css = 'span.course-title' course_title_css = 'span.course-title'
assert_true(world.browser.is_element_present_by_css(course_title_css, 5)) assert_true(world.is_css_present(course_title_css))
def add_section(name='My Section'): def add_section(name='My Section'):
link_css = 'a.new-courseware-section-button' link_css = 'a.new-courseware-section-button'
css_click(link_css) world.css_click(link_css)
name_css = 'input.new-section-name' name_css = 'input.new-section-name'
save_css = 'input.new-section-name-save' save_css = 'input.new-section-name-save'
css_fill(name_css, name) world.css_fill(name_css, name)
css_click(save_css) world.css_click(save_css)
span_css = 'span.section-name-span' span_css = 'span.section-name-span'
assert_true(world.browser.is_element_present_by_css(span_css, 5)) assert_true(world.is_css_present(span_css))
def add_subsection(name='Subsection One'): def add_subsection(name='Subsection One'):
css = 'a.new-subsection-item' css = 'a.new-subsection-item'
css_click(css) world.css_click(css)
name_css = 'input.new-subsection-name-input' name_css = 'input.new-subsection-name-input'
save_css = 'input.new-subsection-name-save' save_css = 'input.new-subsection-name-save'
css_fill(name_css, name) world.css_fill(name_css, name)
css_click(save_css) world.css_click(save_css)
...@@ -11,7 +11,7 @@ def no_courses(step): ...@@ -11,7 +11,7 @@ def no_courses(step):
@step('I click the New Course button$') @step('I click the New Course button$')
def i_click_new_course(step): def i_click_new_course(step):
css_click('.new-course-button') world.css_click('.new-course-button')
@step('I fill in the new course information$') @step('I fill in the new course information$')
...@@ -27,7 +27,7 @@ def i_create_a_course(step): ...@@ -27,7 +27,7 @@ def i_create_a_course(step):
@step('I click the course link in My Courses$') @step('I click the course link in My Courses$')
def i_click_the_course_link_in_my_courses(step): def i_click_the_course_link_in_my_courses(step):
course_css = 'span.class-name' course_css = 'span.class-name'
css_click(course_css) world.css_click(course_css)
############ ASSERTIONS ################### ############ ASSERTIONS ###################
...@@ -35,28 +35,27 @@ def i_click_the_course_link_in_my_courses(step): ...@@ -35,28 +35,27 @@ def i_click_the_course_link_in_my_courses(step):
@step('the Courseware page has loaded in Studio$') @step('the Courseware page has loaded in Studio$')
def courseware_page_has_loaded_in_studio(step): def courseware_page_has_loaded_in_studio(step):
course_title_css = 'span.course-title' course_title_css = 'span.course-title'
assert world.browser.is_element_present_by_css(course_title_css) assert world.is_css_present(course_title_css)
@step('I see the course listed in My Courses$') @step('I see the course listed in My Courses$')
def i_see_the_course_in_my_courses(step): def i_see_the_course_in_my_courses(step):
course_css = 'span.class-name' course_css = 'span.class-name'
assert_css_with_text(course_css, 'Robot Super Course') assert world.css_has_text(course_css, 'Robot Super Course')
@step('the course is loaded$') @step('the course is loaded$')
def course_is_loaded(step): def course_is_loaded(step):
class_css = 'a.class-name' class_css = 'a.class-name'
assert_css_with_text(class_css, 'Robot Super Course') assert world.css_has_text(course_css, 'Robot Super Cousre')
@step('I am on the "([^"]*)" tab$') @step('I am on the "([^"]*)" tab$')
def i_am_on_tab(step, tab_name): def i_am_on_tab(step, tab_name):
header_css = 'div.inner-wrapper h1' header_css = 'div.inner-wrapper h1'
assert_css_with_text(header_css, tab_name) assert world.css_has_text(header_css, tab_name)
@step('I see a link for adding a new section$') @step('I see a link for adding a new section$')
def i_see_new_section_link(step): def i_see_new_section_link(step):
link_css = 'a.new-courseware-section-button' link_css = 'a.new-courseware-section-button'
assert_css_with_text(link_css, '+ New Section') assert world.css_has_text(link_css, '+ New Section')
...@@ -10,7 +10,7 @@ import time ...@@ -10,7 +10,7 @@ import time
@step('I click the new section link$') @step('I click the new section link$')
def i_click_new_section_link(step): def i_click_new_section_link(step):
link_css = 'a.new-courseware-section-button' link_css = 'a.new-courseware-section-button'
css_click(link_css) world.css_click(link_css)
@step('I enter the section name and click save$') @step('I enter the section name and click save$')
...@@ -31,19 +31,19 @@ def i_have_added_new_section(step): ...@@ -31,19 +31,19 @@ def i_have_added_new_section(step):
@step('I click the Edit link for the release date$') @step('I click the Edit link for the release date$')
def i_click_the_edit_link_for_the_release_date(step): def i_click_the_edit_link_for_the_release_date(step):
button_css = 'div.section-published-date a.edit-button' button_css = 'div.section-published-date a.edit-button'
css_click(button_css) world.css_click(button_css)
@step('I save a new section release date$') @step('I save a new section release date$')
def i_save_a_new_section_release_date(step): def i_save_a_new_section_release_date(step):
date_css = 'input.start-date.date.hasDatepicker' date_css = 'input.start-date.date.hasDatepicker'
time_css = 'input.start-time.time.ui-timepicker-input' time_css = 'input.start-time.time.ui-timepicker-input'
css_fill(date_css, '12/25/2013') world.css_fill(date_css, '12/25/2013')
# hit TAB to get to the time field # hit TAB to get to the time field
e = css_find(date_css).first e = world.css_find(date_css).first
e._element.send_keys(Keys.TAB) e._element.send_keys(Keys.TAB)
css_fill(time_css, '12:00am') world.css_fill(time_css, '12:00am')
e = css_find(time_css).first e = world.css_find(time_css).first
e._element.send_keys(Keys.TAB) e._element.send_keys(Keys.TAB)
time.sleep(float(1)) time.sleep(float(1))
world.browser.click_link_by_text('Save') world.browser.click_link_by_text('Save')
...@@ -64,13 +64,13 @@ def i_see_my_section_name_with_quote_on_the_courseware_page(step): ...@@ -64,13 +64,13 @@ def i_see_my_section_name_with_quote_on_the_courseware_page(step):
@step('I click to edit the section name$') @step('I click to edit the section name$')
def i_click_to_edit_section_name(step): def i_click_to_edit_section_name(step):
css_click('span.section-name-span') world.css_click('span.section-name-span')
@step('I see the complete section name with a quote in the editor$') @step('I see the complete section name with a quote in the editor$')
def i_see_complete_section_name_with_quote_in_editor(step): def i_see_complete_section_name_with_quote_in_editor(step):
css = '.edit-section-name' css = '.edit-section-name'
assert world.browser.is_element_present_by_css(css, 5) assert world.is_css_present(css)
assert_equal(world.browser.find_by_css(css).value, 'Section with "Quote"') assert_equal(world.browser.find_by_css(css).value, 'Section with "Quote"')
...@@ -85,7 +85,7 @@ def i_see_a_release_date_for_my_section(step): ...@@ -85,7 +85,7 @@ def i_see_a_release_date_for_my_section(step):
import re import re
css = 'span.published-status' css = 'span.published-status'
assert world.browser.is_element_present_by_css(css) assert world.is_css_present(css)
status_text = world.browser.find_by_css(css).text status_text = world.browser.find_by_css(css).text
# e.g. 11/06/2012 at 16:25 # e.g. 11/06/2012 at 16:25
...@@ -99,7 +99,7 @@ def i_see_a_release_date_for_my_section(step): ...@@ -99,7 +99,7 @@ def i_see_a_release_date_for_my_section(step):
@step('I see a link to create a new subsection$') @step('I see a link to create a new subsection$')
def i_see_a_link_to_create_a_new_subsection(step): def i_see_a_link_to_create_a_new_subsection(step):
css = 'a.new-subsection-item' css = 'a.new-subsection-item'
assert world.browser.is_element_present_by_css(css) assert world.is_css_present(css)
@step('the section release date picker is not visible$') @step('the section release date picker is not visible$')
...@@ -120,10 +120,10 @@ def the_section_release_date_is_updated(step): ...@@ -120,10 +120,10 @@ def the_section_release_date_is_updated(step):
def save_section_name(name): def save_section_name(name):
name_css = '.new-section-name' name_css = '.new-section-name'
save_css = '.new-section-name-save' save_css = '.new-section-name-save'
css_fill(name_css, name) world.css_fill(name_css, name)
css_click(save_css) world.css_click(save_css)
def see_my_section_on_the_courseware_page(name): def see_my_section_on_the_courseware_page(name):
section_css = 'span.section-name-span' section_css = 'span.section-name-span'
assert_css_with_text(section_css, name) assert world.css_has_text(section_css, name)
...@@ -17,7 +17,7 @@ def i_press_the_button_on_the_registration_form(step): ...@@ -17,7 +17,7 @@ def i_press_the_button_on_the_registration_form(step):
submit_css = 'form#register_form button#submit' submit_css = 'form#register_form button#submit'
# Workaround for click not working on ubuntu # Workaround for click not working on ubuntu
# for some unknown reason. # for some unknown reason.
e = css_find(submit_css) e = world.css_find(submit_css)
e.type(' ') e.type(' ')
@step('I should see be on the studio home page$') @step('I should see be on the studio home page$')
......
...@@ -49,7 +49,7 @@ def have_a_course_with_two_sections(step): ...@@ -49,7 +49,7 @@ def have_a_course_with_two_sections(step):
def navigate_to_the_course_overview_page(step): def navigate_to_the_course_overview_page(step):
log_into_studio(is_staff=True) log_into_studio(is_staff=True)
course_locator = '.class-name' course_locator = '.class-name'
css_click(course_locator) world.css_click(course_locator)
@step(u'I navigate to the courseware page of a course with multiple sections') @step(u'I navigate to the courseware page of a course with multiple sections')
...@@ -66,44 +66,44 @@ def i_add_a_section(step): ...@@ -66,44 +66,44 @@ def i_add_a_section(step):
@step(u'I click the "([^"]*)" link$') @step(u'I click the "([^"]*)" link$')
def i_click_the_text_span(step, text): def i_click_the_text_span(step, text):
span_locator = '.toggle-button-sections span' span_locator = '.toggle-button-sections span'
assert_true(world.browser.is_element_present_by_css(span_locator, 5)) assert_true(world.browser.is_element_present_by_css(span_locator))
# first make sure that the expand/collapse text is the one you expected # first make sure that the expand/collapse text is the one you expected
assert_equal(world.browser.find_by_css(span_locator).value, text) assert_equal(world.browser.find_by_css(span_locator).value, text)
css_click(span_locator) world.css_click(span_locator)
@step(u'I collapse the first section$') @step(u'I collapse the first section$')
def i_collapse_a_section(step): def i_collapse_a_section(step):
collapse_locator = 'section.courseware-section a.collapse' collapse_locator = 'section.courseware-section a.collapse'
css_click(collapse_locator) world.css_click(collapse_locator)
@step(u'I expand the first section$') @step(u'I expand the first section$')
def i_expand_a_section(step): def i_expand_a_section(step):
expand_locator = 'section.courseware-section a.expand' expand_locator = 'section.courseware-section a.expand'
css_click(expand_locator) world.css_click(expand_locator)
@step(u'I see the "([^"]*)" link$') @step(u'I see the "([^"]*)" link$')
def i_see_the_span_with_text(step, text): def i_see_the_span_with_text(step, text):
span_locator = '.toggle-button-sections span' span_locator = '.toggle-button-sections span'
assert_true(world.browser.is_element_present_by_css(span_locator, 5)) assert_true(world.is_css_present(span_locator))
assert_equal(world.browser.find_by_css(span_locator).value, text) assert_equal(world.css_find(span_locator).value, text)
assert_true(world.browser.find_by_css(span_locator).visible) assert_true(world.css_visible(span_locator))
@step(u'I do not see the "([^"]*)" link$') @step(u'I do not see the "([^"]*)" link$')
def i_do_not_see_the_span_with_text(step, text): def i_do_not_see_the_span_with_text(step, text):
# Note that the span will exist on the page but not be visible # Note that the span will exist on the page but not be visible
span_locator = '.toggle-button-sections span' span_locator = '.toggle-button-sections span'
assert_true(world.browser.is_element_present_by_css(span_locator)) assert_true(world.is_css_present(span_locator))
assert_false(world.browser.find_by_css(span_locator).visible) assert_false(world.css_visible(span_locator))
@step(u'all sections are expanded$') @step(u'all sections are expanded$')
def all_sections_are_expanded(step): def all_sections_are_expanded(step):
subsection_locator = 'div.subsection-list' subsection_locator = 'div.subsection-list'
subsections = world.browser.find_by_css(subsection_locator) subsections = world.css_find(subsection_locator)
for s in subsections: for s in subsections:
assert_true(s.visible) assert_true(s.visible)
...@@ -111,6 +111,6 @@ def all_sections_are_expanded(step): ...@@ -111,6 +111,6 @@ def all_sections_are_expanded(step):
@step(u'all sections are collapsed$') @step(u'all sections are collapsed$')
def all_sections_are_expanded(step): def all_sections_are_expanded(step):
subsection_locator = 'div.subsection-list' subsection_locator = 'div.subsection-list'
subsections = world.browser.find_by_css(subsection_locator) subsections = world.css_find(subsection_locator)
for s in subsections: for s in subsections:
assert_false(s.visible) assert_false(s.visible)
...@@ -15,8 +15,7 @@ def i_have_opened_a_new_course_section(step): ...@@ -15,8 +15,7 @@ def i_have_opened_a_new_course_section(step):
@step('I click the New Subsection link') @step('I click the New Subsection link')
def i_click_the_new_subsection_link(step): def i_click_the_new_subsection_link(step):
css = 'a.new-subsection-item' world.css_click('a.new-subsection-item')
css_click(css)
@step('I enter the subsection name and click save$') @step('I enter the subsection name and click save$')
...@@ -31,13 +30,13 @@ def i_save_subsection_name_with_quote(step): ...@@ -31,13 +30,13 @@ def i_save_subsection_name_with_quote(step):
@step('I click to edit the subsection name$') @step('I click to edit the subsection name$')
def i_click_to_edit_subsection_name(step): def i_click_to_edit_subsection_name(step):
css_click('span.subsection-name-value') world.css_click('span.subsection-name-value')
@step('I see the complete subsection name with a quote in the editor$') @step('I see the complete subsection name with a quote in the editor$')
def i_see_complete_subsection_name_with_quote_in_editor(step): def i_see_complete_subsection_name_with_quote_in_editor(step):
css = '.subsection-display-name-input' css = '.subsection-display-name-input'
assert world.browser.is_element_present_by_css(css, 5) assert world.is_css_present(css)
assert_equal(world.browser.find_by_css(css).value, 'Subsection With "Quote"') assert_equal(world.browser.find_by_css(css).value, 'Subsection With "Quote"')
...@@ -70,11 +69,11 @@ def the_subsection_does_not_exist(step): ...@@ -70,11 +69,11 @@ def the_subsection_does_not_exist(step):
def save_subsection_name(name): def save_subsection_name(name):
name_css = 'input.new-subsection-name-input' name_css = 'input.new-subsection-name-input'
save_css = 'input.new-subsection-name-save' save_css = 'input.new-subsection-name-save'
css_fill(name_css, name) world.css_fill(name_css, name)
css_click(save_css) world.css_click(save_css)
def see_subsection_name(name): def see_subsection_name(name):
css = 'span.subsection-name' css = 'span.subsection-name'
assert world.browser.is_element_present_by_css(css) assert world.is_css_present(css)
css = 'span.subsection-name-value' css = 'span.subsection-name-value'
assert_css_with_text(css, name) assert world.css_has_text(css, name)
...@@ -2,6 +2,9 @@ from lettuce import world, step ...@@ -2,6 +2,9 @@ from lettuce import world, step
import time import time
from urllib import quote_plus from urllib import quote_plus
from selenium.common.exceptions import WebDriverException from selenium.common.exceptions import WebDriverException
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from lettuce.django import django_url from lettuce.django import django_url
...@@ -9,6 +12,9 @@ from lettuce.django import django_url ...@@ -9,6 +12,9 @@ from lettuce.django import django_url
def wait(seconds): def wait(seconds):
time.sleep(float(seconds)) time.sleep(float(seconds))
@world.absorb
def wait_for(func):
WebDriverWait(world.browser.driver, 5).until(func)
@world.absorb @world.absorb
def visit(url): def visit(url):
...@@ -24,9 +30,27 @@ def url_equals(url): ...@@ -24,9 +30,27 @@ def url_equals(url):
def is_css_present(css_selector): def is_css_present(css_selector):
return world.browser.is_element_present_by_css(css_selector, wait_time=4) return world.browser.is_element_present_by_css(css_selector, wait_time=4)
@world.absorb
def css_has_text(css_selector, text):
return world.css_text(css_selector) == text
@world.absorb
def css_find(css):
def is_visible(driver):
return EC.visibility_of_element_located((By.CSS_SELECTOR,css,))
world.browser.is_element_present_by_css(css, 5)
wait_for(is_visible)
return world.browser.find_by_css(css)
@world.absorb @world.absorb
def css_click(css_selector): def css_click(css_selector):
'''
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
'''
try: try:
world.browser.find_by_css(css_selector).click() world.browser.find_by_css(css_selector).click()
...@@ -37,6 +61,16 @@ def css_click(css_selector): ...@@ -37,6 +61,16 @@ def css_click(css_selector):
time.sleep(1) time.sleep(1)
world.browser.find_by_css(css_selector).click() world.browser.find_by_css(css_selector).click()
@world.absorb
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
'''
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()
@world.absorb @world.absorb
def css_fill(css_selector, text): def css_fill(css_selector, text):
......
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