Merge lp:~roignac/mago/test_thunderbird into lp:~mago-contributors/mago/mago-testsuite

Proposed by Vadim Rutkovsky
Status: Needs review
Proposed branch: lp:~roignac/mago/test_thunderbird
Merge into: lp:~mago-contributors/mago/mago-testsuite
Diff against target: 383 lines (+370/-0)
2 files modified
thunderbird/test_thunderbird.py (+173/-0)
thunderbird/thunderbird.py (+197/-0)
To merge this branch: bzr merge lp:~roignac/mago/test_thunderbird
Reviewer Review Type Date Requested Status
Mago Contributors Pending
Jean-Baptiste Lallement Pending
Review via email: mp+71685@code.launchpad.net

Description of the change

This branch adds 4 simple tests for thunderbird:
 - Sending an email to oneself
 - Sending an email with attachment
 - Replying to an email
 - Forwarding an email

Note, that these tests require a configured account

I guess, some checks during tests are missing, so could you please point to the most important parts in these tests?

To post a comment you must log in.

Unmerged revisions

30. By Vadim Rutkovsky

Added test_04_forward_a_mail_sent_to_you

29. By Vadim Rutkovsky

Added test_03_reply_to_mail_sent_to_you

28. By Vadim Rutkovsky

Added test_02_new_message_with_attachment

27. By Vadim Rutkovsky

Completed test_01_new_message

26. By Vadim Rutkovsky

Initial commit for thunderbird tests

25. By Vadim Rutkovsky

Started tests for evolution

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'thunderbird'
2=== added directory 'thunderbird/data'
3=== added file 'thunderbird/data/ubuntu01.jpg'
4Binary files thunderbird/data/ubuntu01.jpg 1970-01-01 00:00:00 +0000 and thunderbird/data/ubuntu01.jpg 2011-08-16 13:21:23 +0000 differ
5=== added file 'thunderbird/test_thunderbird.py'
6--- thunderbird/test_thunderbird.py 1970-01-01 00:00:00 +0000
7+++ thunderbird/test_thunderbird.py 2011-08-16 13:21:23 +0000
8@@ -0,0 +1,173 @@
9+# Copyright (C) 2010 Canonical Ltd
10+#
11+# This program is free software; you can redistribute it and/or modify
12+# it under the terms of the GNU General Public License as published by
13+# the Free Software Foundation; either version 2 of the License, or
14+# (at your option) any later version.
15+#
16+# This program is distributed in the hope that it will be useful,
17+# but WITHOUT ANY WARRANTY; without even the implied warranty of
18+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+# GNU General Public License for more details.
20+#
21+# You should have received a copy of the GNU General Public License
22+# along with this program; if not, write to the Free Software
23+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24+
25+"""
26+Thunderbird Test Suite
27+"""
28+
29+from mago import TestCase
30+import unittest
31+import os
32+import ldtp, ooldtp
33+import thunderbird
34+
35+"""
36+Prerequisites:
37+ - one configured mailbox
38+"""
39+
40+class TestThunderbird(TestCase):
41+ """
42+ Test for Thunderbird mail client
43+ """
44+ launcher = 'thunderbird'
45+ main = None # Main Window class
46+ composer = None # Composer window class
47+
48+ def test_01_new_message(self):
49+ """
50+ IntEvo-001: Compose and send message
51+ """
52+
53+ subject = 'Mago test_01'
54+ body = 'Testing'
55+
56+ # Open Compose message window
57+ self.main = thunderbird.MainWindow()
58+ self.composer = self.main.clickNewMessage()
59+
60+ # Fill in details and click Send
61+ sender = self.composer.getUserEmail()
62+ self.composer.setTo(sender)
63+ self.composer.setSubject(subject)
64+ self.composer.setBody(body)
65+ self.composer.clickSendMessage()
66+
67+ # Click Get Mail and wait until operation is complete
68+ self.main.clickGetMail()
69+ # Select Inbox folder of specified mailbox
70+ self.main.selectFolder('Inbox')
71+ # Search for a message with specified subject
72+ self.main.selectMessage(subject)
73+ # Check that correct body and subject are delivered
74+ received_sender = self.main.getSenderFromActiveMessage()
75+ received_subject = self.main.getSubjectFromActiveMessage()
76+ received_body = self.main.getBodyFromActiveMessage()
77+ assert received_sender== sender, "Got '%s', expected '%s'" % (received_sender, sender)
78+ assert received_subject == subject, "Got '%s', expected '%s'" % (received_subject, subject)
79+ assert received_body == body, "Got '%s', expected '%s'" % (received_body, body)
80+
81+ def test_02_new_message_with_attachment(self):
82+ """
83+ IntEvo-002: Compose and send message with attachment
84+ """
85+
86+ attachments = ['ubuntu01.jpg']
87+ subject = 'Mago test_02'
88+ body = 'Testing'
89+
90+ # Open Compose message window
91+ self.main = thunderbird.MainWindow()
92+ self.composer = self.main.clickNewMessage()
93+
94+ # Fill in details and click Send
95+ sender = self.composer.getUserEmail()
96+ self.composer.setTo(sender)
97+ self.composer.setSubject(subject)
98+ self.composer.setBody(body)
99+
100+ for attachment in attachments:
101+ self.attachDialog = self.composer.clickAddAttachment()
102+ attachment_path = os.path.join(os.path.dirname(__file__), 'data', attachment)
103+ self.attachDialog.selectLocation(attachment_path)
104+
105+ self.composer.clickSendMessage()
106+
107+ self.main.clickGetMail()
108+ self.main.selectFolder('Inbox')
109+ self.main.selectMessage(subject)
110+ received_sender = self.main.getSenderFromActiveMessage()
111+ received_subject = self.main.getSubjectFromActiveMessage()
112+ received_body = self.main.getBodyFromActiveMessage()
113+ received_attachments = self.main.getAttachmentsFromActiveMessage()
114+ assert received_sender== sender, "Got '%s', expected '%s'" % (received_sender, sender)
115+ assert received_subject == subject, "Got '%s', expected '%s'" % (received_subject, subject)
116+ assert received_body == body, "Got '%s', expected '%s'" % (received_body, body)
117+ assert received_attachments == attachments, "Got '%s', expected '%s'" % (received_attachments, attachments)
118+
119+ def test_03_reply_to_mail_sent_to_you(self):
120+ """
121+ IntEvo-003: Reply to a mail sent to you
122+ """
123+
124+ subject = 'Mago test_02'
125+ body = 'Replying'
126+
127+ # Open Compose message window
128+ self.main = thunderbird.MainWindow()
129+ self.main.clickGetMail()
130+ self.main.selectFolder('Inbox')
131+ self.main.selectMessage(subject)
132+
133+ self.composer = self.main.clickReply()
134+ sender = self.composer.getUserEmail()
135+ self.composer.appendBody(body)
136+ self.composer.clickSendMessage()
137+
138+ self.main.clickGetMail()
139+ self.main.selectFolder('Inbox')
140+ new_subject = 'Re: ' + subject
141+ self.main.selectMessage(new_subject)
142+ received_sender = self.main.getSenderFromActiveMessage()
143+ received_subject = self.main.getSubjectFromActiveMessage()
144+ received_body = self.main.getBodyFromActiveMessage().encode(errors='replace')
145+ assert received_sender== sender, "Got '%s', expected '%s'" % (received_sender, sender)
146+ assert received_subject == new_subject, "Got '%s', expected '%s'" % (received_subject, new_subject)
147+ assert body in received_body, "Got '%s', doesn't contain '%s'" % (received_body, body)
148+
149+ def test_04_forward_a_mail_sent_to_you(self):
150+ """
151+ IntEvo-004: Forward a mail sent to you
152+ """
153+
154+ subject = 'Mago test_02'
155+ body = 'Forwarding'
156+
157+ # Open Compose message window
158+ self.main = thunderbird.MainWindow()
159+ self.main.clickGetMail()
160+ self.main.selectFolder('Inbox')
161+ self.main.selectMessage(subject)
162+
163+ self.composer = self.main.clickForward()
164+ sender = self.composer.getUserEmail()
165+ self.composer.setTo(sender)
166+ self.composer.appendBody(body)
167+ self.composer.clickSendMessage()
168+
169+ self.main.clickGetMail()
170+ self.main.selectFolder('Inbox')
171+ new_subject = 'Fwd: ' + subject
172+ self.main.selectMessage(new_subject)
173+ received_sender = self.main.getSenderFromActiveMessage()
174+ received_subject = self.main.getSubjectFromActiveMessage()
175+ received_body = self.main.getBodyFromActiveMessage().encode(errors='replace')
176+ assert received_sender== sender, "Got '%s', expected '%s'" % (received_sender, sender)
177+ assert received_subject == new_subject, "Got '%s', expected '%s'" % (received_subject, new_subject)
178+ assert body in received_body, "Got '%s', doesn't contain '%s'" % (received_body, body)
179+
180+if __name__ == "__main__":
181+ unittest.main()
182
183=== added file 'thunderbird/thunderbird.py'
184--- thunderbird/thunderbird.py 1970-01-01 00:00:00 +0000
185+++ thunderbird/thunderbird.py 2011-08-16 13:21:23 +0000
186@@ -0,0 +1,197 @@
187+# Copyright (C) 2010 Canonical Ltd
188+#
189+# This program is free software; you can redistribute it and/or modify
190+# it under the terms of the GNU General Public License as published by
191+# the Free Software Foundation; either version 2 of the License, or
192+# (at your option) any later version.
193+#
194+# This program is distributed in the hope that it will be useful,
195+# but WITHOUT ANY WARRANTY; without even the implied warranty of
196+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
197+# GNU General Public License for more details.
198+#
199+# You should have received a copy of the GNU General Public License
200+# along with this program; if not, write to the Free Software
201+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
202+
203+"""
204+Thunderbird Test Wrapper
205+"""
206+
207+import ldtp, ooldtp
208+
209+class MainWindow():
210+ """ Main window class """
211+ window_name = '*-MozillaThunderbird'
212+ write_button = 'btnWrite'
213+ mailbox_tree = 'tree0'
214+ inbox = 'lstInbox'
215+ messages_table = 'tbl1'
216+ get_mail_button = 'btnGetMail1'
217+
218+ attachments_panel = 'scpn0'
219+ sender_field = 'txtfrom'
220+ reply_button = 'btnreply1'
221+ menu_message = 'mnuMessage'
222+ menu_forward = 'mnuForward'
223+
224+ def clickNewMessage(self):
225+ """ Click 'New' button on toolbar """
226+ ldtp.click(self.window_name, self.write_button)
227+ # Wait until the editor window appears
228+ ldtp.waittillguiexist(ComposeMessage.window_name)
229+ return ComposeMessage()
230+
231+ def clickReply(self):
232+ """ Click Reply in message pane """
233+ ldtp.click(self.window_name, self.reply_button)
234+ # Wait until the editor window appears
235+ ldtp.waittillguiexist(ComposeMessage.window_name)
236+ return ComposeMessage()
237+
238+ def clickForward(self):
239+ """ Click Reply in message pane """
240+ ldtp.selectmenuitem(self.window_name, self.menu_message)
241+ ldtp.selectmenuitem(self.window_name, self.menu_forward)
242+ # Wait until the editor window appears
243+ ldtp.waittillguiexist(ComposeMessage.window_name)
244+ return ComposeMessage()
245+
246+ def clickGetMail(self):
247+ """ Click Get Mail """
248+ ldtp.click(self.window_name, self.get_mail_button)
249+
250+ def selectFirstMailbox(self):
251+ """ Select mailbox with label """
252+ mailboxes = ldtp.getobjectproperty(self.window_name, self.mailbox_tree, 'children').split(' ')
253+ ldtp.doubleclick(self.window_name, mailboxes[1])
254+
255+ def selectFolder(self, folder_name):
256+ """ Select a folder with specified name """
257+ try:
258+ folder = ldtp.getchild(self.window_name, folder_name)
259+ except:
260+ self.selectFirstMailbox()
261+ folder = ldtp.getchild(self.window_name, folder_name)
262+ ldtp.wait(2)
263+ ldtp.click(self.window_name, folder[0])
264+
265+ ldtp.wait(5)
266+ assert ldtp.objectexist(self.window_name, self.messages_table)
267+
268+ def selectMessage(self, match):
269+ """ Select a specified message by id """
270+ ldtp.singleclickrow(self.window_name, self.messages_table, match)
271+ ldtp.wait(5)
272+
273+ def getSenderFromActiveMessage(self):
274+ """ Get sender from active message """
275+ ldtp.wait(2)
276+ sender = ldtp.getobjectproperty(self.window_name, 'txtfrom*', 'label')
277+ return sender.split('<')[1].split('>')[0]
278+
279+ def getSubjectFromActiveMessage(self):
280+ """ Get subject from active message """
281+ sender = ldtp.getobjectproperty(self.window_name, 'txtsubject*', 'label')
282+ return ": ".join(sender.split(': ')[1:])
283+
284+ def getBodyFromActiveMessage(self):
285+ """ Get body from active message """
286+ body_frame = ldtp.getchild(self.window_name, role = 'document_frame')[0]
287+ body_field = ldtp.getobjectproperty(self.window_name, body_frame, 'children').split(' ')[0]
288+ body_value = ldtp.gettextvalue(self.window_name, body_field)
289+ return body_value.strip()
290+
291+ def getAttachmentsFromActiveMessage(self):
292+ """ Get attachment name from active message """
293+ attachments = []
294+ attachments_panel_children = ldtp.getobjectproperty(self.window_name, self.attachments_panel, 'children').split(' ')
295+ for child in attachments_panel_children:
296+ if 'ukn' in child:
297+ child_label = ldtp.getobjectproperty(self.window_name, child, 'label')
298+ if child_label != '':
299+ attachments.append(child_label)
300+ return attachments
301+
302+class ComposeMessage():
303+ """ Compose message class """
304+ window_name = 'frmWrite:*'
305+ from_field = 'cboFrom'
306+ to_field = 'To:'
307+ subject_field = 'txtSubject'
308+ body_field = 'uknaboutblank'
309+ send_button = 'btnSend'
310+
311+ attach_button = 'btnAttach1'
312+
313+ def getUserEmail(self):
314+ """ Get user email from combobox """
315+ from_value = ldtp.getobjectproperty(self.window_name, self.from_field, 'children')
316+ full_user_name = ldtp.getobjectproperty(self.window_name,from_value, 'label')
317+ return full_user_name.split('<')[1].split('>')[0]
318+
319+ def setTo(self, value):
320+ """ Enter recipient """
321+ # TODO: Can't select To: field, so focus the window and send keys
322+ ldtp.wait(2)
323+ for char in value:
324+ ldtp.generatekeyevent(char)
325+ ldtp.wait(0.2)
326+
327+ def setSubject(self, value):
328+ """ Enter subject and update window_name"""
329+ ldtp.settextvalue(self.window_name, self.subject_field, value)
330+
331+ def setBody(self, value):
332+ """ Enter body text """
333+ ldtp.grabfocus(self.window_name, self.body_field)
334+ ldtp.settextvalue(self.window_name, self.body_field, value)
335+
336+ def appendBody(self, value):
337+ """ Append some text to body """
338+ ldtp.grabfocus(self.window_name, self.body_field)
339+ ldtp.wait(2)
340+ for char in value:
341+ ldtp.generatekeyevent(char)
342+ ldtp.wait(0.2)
343+
344+ def clickSendMessage(self):
345+ """ Click Send button on toolbar and wait until the window disappears"""
346+ ldtp.click(self.window_name, self.send_button)
347+ ldtp.waittillguinotexist(self.window_name)
348+
349+ def clickAddAttachment(self):
350+ """ Click Add Attachment button """
351+ ldtp.click(self.window_name, self.attach_button)
352+ attachmentDialog = AttachmentDialog()
353+ attachmentDialog.waitUntilDialogAppears()
354+ return attachmentDialog
355+
356+class AttachmentDialog():
357+ """ The class describes action in attachment dialog """
358+
359+ attach_dialog = 'dlgAttachFile(s)'
360+ attach_dialog_location_edit = 'tbtnTypeafilename'
361+ attach_dialog_filename_field = 'txtLocation'
362+ attach_dialog_attach_button = 'btnOpen'
363+
364+ def waitUntilDialogAppears(self):
365+ """ Wait until the dialog appears """
366+ ldtp.waittillguiexist(self.attach_dialog)
367+
368+ def selectLocation(self, location):
369+ """ Click Edit Location button, input location and click 'Attach' button """
370+
371+ # If location entry didn't appear, click 'Edit Location' button
372+ try:
373+ ldtp.getchild(self.attach_dialog, self.attach_dialog_filename_field)
374+ except:
375+ # Click 'Edit Location' button
376+ ldtp.click(self.attach_dialog, self.attach_dialog_location_edit)
377+
378+ # Input path to sample file
379+ ldtp.settextvalue(self.attach_dialog, self.attach_dialog_filename_field, location)
380+ # Click 'Attach'
381+ ldtp.click(self.attach_dialog, self.attach_dialog_attach_button)
382+ # Wait until the dialog is closed
383+ ldtp.waittillguinotexist(self.attach_dialog)

Subscribers

People subscribed via source and target branches