summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/test/functional/features/checkboxes_and_mailboxes.feature31
-rw-r--r--service/test/functional/features/compose_save_draft_and_send.feature4
-rw-r--r--service/test/functional/features/environment.py16
-rw-r--r--service/test/functional/features/steps/common.py20
-rw-r--r--service/test/functional/features/steps/compose.py13
-rw-r--r--service/test/functional/features/steps/mail_list.py72
-rw-r--r--service/test/functional/features/steps/mail_view.py20
-rw-r--r--service/test/functional/features/steps/search.py3
-rw-r--r--service/test/functional/features/steps/tag_list.py9
-rw-r--r--service/test_requirements.txt1
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