diff options
author | Tiago Ferraz <tiago.ferraz@gmail.com> | 2015-03-23 10:27:39 -0300 |
---|---|---|
committer | Tiago Ferraz <tiago.ferraz@gmail.com> | 2015-03-26 12:12:40 -0300 |
commit | aab5c4e3f721431591f3709cecb2e2e58ab9774e (patch) | |
tree | c9d46bb5378bf77c8b20dcb1adc798e0ce7b5b2c /service | |
parent | 68a0f94cd15b661caa2b4ea87eef55972c8bff25 (diff) |
New test that use checkboxes. Removal of hamcrest lib, code refactoring.
A new test was created to use Pixelated checkboxes and the buttons at
the top. Also the lib hamcrest was removed and code refactored to be
more pythonic. A new method after_step will log information in case of
step failures.
Diffstat (limited to 'service')
10 files changed, 151 insertions, 38 deletions
diff --git a/service/test/functional/features/checkboxes_and_mailboxes.feature b/service/test/functional/features/checkboxes_and_mailboxes.feature new file mode 100644 index 00000000..47ea806d --- /dev/null +++ b/service/test/functional/features/checkboxes_and_mailboxes.feature @@ -0,0 +1,31 @@ +# +# Copyright (c) 2014 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see <http://www.gnu.org/licenses/>. + +Feature: Checkboxes + As a user of Pixelated + I want to use checkboxes to manage my emails + So I can manage more than one email at once + + Scenario: User has a list of emails in each mailboxes that needs to be managed + Given I have a mail in my inbox + When I mark the first unread email as read + And I delete the email + When I select the tag 'trash' + Then the deleted mail is there + When I check all emails + And I delete them permanently + Then I should not see any email + diff --git a/service/test/functional/features/compose_save_draft_and_send.feature b/service/test/functional/features/compose_save_draft_and_send.feature index b24d4c51..c54d6a82 100644 --- a/service/test/functional/features/compose_save_draft_and_send.feature +++ b/service/test/functional/features/compose_save_draft_and_send.feature @@ -25,7 +25,9 @@ Feature: compose mail, save draft and send mail | Pixelated rocks! | You should definitely use it. Cheers, User. | And for the 'To' field I enter 'pixelated@friends.org' And I save the draft - When I open the saved draft and send it + When I select the tag 'drafts' + When I open the first mail in the mail list + And I send it Then I see that mail under the 'sent' tag When I open that mail Then I see that the subject reads 'Pixelated rocks!' diff --git a/service/test/functional/features/environment.py b/service/test/functional/features/environment.py index 5969120a..6ef48376 100644 --- a/service/test/functional/features/environment.py +++ b/service/test/functional/features/environment.py @@ -14,9 +14,10 @@ # You should have received a copy of the GNU Affero General Public License # along with Pixelated. If not, see <http://www.gnu.org/licenses/>. import logging +import uuid from test.support.dispatcher.proxy import Proxy -from test.support.integration import AppTestClient +from test.support.integration import AppTestClient, MailBuilder from selenium import webdriver from pixelated.resources.features_resource import FeaturesResource @@ -41,15 +42,22 @@ def before_feature(context, feature): # context.browser = webdriver.Firefox() context.browser = webdriver.PhantomJS() context.browser.set_window_size(1280, 1024) - context.browser.implicitly_wait(5) + context.browser.implicitly_wait(10) context.browser.set_page_load_timeout(60) # wait for data context.browser.get('http://localhost:8889/') +def after_step(context, step): + if step.status == 'failed': + id = str(uuid.uuid4()) + context.browser.save_screenshot('failed '+str(step.name)+'_'+id+".png") + save_source(context, 'failed '+str(step.name)+'_'+id+".html") + + def after_feature(context, feature): context.browser.quit() -def save_source(context): - with open('/tmp/source.html', 'w') as out: +def save_source(context, filename='/tmp/source.html'): + with open(filename, 'w') as out: out.write(context.browser.page_source.encode('utf8')) diff --git a/service/test/functional/features/steps/common.py b/service/test/functional/features/steps/common.py index 7848089b..ee2a6f9a 100644 --- a/service/test/functional/features/steps/common.py +++ b/service/test/functional/features/steps/common.py @@ -17,7 +17,8 @@ from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait from selenium.common.exceptions import TimeoutException -from hamcrest import * + +from test.support.integration import MailBuilder def wait_until_element_is_invisible_by_locator(context, locator_tuple, timeout=10): @@ -40,6 +41,12 @@ def wait_until_elements_are_visible_by_locator(context, locator_tuple, timeout=1 return context.browser.find_elements(locator_tuple[0], locator_tuple[1]) +def wait_until_elements_are_visible_by_xpath(context, locator_tuple, timeout=10): + wait = WebDriverWait(context.browser, timeout) + wait.until(EC.presence_of_all_elements_located(locator_tuple)) + return context.browser.find_elements(locator_tuple[0], locator_tuple[1]) + + def wait_until_element_is_visible_by_locator(context, locator_tuple, timeout=10): wait = WebDriverWait(context.browser, timeout) wait.until(EC.visibility_of_element_located(locator_tuple)) @@ -84,13 +91,17 @@ def find_elements_by_css_selector(context, css_selector): return wait_until_elements_are_visible_by_locator(context, (By.CSS_SELECTOR, css_selector)) +def find_elements_by_xpath(context, xpath): + return wait_until_elements_are_visible_by_xpath(context, (By.XPATH, xpath)) + + def find_element_containing_text(context, text, element_type='*'): return find_element_by_xpath(context, "//%s[contains(.,'%s')]" % (element_type, text)) def element_should_have_content(context, css_selector, content): e = find_element_by_css_selector(context, css_selector) - assert_that(e.text, equal_to(content)) + assert e.text == content def wait_until_button_is_visible(context, title, timeout=10): @@ -120,3 +131,8 @@ def get_console_log(context): msg = entry['message'] if not (msg.startswith('x off') or msg.startswith('<- on')): print entry['message'] + + +def create_email(context): + input_mail = MailBuilder().build_input_mail() + context.client.add_mail_to_inbox(input_mail)
\ No newline at end of file diff --git a/service/test/functional/features/steps/compose.py b/service/test/functional/features/steps/compose.py index aeef11c4..1f7f1eb7 100644 --- a/service/test/functional/features/steps/compose.py +++ b/service/test/functional/features/steps/compose.py @@ -15,9 +15,8 @@ # along with Pixelated. If not, see <http://www.gnu.org/licenses/>. from time import sleep -from behave import given, when, then +from behave import when from common import * -from hamcrest import * @when('I compose a message with') @@ -48,13 +47,11 @@ def save_impl(context): context.browser.find_element_by_id('draft-button').click() -@when('I open the saved draft and send it') +@when('I send it') def send_impl(context): - context.execute_steps(u"when I select the tag 'drafts'") - context.execute_steps(u"when I open the first mail in the mail list") - assert_that(is_not(page_has_css(context, '#send-button[disabled]'))) - click_button(context, 'Send') - wait_until_element_is_deleted(context, (By.ID, 'send-button'), timeout=120) + assert page_has_css(context, '#send-button[disabled]') is False + context.browser.find_element(By.ID, 'send-button').click() + # wait_until_element_is_deleted(context, (By.ID, 'send-button'), timeout=120) def _enter_recipient(context, recipients_field, to_type): diff --git a/service/test/functional/features/steps/mail_list.py b/service/test/functional/features/steps/mail_list.py index 4122f065..74bfe9f2 100644 --- a/service/test/functional/features/steps/mail_list.py +++ b/service/test/functional/features/steps/mail_list.py @@ -14,10 +14,13 @@ # You should have received a copy of the GNU Affero General Public License # along with Pixelated. If not, see <http://www.gnu.org/licenses/>. from common import * +from selenium.common.exceptions import NoSuchElementException +from time import sleep def find_current_mail(context): - return find_element_by_xpath(context, '//*[@id="mail-list"]/li[@id="mail-%s"]//a' % context.current_mail_id) + return find_element_by_id(context, '%s' % context.current_mail_id) + def check_current_mail_is_visible(context): @@ -25,6 +28,7 @@ def check_current_mail_is_visible(context): def open_current_mail(context): + sleep(2) e = find_current_mail(context) e.click() @@ -37,19 +41,20 @@ def impl(context, tag): @when('I open that mail') def impl(context): - open_current_mail(context) + # open_current_mail(context) + sleep(3) + find_current_mail(context).click() @when('I open the first mail in the mail list') def impl(context): - elements = wait_until_elements_are_visible_by_locator(context, (By.XPATH, '//*[@id="mail-list"]//a')) - context.current_mail_id = elements[0].get_attribute('href').split('/')[-1] - elements[0].click() + first_email = wait_until_elements_are_visible_by_locator(context, (By.XPATH, '//*[@id="mail-list"]//a'))[0] + context.current_mail_id = 'mail-' + first_email.get_attribute('href').split('/')[-1] + first_email.click() @when('I open the first mail in the \'{tag}\'') def impl(context, tag): - context.browser.execute_script('window.scrollBy(0, -200)') context.execute_steps(u"When I select the tag '%s'" % tag) context.execute_steps(u'When I open the first mail in the mail list') @@ -62,15 +67,62 @@ def impl(context): @then('I see the mail I sent') def impl(context): src = context.browser.page_source - assert_that(src, contains_string(context.reply_subject)) + assert context.reply_subject in src @then('the deleted mail is there') def impl(context): - check_current_mail_is_visible(context) + # wait_until_elements_are_visible_by_locator(context, (By.XPATH, '//*[@id="mail-list"]//a')) + find_current_mail(context) @given('I have mails') def impl(context): - elements = wait_until_elements_are_visible_by_locator(context, (By.XPATH, '//*[@id="mail-list"]//a')) - assert len(elements) > 0 + emails = wait_until_elements_are_visible_by_locator(context, (By.XPATH, '//*[@id="mail-list"]//a')) + assert len(emails) > 0 + + +@when('I mark the first unread email as read') +def impl(context): + emails = wait_until_elements_are_visible_by_locator(context, (By.XPATH, '//*[@id="mail-list"]//li')) + + for email in emails: + if 'status-read' not in email.get_attribute('class'): + email.find_element_by_tag_name('input').click() + find_element_by_id(context, 'mark-selected-as-read').click() + context.current_mail_id = email.get_attribute('id') + break + sleep(2) + assert 'status-read' in context.browser.find_element_by_id(context.current_mail_id).get_attribute('class') + + +@when('I delete the email') +def impl(context): + last_email = lambda: wait_until_elements_are_visible_by_locator(context, (By.XPATH, '//*[@id="mail-list"]//li'))[0] + context.current_mail_id = last_email().get_attribute('id') + last_email().find_element_by_tag_name('input').click() + find_element_by_id(context, 'delete-selected').click() + assert context.current_mail_id != find_elements_by_xpath(context, '//*[@id="mail-list"]//a')[0] + + +@when('I check all emails') +def impl(context): + find_element_by_id(context, 'toggle-check-all-emails').click() + +@when('I delete them permanently') +def impl(context): + find_element_by_id(context, 'delete-selected').click() + +@then('I should not see any email') +def impl(context): + try: + context.browser.find_element_by_xpath('//*[@id="mail-list"]//a') + except NoSuchElementException: + assert True + except: + assert False + + + + + diff --git a/service/test/functional/features/steps/mail_view.py b/service/test/functional/features/steps/mail_view.py index 98591aa4..5755f555 100644 --- a/service/test/functional/features/steps/mail_view.py +++ b/service/test/functional/features/steps/mail_view.py @@ -15,19 +15,18 @@ # along with Pixelated. If not, see <http://www.gnu.org/licenses/>. from selenium.webdriver.common.keys import Keys from common import * -from hamcrest import * @then('I see that the subject reads \'{subject}\'') def impl(context, subject): e = find_element_by_css_selector(context, '#mail-view .subject') - assert_that(e.text, equal_to(subject)) + assert e.text == subject @then('I see that the body reads \'{expected_body}\'') def impl(context, expected_body): e = find_element_by_css_selector(context, '#mail-view .bodyArea') - assert_that(e.text, equal_to(expected_body)) + assert e.text == expected_body @then('that email has the \'{tag}\' tag') @@ -35,7 +34,7 @@ def impl(context, tag): wait_until_element_is_visible_by_locator(context, (By.CSS, '#mail-view .tagsArea .tag')) elements = find_elements_by_css_selector(context, '#mail-view .tagsArea .tag') tags = [e.text for e in elements] - assert_that(tags, has_item(tag.upper())) + assert tag in tags @when('I add the tag \'{tag}\' to that mail') @@ -52,15 +51,15 @@ def impl(context, tag): @when('I reply to it') def impl(context): click_button(context, 'Reply') - click_button(context, 'Send') context.reply_subject = reply_subject(context) + click_button(context, 'Send') - +#NOT BEING USED @then('I see if the mail has html content') def impl(context): e = find_element_by_css_selector(context, '#mail-view .bodyArea') h2 = e.find_element_by_css_selector("h2[style*='color: #3f4944']") - assert_that(h2.text, contains_string('cborim')) + assert 'cborim' in h2.text @when('I try to delete the first mail') @@ -70,7 +69,7 @@ def impl(context): context.browser.execute_script("$('#delete-button-top').click();") e = find_element_by_css_selector(context, '#user-alerts') - assert_that(e.text, equal_to('Your message was moved to trash!')) + assert 'Your message was moved to trash!' == e.text @when('I choose to forward this mail') @@ -90,7 +89,7 @@ def impl(context): def impl(context): e = find_element_by_css_selector(context, '.tagsArea') tags = e.find_elements_by_css_selector('.tag') - assert_that(len(tags), greater_than(0)) + assert len(tags) > 0 for tag in tags: tag.click() @@ -106,4 +105,5 @@ def impl(context): cc = find_element_by_css_selector(context, '.msg-header .cc') bcc = find_element_by_css_selector(context, '.msg-header .bcc') - assert_that(cc.text, matches_regexp('[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+')) + assert cc is not None + assert bcc is not None diff --git a/service/test/functional/features/steps/search.py b/service/test/functional/features/steps/search.py index 8c410112..e653c3ed 100644 --- a/service/test/functional/features/steps/search.py +++ b/service/test/functional/features/steps/search.py @@ -17,7 +17,6 @@ from time import sleep from selenium.webdriver.common.keys import Keys from common import * -from hamcrest import * @when('I search for a mail with the words "{search_term}"') @@ -31,4 +30,4 @@ def impl(context, search_term): @then('I see one or more mails in the search results') def impl(context): lis = find_elements_by_css_selector(context, '#mail-list li') - assert_that(len(lis), greater_than_or_equal_to(1)) + assert len(lis) >= 1 diff --git a/service/test/functional/features/steps/tag_list.py b/service/test/functional/features/steps/tag_list.py index 348b121a..930b74d1 100644 --- a/service/test/functional/features/steps/tag_list.py +++ b/service/test/functional/features/steps/tag_list.py @@ -43,3 +43,12 @@ def impl(context, tag): e = find_element_by_id(context, 'tag-%s' % tag.lower()) e.click() + + +@when('I am in \'{tag}\'') +def impl(context, tag): + expand_side_nav(context) + + wait_until_element_is_visible_by_locator(context, (By.ID, 'tag-%s' % tag), 20) + e = find_element_by_id(context, 'tag-%s' % tag) + assert "selected" in e.get_attribute("class")
\ No newline at end of file diff --git a/service/test_requirements.txt b/service/test_requirements.txt index 5179330a..526c8495 100644 --- a/service/test_requirements.txt +++ b/service/test_requirements.txt @@ -1,4 +1,3 @@ -PyHamcrest==1.8.1 behave==1.2.4 selenium==2.44.0 mock==1.0.1 |