Commit a13f4533 authored by Vadim Rutkovsky's avatar Vadim Rutkovsky

tests: add addressbook tests

parent fdde3339
......@@ -150,8 +150,9 @@ DISTCHECK_CONFIGURE_FLAGS = \
--with-help
@BEHAVE_INSTALLED_TESTS_RULE@
INSTALLED_TESTS=general_shortcuts mail_shortcuts contacts_shortcuts \
calendar_shortcuts memos_shortcuts view_shortcuts menu_shortcuts
INSTALLED_TESTS=general_shortcuts mail_shortcuts contacts_shortcuts \
calendar_shortcuts memos_shortcuts view_shortcuts menu_shortcuts \
addressbook_contacts
INSTALLED_TESTS_TYPE=session-exclusive
-include $(top_srcdir)/git.mk
Feature: Addressbook: File: Create contacts
Background:
* Open Evolution and setup fake account
* Open "Contacts" section
* Select "Personal" addressbook
* Change categories view to "Any Category"
* Delete all contacts containing "Doe"
@addressbook_contacts
Scenario: Create a simple contact
* Create a new contact
* Set "Full Name..." in contact editor to "John Doe"
* Save the contact
* Refresh addressbook
* Select "Doe, John" contact
* Open contact editor for selected contact
Then "Full Name..." property is set to "John Doe"
@addressbook_contacts
Scenario: Create a contact with full data
* Create a new contact
* Set "Full Name..." in contact editor to "Jimmy Doe"
* Set "Nickname:" in contact editor to "Unknown"
* Set emails in contact editor to
| Field | Value |
| Work | jimmy.doe@company.com |
| Home | jimmy_doe_72@gmail.com |
| Other | jimmydoe72@yahoo.com |
| Other | xxjimmyxx@free_email.com |
* Tick "Wants to receive HTML mail" checkbox
* Set phones in contact editor to
| Field | Value |
| Assistant Phone | 123 |
| Business Phone | 234 |
| Business Fax | 345 |
| Callback Phone | 456 |
| Car Phone | 567 |
| Company Phone | 678 |
| Home Phone | 789 |
| Home Fax | 890 |
* Set IMs in contact editor to
| Field | Value |
| AIM | 123 |
| Jabber | 234 |
| Yahoo | 345 |
| Gadu-Gadu | 456 |
* Switch to "Personal Information" tab in contact editor
* Set the following properties in contact editor
| Field | Value |
| Home Page: | http://anna-doe.com |
| Blog: | http://blog.anna-doe.com |
| Calendar: | caldav://anna-doe.com/calendar.ics |
| Free/Busy: | http://anna-doe.com/free-busy |
| Video Chat: | http://anna-doe.com/video-chat |
| Profession: | QA Engineer |
| Title: | Dr. |
| Company: | Something Ltd. |
| Department: | Desktop QA |
| Manager: | John Doe |
| Assistant: | Anna Doe |
| Office: | 221b |
| Spouse: | Jack Doe |
* Switch to "Mailing Address" tab in contact editor
* Set the following properties in "Home" section of contact editor
| Field | Value |
| City: | Brno |
| Zip/Postal Code: | 61245 |
| State/Province: | Brno-Kralovo Pole |
| Country: | Czech Republic |
| PO Box: | 123456 |
| Address: | Purkynova 99/71 |
* Set the following properties in "Work" section of contact editor
| Field | Value |
| City: | Brno |
| Zip/Postal Code: | 61245 |
| State/Province: | Brno-Kralovo Pole |
| Country: | Czech Republic |
| PO Box: | 123456 |
| Address: | Purkynova 99/71 |
* Set the following properties in "Other" section of contact editor
| Field | Value |
| City: | Brno |
| Zip/Postal Code: | 61245 |
| State/Province: | Brno-Kralovo Pole |
| Country: | Czech Republic |
| PO Box: | 123456 |
| Address: | Purkynova 99/71 |
* Switch to "Notes" tab in contact editor
* Set the following note for the contact:
"""
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed dignissim gravida elit, nec facilisis augue commodo quis.
Sed ac metus quis tellus aliquet posuere non quis elit. Quisque non ante congue urna blandit accumsan.
In vitae ligula risus. Nunc venenatis leo vel leo facilisis porta. Nam sed magna urna, venenatis.
"""
* Refresh addressbook
* Select "Doe, Jimmy" contact
* Open contact editor for selected contact
Then "Nickname:" property is set to "Unknown"
And Emails are set to
| Field | Value |
| Work | jimmy.doe@company.com |
| Home | jimmy_doe_72@gmail.com |
| Other | jimmydoe72@yahoo.com |
| Other | xxjimmyxx@free_email.com |
And "Wants to receive HTML mail" checkbox is ticked
And Phones are set to
| Field | Value |
| Assistant Phone | 123 |
| Business Phone | 234 |
| Business Fax | 345 |
| Callback Phone | 456 |
| Car Phone | 567 |
| Company Phone | 678 |
| Home Phone | 789 |
| Home Fax | 890 |
And IMs are set to
| Field | Value |
| AIM | 123 |
| Jabber | 234 |
| Yahoo | 345 |
| Gadu-Gadu | 456 |
* Switch to "Personal Information" tab in contact editor
Then The following properties in contact editor are set
| Field | Value |
| Home Page: | http://anna-doe.com |
| Blog: | http://blog.anna-doe.com |
| Calendar: | caldav://anna-doe.com/calendar.ics |
| Free/Busy: | http://anna-doe.com/free-busy |
| Video Chat: | http://anna-doe.com/video-chat |
| Field | Value |
| Profession: | QA Engineer |
| Title: | Dr. |
| Company: | Something Ltd. |
| Department: | Desktop QA |
| Manager: | John Doe |
| Assistant: | Anna Doe |
| Office: | 221b |
| Spouse: | Jack Doe |
* Switch to "Mailing Address" tab in contact editor
Then The following properties in "Home" section of contact editor are set
| Field | Value |
| City: | Brno |
| Zip/Postal Code: | 61245 |
| State/Province: | Brno-Kralovo Pole |
| Country: | Czech Republic |
| PO Box: | 123456 |
| Address: | Purkynova 99/71 |
And The following properties in "Work" section of contact editor are set
| Field | Value |
| City: | Brno |
| Zip/Postal Code: | 61245 |
| State/Province: | Brno-Kralovo Pole |
| Country: | Czech Republic |
| PO Box: | 123456 |
| Address: | Purkynova 99/71 |
And The following properties in "Other" section of contact editor are set
| Field | Value |
| City: | Brno |
| Zip/Postal Code: | 61245 |
| State/Province: | Brno-Kralovo Pole |
| Country: | Czech Republic |
| PO Box: | 123456 |
| Address: | Purkynova 99/71 |
* Switch to "Notes" tab in contact editor
Then The following note is set for the contact:
"""
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed dignissim gravida elit, nec facilisis augue commodo quis.
Sed ac metus quis tellus aliquet posuere non quis elit. Quisque non ante congue urna blandit accumsan.
In vitae ligula risus. Nunc venenatis leo vel leo facilisis porta. Nam sed magna urna, venenatis.
"""
@addressbook_contacts
Scenario: Create a contact with different "file under" field
* Create a new contact
* Set "Full Name..." in contact editor to "Jackie Doe"
* Set "File under:" in contact editor to "Jackie Doe"
* Save the contact
* Refresh addressbook
* Select "Jackie Doe" contact
* Open contact editor for selected contact
Then "Full Name..." property is set to "Jackie Doe"
@addressbook_contacts
Scenario: Create a contact with all phones and IM set (part 2)
* Create a new contact
* Set "Full Name..." in contact editor to "Kevin Doe"
* Set IMs in contact editor to
| Field | Value |
| MSN | 123 |
| ICQ | 234 |
| GroupWise | 345 |
| Skype | 456 |
* Set phones in contact editor to
| Field | Value |
| ISDN | 123 |
| Mobile Phone | 234 |
| Other Phone | 345 |
| Other Fax | 456 |
| Pager | 567 |
| Primary Phone | 678 |
| Radio | 789 |
| Telex | 890 |
* Save the contact
* Refresh addressbook
* Select "Doe, Kevin" contact
* Open contact editor for selected contact
Then Phones are set to
| Field | Value |
| ISDN | 123 |
| Mobile Phone | 234 |
| Other Phone | 345 |
| Other Fax | 456 |
| Pager | 567 |
| Primary Phone | 678 |
| Radio | 789 |
| Telex | 890 |
And IMs are set to
| Field | Value |
| MSN | 123 |
| ICQ | 234 |
| GroupWise | 345 |
| Skype | 456 |
@addressbook_contacts
Scenario: Create a contact with all IM set (part 2)
* Create a new contact
* Set "Full Name..." in contact editor to "Mary Doe"
* Set IMs in contact editor to
| Field | Value |
| Twitter | 123 |
| ICQ | 234 |
| Jabber | 345 |
| Skype | 456 |
* Save the contact
* Refresh addressbook
* Select "Doe, Mary" contact
* Open contact editor for selected contact
Then IMs are set to
| Field | Value |
| Twitter | 123 |
| ICQ | 234 |
| Jabber | 345 |
| Skype | 456 |
......@@ -16,6 +16,9 @@ def before_all(context):
"""
try:
# Close running evo instances
os.system("evolution --force-shutdown > /dev/null")
# Skip dogtail actions to print to stdout
config.logDebugToStdOut = False
config.typingDelay = 0.2
......
# -*- coding: UTF-8 -*-
from behave import step, then
from common_steps import wait_until
from dogtail.predicate import GenericPredicate
from dogtail.rawinput import keyCombo
from time import time, sleep
from gi.repository import GLib
import pyatspi
@step(u'Select "{name}" addressbook')
def select_addressbook(context, name, password=None):
cells = context.app.findChildren(
GenericPredicate(name=name, roleName='table cell'))
visible_cells = filter(lambda x: x.showing, cells)
if visible_cells == []:
raise RuntimeError("Cannot find addressbook '%s'" % name)
visible_cells[0].click()
# Wait for addressbook to load
try:
spinner = context.app.findChild(
GenericPredicate(name='Spinner'), retry=False, requireResult=False)
if spinner:
start_time = time()
while spinner.showing:
sleep(1)
if (time() - start_time) > 180:
raise RuntimeError("Contacts take too long to synchronize")
except (GLib.GError, TypeError):
pass
@step(u'Change categories view to "{category}"')
def change_categories_view(context, category):
labels = context.app.findChildren(
lambda x: x.labeller.name == 'Show:' and x.showing)
if labels == []:
raise RuntimeError("Cannot find category switcher")
labels[0].combovalue = category
@step(u'Delete selected contact')
def delete_selected_contact(context):
context.app.menu('Edit').click()
mnu = context.app.menu('Edit').menuItem("Delete Contact")
if pyatspi.STATE_ENABLED in mnu.getState().getStates():
context.app.menu('Edit').menuItem("Delete Contact").click()
alert = context.app.child(roleName='alert', name='Question')
alert.button('Delete').click()
context.execute_steps(u"* Wait for email to synchronize")
@step(u'Delete all contacts containing "{part}"')
def delete_all_contacts_containing(context, part):
context.app.search_bar.grab_focus()
for attempts in range(0, 10):
try:
context.app.search_bar.text = part
break
except (GLib.GError, AttributeError):
sleep(0.1)
continue
keyCombo("<Enter>")
context.execute_steps(u"* Wait for email to synchronize")
context.app.search_bar.grab_focus()
keyCombo("<Tab>")
sleep(3)
heading = context.app.findChild(
GenericPredicate(roleName='heading'),
retry=False, requireResult=False)
if heading:
keyCombo("<Control>a")
context.execute_steps(u"* Delete selected contact")
sleep(3)
@step(u'Create a new contact')
def create_a_new_contact(context):
context.app.menu('File').click()
context.app.menu('File').menu('New').point()
context.app.menu('File').menu('New').menuItem("Contact").click()
context.execute_steps(u"Then Contact editor window is opened")
def get_element_by_name(contact_editor, name, section=None):
"""Get a field object by name in section (if specified)"""
element = None
if section:
panel = contact_editor.findChild(
GenericPredicate(roleName='panel', name=section), retry=False, requireResult=False)
if not panel:
# Other section is not a panel, but a toggle button
panel = contact_editor.child(roleName='toggle button', name=section)
element = panel.childLabelled(name)
else:
label = contact_editor.findChild(
GenericPredicate(label=name), retry=False, requireResult=False)
if not label:
# In case childLabelled is missing
# Find a filler with this name and get its text child
element = contact_editor.child(
roleName='filler', name=name).child(roleName='text')
else:
element = contact_editor.childLabelled(name)
if element:
return element
else:
raise RuntimeError("Cannot find element named '%s' in section '%s'" % (
name, section))
@step(u'Set "{field_name}" in contact editor to "{field_value}"')
def set_field_to_value(context, field_name, field_value):
element = get_element_by_name(context.app.contact_editor, field_name)
if element.roleName == "text":
element.text = field_value
elif element.roleName == "combo box":
if element.combovalue != field_value:
element.combovalue = field_value
@step(u'Save the contact')
def save_contact(context):
context.app.contact_editor.button('Save').click()
assert wait_until(lambda x: x.dead, context.app.contact_editor),\
"Contact Editor was not closed"
context.app.contact_editor = None
@step(u'Refresh addressbook')
def refresh_addressbook(context):
#Clear the search
icons = context.app.search_bar.findChildren(lambda x: x.roleName == 'icon')
if icons != []:
icons[-1].click()
else:
for attempts in range(0, 10):
try:
context.app.search_bar.text = ''
break
except (GLib.GError, AttributeError):
sleep(0.1)
continue
context.app.search_bar.grab_focus()
keyCombo('<Enter>')
context.execute_steps(u"* Wait for email to synchronize")
@step(u'Select "{contact_name}" contact list')
@step(u'Select "{contact_name}" contact')
def select_contact_with_name(context, contact_name):
# heading shows the name of currently selected contact
# We have to keep on pressing Tab to select the next contact
# Until we meet the first contact
# WARNING - what if we will have two identical contacts?
fail = False
selected_contact = None
# HACK
# To make the contact table appear
# we need to focus on search window
# and send Tabs to have the first contact focused
context.app.search_bar.grab_focus()
sleep(0.1)
# Switch to 'Any field contains' (not reachable in 3.6)
icons = context.app.search_bar.findChildren(GenericPredicate(roleName='icon'))
if icons != []:
icons[0].click()
wait_until(lambda x: x.findChildren(
GenericPredicate(roleName='check menu item', name='Any field contains')) != [],
context.app)
context.app.menuItem('Any field contains').click()
for attempts in range(0, 10):
try:
context.app.search_bar.text = contact_name
break
except (GLib.GError, AttributeError):
sleep(0.1)
continue
keyCombo("<Enter>")
context.app.search_bar.grab_focus()
keyCombo("<Tab>")
first_contact_name = context.app.child(roleName='heading').text
while True:
selected_contact = context.app.child(roleName='heading')
if selected_contact.text == contact_name:
fail = False
break
keyCombo("<Tab>")
# Wait until contact data is being rendered
sleep(1)
if first_contact_name == selected_contact.text:
fail = True
break
context.assertion.assertFalse(
fail, "Can't find contact named '%s'" % contact_name)
context.selected_contact_text = selected_contact.text
@step(u'Open contact editor for selected contact')
def open_contact_editor_for_selected_contact(context):
context.app.menu('File').click()
context.app.menu('File').menuItem('Open Contact').click()
context.execute_steps(u"""
Then Contact editor window with title "Contact Editor - %s" is opened
""" % context.selected_contact_text)
@then(u'"{field}" property is set to "{expected}"')
def property_in_contact_window_is_set_to(context, field, expected):
element = get_element_by_name(context.app.contact_editor, field)
actual = None
if element.roleName == "text":
actual = element.text
elif element.roleName == "combo box":
actual = element.combovalue
if actual == '':
actual = element.textentry('').text
assert unicode(actual) == expected, "Incorrect value"
def get_combobox_textbox_object(contact_editor, section):
"""Get a list of paired 'combobox-textbox' objects in contact editor"""
section_names = {
'Ims': 'Instant Messaging',
'Phones': 'Telephone',
'Emails': 'Email'}
section = section_names[section.capitalize()]
lbl = contact_editor.child(roleName='label', name=section)
panel = lbl.findAncestor(GenericPredicate(roleName='panel'))
textboxes = panel.findChildren(GenericPredicate(roleName='text'))
# Expand section if button exists
button = panel.findChild(
GenericPredicate(roleName='push button', name=section),
retry=False, requireResult=False)
# Expand button if any of textboxes is not visible
if button and (False in [x.showing for x in textboxes]):
button.click()
comboboxes = panel.findChildren(GenericPredicate(roleName='combo box'))
# Rearrange comboboxes and textboxes according to their position
result = []
for combo in comboboxes:
combo_row = combo.position[1]
matching_textboxes = [
x for x in textboxes
if (x.position[1] == combo_row) and (x.position[0] > combo.position[0])]
correct_textbox = min(matching_textboxes, key=lambda x: x.position[0])
result.append((combo, correct_textbox))
comboboxes = [x[0] for x in result]
textboxes = [x[1] for x in result]
return (textboxes, comboboxes)
@step(u'Set {section} in contact editor to')
def set_contact_emails_to_value(context, section):
(textboxes, comboboxes) = get_combobox_textbox_object(
context.app.contact_editor, section)
# clear existing data
for textbox in textboxes:
textbox.text = ""
for index, row in enumerate(context.table.rows):
textboxes[index].text = row['Value']
if comboboxes[index].combovalue != row['Field']:
comboboxes[index].combovalue = row['Field']
@then(u'{section} are set to')
def emails_are_set_to(context, section):
(textboxes, comboboxes) = get_combobox_textbox_object(
context.app.contact_editor, section)
actual = []
for index, textbox in enumerate(textboxes):
combo_value = textbox.text
if combo_value.strip() != '':
type_value = comboboxes[index].combovalue
actual.append({'Field': unicode(type_value), 'Value': unicode(combo_value)})
actual = sorted(actual)
expected = []
for row in context.table:
expected.append({'Field': row['Field'], 'Value': row['Value']})
expected = sorted(expected)
assert actual == expected, "Incorrect %s value:\nexpected:%s\n but was:%s" % (
row['Field'], expected, actual)
@step(u'Tick "Wants to receive HTML mail" checkbox')
def tick_checkbox(context):
context.app.contact_editor.childNamed("Wants to receive HTML mail").click()
@step(u'"Wants to receive HTML mail" checkbox is ticked')
def checkbox_is_ticked(context):
check_state = context.app.childNamed("Wants to receive HTML mail").checked
assert check_state, "Incorrect checkbox state"
@step(u'Switch to "{name}" tab in contact editor')
def switch_to_tab(context, name):
context.app.contact_editor.tab(name).click()
@step(u'Set the following properties in contact editor')
def set_properties(context):
for row in context.table.rows:
context.execute_steps(u"""
* Set "%s" in contact editor to "%s"
""" % (row['Field'], row['Value']))
@step(u'The following properties in contact editor are set')
def verify_properties(context):
for row in context.table.rows:
context.execute_steps(u"""
Then "%s" property is set to "%s"
""" % (row['Field'], row['Value']))
@step(u'Set the following properties in "{section}" section of contact editor')
def set_properties_in_section(context, section):
for row in context.table.rows:
context.execute_steps(u"""
* Set "%s" in "%s" section of contact editor to "%s"
""" % (row['Field'], section, row['Value']))
@step(u'The following properties in "{section}" section of contact editor are set')
def verify_properties_in_section(context, section):
for row in context.table.rows:
context.execute_steps(u"""
Then "%s" property in "%s" section is set to "%s"
""" % (row['Field'], section, row['Value']))
@step(u'Set the following note for the contact')
def set_note_for_contact(context):
context.app.contact_editor.child(
roleName='page tab', name='Notes').textentry('').text = context.text
@then(u'The following note is set for the contact')
def verify_note_set_for_contact(context):
actual = context.app.contact_editor.child(
roleName='page tab', name='Notes').textentry('').text
expected = context.text
assert actual == expected,\
"Incorrect note value:\nexpected:%s\n but was:%s" % (expected, actual)
@step(u'Set "{field_name}" in "{section}" section of contact editor to "{field_value}"')
def set_field_in_section_to_value(context, field_name, section, field_value):
element = get_element_by_name(
context.app.contact_editor, field_name, section=section)
if element.roleName == "text":
element.text = field_value
elif element.roleName == "combo box":
element.combovalue = field_value
\ No newline at end of file
......@@ -3,9 +3,9 @@ from behave import step, then
from common_steps import wait_until
from dogtail.tree import root
from dogtail.rawinput import keyCombo
from time import sleep
from time import sleep, time
from os import system
from gi.repository import Gio
from gi.repository import Gio, GLib
@step(u'Help section "{name}" is displayed')
......@@ -42,12 +42,23 @@ def view_is_opened(context, name):
context.assertion.assertTrue(context.app.menu('Message').showing)
def get_visible_searchbar(context):
"""Wait for searchbar to become visible"""
searchbars = context.app.findChildren(lambda x: x.labeller.name == 'Search:' and x.showing)
assert wait_until(lambda x: len(x) > 0, searchbars), "No visible searchbars found"
return searchbars[0]
@step(u'Open "{section_name}" section')
def open_section_by_name(context, section_name):
wait_until(lambda x: x.showing, context.app.menu('View'))
context.app.menu('View').click()
context.app.menu('View').menu('Window').point()
context.app.menu('View').menu('Window').menuItem(section_name).click()
# Find a search bar
context.app.search_bar = get_visible_searchbar(context)
# Check that service required for this sections is running
required_services = {
'Mail': 'org.gnome.evolution.dataserver.Sources',
......@@ -143,3 +154,22 @@ def task_editor_with_title_is_opened(context, title):
@step(u'Event editor with title "{name}" is displayed')
def event_editor_with_name_displayed(context, name):
context.app.event_editor = context.app.window(name)
@step(u'Wait for email to synchronize')
def wait_for_mail_folder_to_synchronize(context):
# Wait until Google calendar is loaded
for attempt in range(0, 10):
start_time = time()
try:
spinners = context.app.findChildren(lambda x: x.name == 'Spinner')
for spinner in spinners:
try:
while spinner.showing:
sleep(0.1)
if (time() - start_time) > 180:
raise RuntimeError("Mail takes too long to synchronize")
except GLib.GError:
continue
except (GLib.GError, TypeError):
continue
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