~ubuntu-branches/ubuntu/utopic/dogtail/utopic

« back to all changes in this revision

Viewing changes to dogtail/apps/wrappers/evolution.py

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2006-12-21 13:33:47 UTC
  • mfrom: (1.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 5.
  • Revision ID: james.westby@ubuntu.com-20061221133347-xo9jg11afp5plcka
Tags: upstream-0.6.1
ImportĀ upstreamĀ versionĀ 0.6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
"""Wrapper code to help when scripting Evolution
2
 
 
3
 
Author: David Malcolm <dmalcolm@redhat.com>"""
4
 
 
5
 
__author__ = 'David Malcolm <dmalcolm@redhat.com>'
6
 
 
7
 
from dogtail.tree import *
8
 
from dogtail.procedural import *
9
 
from dogtail.utils import run
10
 
from os import environ, path, remove
11
 
 
12
 
from dogtail.distro import *
13
 
from dogtail.version import Version
14
 
 
15
 
from dogtail.apps.categories import *
16
 
 
17
 
# Evolution folder browser (GtkTreeView?) seems to be implemented as a list of role='table cell' children (the rows), with each having a list of 'table cell' children (the table cells)
18
 
# The table rows have NODE_CHILD_OF relations (with paths, in at-poke)
19
 
20
 
 
21
 
# Use the gettext translations sniffed from the package db:
22
 
import dogtail.i18n
23
 
#dogtail.i18n.loadTranslationsFromPackageMoFiles('evolution')
24
 
dogtail.i18n.loadTranslationsFromPackageMoFiles('evolution-connector')
25
 
 
26
 
# App-specific wrapper classes:
27
 
 
28
 
class EvolutionApp(Application, EmailClient):
29
 
        """
30
 
        Useful test hooks for Evolution testcases
31
 
        """
32
 
        def __init__(self):
33
 
                Application.__init__(self, root.application("evolution"))
34
 
 
35
 
                self.evoVersion = packageDb.getVersion("evolution")
36
 
                print "Evolution version %s"%self.evoVersion
37
 
 
38
 
                if self.evoVersion>=Version([1,5,0]):
39
 
                        self.edsVersion = packageDb.getVersion("evolution-data-server")
40
 
                        print "evolution-data-server version %s"%self.edsVersion
41
 
                else:
42
 
                        self.edsVersion = None
43
 
 
44
 
                # The name of the gtkhtml package(s) for the various versions of Evolution varies between distributions:
45
 
                self.gtkhtmlVersion = None
46
 
                if distro:
47
 
                        if isinstance(distro, RedHatOrFedora):
48
 
                                self.gtkhtmlPackageName = "gtkhtml3"
49
 
                        else:
50
 
                                raise "You need to implement appropriate logic here to get the name of the gtkhtml package for your distribution for this version of Evolution"
51
 
                        self.gtkhtmlVersion = packageDb.getVersion(self.gtkhtmlPackageName)
52
 
                        print "%s version %s"%(self.gtkhtmlPackageName, self.gtkhtmlVersion)
53
 
 
54
 
        def getConfigMenuItem(self):
55
 
                """
56
 
                Get the menu item that triggers the Settings/Preferences dialog,
57
 
                handling version-specific differences
58
 
                """
59
 
                if self.evoVersion<Version([2,1,0]):
60
 
                        return self.menu("Tools").menuItem("Settings...")
61
 
                else:
62
 
                        return self.menu("Edit").menuItem("Preferences")
63
 
 
64
 
        def doPasswordDialog(self, password, rememberPassword):
65
 
                """
66
 
                Utility function for dealing with Evolution's password dialog.  It
67
 
                finds the dialog, then fills in the password, setting the 'Remember
68
 
                Password' checkbox accordingly. It then clicks on OK
69
 
                """
70
 
                passwdDlg = self.child(roleName="alert", recursive=False, debugName="passwordDlg")
71
 
                passwdDlg.child("Remember this password").setCheckbox = rememberPassword
72
 
                passwdDlg.child(roleName="password text").passwordText = password
73
 
                passwdDlg.child("OK").click()
74
 
 
75
 
        def getSelectFolderDialog(self):
76
 
                """
77
 
                Utility function to get the 'Select folder' dialog, wrapped
78
 
                """
79
 
                return EvolutionSelectFolderDialog(self.dialog("Select folder"), self)
80
 
 
81
 
#FIXME: generalize this to handle arbitrary error dialogs, and allow a non-fatal version where we check that an error that was meant to occur did occur?
82
 
#FIXME: maybe allow installation of error detection hooks into the agent, and have it do it after every "action"??? (more complicated?)
83
 
        def detectAuthFailure(self):
84
 
                """
85
 
                Detect an 'Evolution Error' dialog, raising an exception if one is
86
 
                found.  The text of the dialog is scraped into the exception.
87
 
                """
88
 
                errorDlg = self.child("Evolution Error", recursive=False)
89
 
                if errorDlg:
90
 
                        raise "AuthenticationError: %s"%errorDlg.child(roleName="label").text
91
 
 
92
 
#FIXME: finish the import hooks
93
 
 
94
 
        def __doImportFirstPage(self):
95
 
                """
96
 
                Open the File->Import wizard and navigate to the second page
97
 
                """
98
 
                self.menu("File").menuItem("Import...").click()
99
 
                importAssistant = Wizard(self.child("Evolution Import Assistant", recursive=False), "Import Assistant")
100
 
                importAssistant.clickForward()
101
 
                return importAssistant
102
 
 
103
 
        def __doImportFromOtherProgram(self):
104
 
                importAssistant = self.__doImportFirstPage()
105
 
                importAssistant.child("Import data and settings from older programs").click()
106
 
                importAssistant.clickForward()
107
 
                return importAssistant
108
 
 
109
 
        def __doImportFromSingleFile(self, filename, filetype):
110
 
                importAssistant = self.__doImportFirstPage()
111
 
                importAssistant.child("Import a single file").click()
112
 
                importAssistant.clickForward()
113
 
 
114
 
                importAssistant.child(label="Filename:").child(roleName="text").text = filename
115
 
                importAssistant.child(label="File type:").combovalue=filetype
116
 
                importAssistant.clickForward()
117
 
                
118
 
                return importAssistant
119
 
        
120
 
        def importSingleEmail(self, filename, useSubfolder=False):
121
 
                """
122
 
                Test hook to test importing a single email. Imports the email into a
123
 
                local folder (either the local Inbox, or creates specially-purpose
124
 
                subfolder inside the local Inbox), then views that email (and then
125
 
                tests that Evolution is still running)
126
 
 
127
 
                FIXME: not fully implemented yet
128
 
                """
129
 
 
130
 
                # Tested on Evolution 2.0.4 and Evolution 2.4.0:
131
 
                # FIXME: what's the _exact_ value for this version test?
132
 
                if self.evoVersion>=Version([2,4.0]):
133
 
                        filetype = "Berkeley Mailbox (mbox)"
134
 
                else:
135
 
                        filetype = "MBox (mbox)"
136
 
          
137
 
                importAssistant = self.__doImportFromSingleFile(filename, filetype)
138
 
 
139
 
                if useSubfolder:
140
 
                        # Unfortunately this doesn't yet have a labelling relationship (in evolution-data-server 1.4.0)
141
 
                        #importAssistant.child(label="Destination folder:").click()
142
 
                        # So we get it by its label:
143
 
                        importAssistant.child("Inbox").click()
144
 
 
145
 
                        selectFolderDlg = self.getSelectFolderDialog()
146
 
                        folderName = "test folder for %s"%agent.testRunId
147
 
                        selectFolderDlg.newInboxSubfolder(folderName)
148
 
                        # FIXME: the above can fail if the testrun ID contains characters that can't be a folder name
149
 
                
150
 
                importAssistant.clickForward()
151
 
                importAssistant.child("Import").click()
152
 
 
153
 
                # FIXME: now view it and see if we're still alive
154
 
                # use PrintPreview as well
155
 
 
156
 
        def __doIdentityPage(self, accountWiz, account):        
157
 
                # "Identity" page:
158
 
                accountWiz.child(label="Full Name:").text = account.fullName
159
 
                accountWiz.child(label="Email Address:").text = account.emailAddress
160
 
                accountWiz.child(label="Reply-To:").text = account.replyTo
161
 
                accountWiz.child(label="Organization:").text = account.organisation
162
 
                accountWiz.clickForward()
163
 
 
164
 
        def __doReceivingEmailPage(self, accountWiz, account):  
165
 
                # "Receiving Email" page:
166
 
                accountWiz.child(label="Server Type: ").combovalue=account.getReceivingComboValue()
167
 
 
168
 
                if isinstance(account, ExchangeAccount):
169
 
                        if self.evoVersion>Version([2,3,0]):
170
 
                                accountWiz.child(label="Username:").text = account.windowsUsername
171
 
                                accountWiz.child(label="OWA Url:").text = account.urlForOWA
172
 
 
173
 
                                # For Exchange, in Evolution 2.3 and later we have to click on the authenticate button to get further:
174
 
                                accountWiz.child("Authenticate").click()
175
 
                                self.doPasswordDialog(account.password, True)
176
 
                                self.detectAuthFailure()
177
 
                        else:
178
 
                                accountWiz.child(label="Exchange Server:").text = account.server
179
 
                                accountWiz.child(label="Windows Username:").text = account.windowsUsername
180
 
                                
181
 
                elif isinstance(account,MixedAccount):
182
 
                        # In Evolution 2.0.4, server field is labelled "Host:", in Evolution 2.4.0 it is labelled "Server:"
183
 
                        # FIXME: check for other versions of Evolution; what is the _exact_ test here?
184
 
                        if self.evoVersion<Version([2,4,0]):
185
 
                                accountWiz.child(label="Host:").text = account.receiveMethod.server
186
 
                        else:
187
 
                                accountWiz.child(label="Server:").text = account.receiveMethod.server
188
 
                        accountWiz.child(label="Username:").text = account.receiveMethod.username
189
 
                        # FIXME: "Use secure Connection"
190
 
                        # FIXME: "Check for Supported Types"
191
 
                        # FIXME: "Remember password"
192
 
                else:
193
 
                        raise NotImplementedError
194
 
 
195
 
                accountWiz.clickForward()
196
 
 
197
 
        def __doReceivingOptionsPage(self, accountWiz, account):        
198
 
                # "Receiving Options" page:
199
 
                # FIXME: implement
200
 
                accountWiz.clickForward()
201
 
 
202
 
        def __doSendingEmailPage(self, accountWiz, account):    
203
 
                # "Sending Email" page:
204
 
                # FIXME: this fails; it picks up on the "Server Type:" from the earlier page
205
 
                # and hence can't find the value it wants in the combo. Should use the correct page for all of this...
206
 
                sendingEmailPage = accountWiz.currentPage()
207
 
                sendingEmailPage.child(label="Server Type: ").combovalue = account.getSendingComboValue()
208
 
                print sendingEmailPage
209
 
                if isinstance(account,MixedAccount):
210
 
                        if isinstance(account.sendMethod,SMTPSettings):
211
 
                                sendingEmailPage.child(label="Server:").text = account.sendMethod.server
212
 
                                # FIXME: "Server requires authentication"
213
 
                                # etc etc
214
 
 
215
 
                                # FIXME: is this visible? "SSL is not supported in this build of Evolution"
216
 
                elif isinstance(account, ExchangeAccount):
217
 
                        # Nothing should need doing
218
 
                        pass
219
 
                else:
220
 
                        raise NotImplementedError
221
 
                accountWiz.clickForward()
222
 
 
223
 
        def __doAccountManagementPage(self, accountWiz, accountName):   
224
 
                # "Account Management" page:
225
 
                accountWiz.child(label="Name:").text = accountName
226
 
                accountWiz.clickForward()
227
 
 
228
 
        def createAccount(self, account, accountName):
229
 
                """
230
 
                Add a new account, running the Evolution Account Assistant, filling in
231
 
                the values given.
232
 
                """
233
 
                
234
 
                self.getConfigMenuItem().click()
235
 
                settingsDlg = self.child("Evolution Settings", recursive=False)
236
 
                #pageTabs = settingsDlg.child(roleName="page tab list")
237
 
                # page tabs don't seem to be labelled in the tree... how do we get at this?
238
 
 
239
 
                # for now, assume Mail Accounts tab is selected..
240
 
                # Account wizard takes a while to appear...
241
 
                settingsDlg.child("Add").click()
242
 
                # this one needs a watch, I guess
243
 
 
244
 
                accountWiz = Wizard(self.child("Evolution Account Assistant", recursive=False),"Evolution Account Assistant")
245
 
                accountWiz.clickForward()
246
 
 
247
 
                self.__doIdentityPage(accountWiz, account)
248
 
                self.__doReceivingEmailPage(accountWiz, account)
249
 
                self.__doReceivingOptionsPage(accountWiz, account)
250
 
                self.__doSendingEmailPage(accountWiz, account)
251
 
                self.__doAccountManagementPage(accountWiz, accountName)
252
 
 
253
 
                # "Done" page:
254
 
                accountWiz.child("Apply").click()
255
 
 
256
 
                # FIXME: we should add a review stage where we check that all widgets have the correct settings. (But why should that even be necessary? Can our framework implement that on the script's behalf? perhaps with a UITransaction class or somesuch?)
257
 
 
258
 
        def doFirstTimeWizard(self, account, accountName, timezoneName):
259
 
                setupWiz = Wizard(self.window('Evolution Setup Assistant'))
260
 
                setupWiz.clickForward()
261
 
 
262
 
                self.__doIdentityPage(setupWiz, account)
263
 
                self.__doReceivingEmailPage(setupWiz, account)
264
 
                self.__doReceivingOptionsPage(setupWiz, account)
265
 
                self.__doSendingEmailPage(setupWiz, account)
266
 
                self.__doAccountManagementPage(setupWiz, accountName)
267
 
                
268
 
                # Timezone page:
269
 
                # FIXME: timezone selection doesn't yet work
270
 
                #self.child("TimeZone Combobox").child(timezoneName).click()
271
 
                setupWiz.clickForward()
272
 
 
273
 
                # "Done" page:
274
 
                setupWiz.child("Apply").click()
275
 
                
276
 
        def composeEmail(self):
277
 
                """
278
 
                Utility function to start composing a new email.
279
 
 
280
 
                Returns a Composer instance wrapping the new email composer window.
281
 
                """
282
 
                self.menu("File").child("Mail Message").click()
283
 
                composer = self.window("Compose a message")
284
 
                return Composer(composer)
285
 
                
286
 
        def createMeeting(self):
287
 
                """
288
 
                Utility function to start creating a new meeting.
289
 
 
290
 
                Returns a MeetingWindow instance wrapping the new meeting window.
291
 
                """
292
 
                self.menu("File").child("Meeting").click()
293
 
                meetingWin = self.dialog("Meeting - No summary")
294
 
                return MeetingWindow(meetingWin)
295
 
                
296
 
 
297
 
class Composer(Window):
298
 
        """
299
 
        Subclass of Window wrapping an Evolution email composer, with utility functions
300
 
        """
301
 
 
302
 
        def __init__(self, node):
303
 
                Window.__init__(self, node)
304
 
 
305
 
                #FIXME: doesn't seem to be accessible on FC3 with evolution-2.0.4/gtkhtml3-3.3.2
306
 
                gtkhtmlPanel = self.child(name="Panel containing HTML", roleName="panel")
307
 
                gtkhtmlPanel.debugName="GTKHtml panel"
308
 
                self.htmlNode = gtkhtmlPanel.child(roleName="text")
309
 
 
310
 
        def __setattr__(self, name, value):
311
 
                if name=="to":
312
 
                        # Set the To: ("addressee" if you're feeling fancy) of the email:
313
 
                        self.textentry("To:").text = value
314
 
                elif name=="subject":
315
 
                        # Set the subject of the email:
316
 
                        self.child(label="Subject:").text = value
317
 
                elif name=="body":
318
 
                        # Set the body text of the email:
319
 
                        self.htmlNode.text = value
320
 
                else:
321
 
                        # otherwise, use normal Python attribute-handling:
322
 
                        self.__dict__[name]=value
323
 
 
324
 
        def setHtml(self, htmlFlag):
325
 
                if not htmlFlag:
326
 
                        raise NotImplementedError
327
 
        
328
 
                # Set to HTML
329
 
                formatMenu = self.menu("Format")
330
 
                formatMenu.menuItem("HTML").click()
331
 
 
332
 
        def setHeader(self, level):
333
 
                """
334
 
                Set the text type to 'Heading 1-6'
335
 
                """
336
 
                formatMenu = self.menu("Format")
337
 
                headingMenu = formatMenu.menu("Heading")
338
 
                headingMenu.menuItem("Header %s"% level).click()
339
 
 
340
 
        def setBulletedList(self):
341
 
                """
342
 
                Sets the text style to be 'Bulleted List'
343
 
                """
344
 
                formatMenu = self.menu("Format")
345
 
                headingMenu = formatMenu.menu("Heading")
346
 
                headingMenu.menuItem("Bulleted List").click()
347
 
 
348
 
        def typeText(self, text):
349
 
                self.htmlNode.typeText(text)
350
 
 
351
 
        def send(self):
352
 
                """
353
 
                Clicks on the Send menu item to send this email.  Use with caution!
354
 
                """
355
 
                self.menuItem("Send").click()
356
 
 
357
 
        def testUndoRedo(self):
358
 
                """
359
 
                Repeatedly does an 'Undo' until everything is undone, then does a 'Redo'
360
 
                that many times, and checks that the content is the same.
361
 
 
362
 
                Unfortunately, this doesn't work; Undo is always sensitive, even when
363
 
                there's nothing to undo:
364
 
                http://bugzilla.gnome.org/show_bug.cgi?id=257214
365
 
                """
366
 
                numUndos = 0
367
 
                undo = self.menuItem("Undo")
368
 
                redo = self.menuItem("Redo")
369
 
 
370
 
                originalText = self.htmlNode.text
371
 
                
372
 
                while undo.sensitive:
373
 
                        undo.click()
374
 
                        numUndos+=1
375
 
 
376
 
                # Now redo it:
377
 
                for i in range(numUndos):
378
 
                        redo.click()
379
 
 
380
 
                newText = self.htmlNode.text
381
 
 
382
 
                if newText!=originalText:
383
 
                        raise UndoRedoException(originalText, newText)
384
 
 
385
 
class UndoRedoException(Exception):
386
 
        def __init__(self, originalValue, newValue):
387
 
                self.originalValue = originalValue
388
 
                self.newValue = newValue
389
 
 
390
 
        def __str__(self):
391
 
                return "Original value %s not equal to new value %s"%(originalValue, newValue)
392
 
 
393
 
class AppointmentWindow(Window):
394
 
        """
395
 
        Subclass of Window wrapping an Evolution appointment window, with utility functions
396
 
        """
397
 
        def __init__(self, node):
398
 
                Window.__init__(self, node)
399
 
 
400
 
        def __setattr__(self, name, value):
401
 
                if name=="summary":
402
 
                        self.tab("Appointment").child(label="Summary:").text = value
403
 
                else:
404
 
                        # otherwise, use normal Python attribute-handling:
405
 
                        self.__dict__[name]=value
406
 
 
407
 
class MeetingWindow(AppointmentWindow):
408
 
        """
409
 
        Subclass of AppointmentWindow wrapping an Evolution meeting window, with utility functions
410
 
        """
411
 
        def __init__(self, node):
412
 
                AppointmentWindow.__init__(self, node)
413
 
                self.invitationsTab = self.tab("Invitations")
414
 
                self.attendeeTable = self.invitationsTab.child(roleName='table')
415
 
                
416
 
        def addAttendee(self, attendee, attendeeType, role, rsvp, status):
417
 
                """
418
 
                Add an attendeee to this meeting. Doesn't fully work yet.
419
 
                """
420
 
                self.invitationsTab.button('Add').click()
421
 
 
422
 
class SelectFolderDialog(Window):
423
 
        """
424
 
        Subclass of Window wrapping an Evolution 'Select Folder' dialog, with
425
 
        utility functions
426
 
        """
427
 
 
428
 
        def __init__(self, node, evoApp):
429
 
                Window.__init__(self, node)
430
 
                self.evoApp = evoApp
431
 
 
432
 
        def newInboxSubfolder(self, name):
433
 
                self.child("New").click()
434
 
                createFolderDlg = self.evoApp.dialog("Create folder")
435
 
                createFolderDlg.child(label="Folder name:").text = name
436
 
 
437
 
                tree = self.child("Mail Folder Tree")
438
 
                tableCell = "On This Computer"
439
 
                "Inbox"
440
 
                # FIXME: need implement table stuff for this...
441
 
                #"On This Computer" / "Inbox"
442
 
                
443
 
                # FIXME: select parent folder
444
 
                createFolderDlg.child("Create").click()
445
 
                # this is only clickable if we have a sane folder name and a selected parent
446
 
 
447
 
                # FIXME: now need to select the new folder in the Select Folder dialog
448
 
 
449
 
                # FIXME: finally, should click on OK (or should the caller do this?)
450
 
 
451
 
class Account:
452
 
        """
453
 
        Base class for an Evolution account, for use when creating test accounts
454
 
        """
455
 
        def __init__(self, fullName, emailAddress, replyTo="", organisation="", password=""):
456
 
                self.fullName = fullName
457
 
                self.emailAddress = emailAddress
458
 
                self.replyTo = replyTo
459
 
                self.organisation = organisation
460
 
                self.password = password
461
 
 
462
 
        def getReceivingComboValue(self):
463
 
                raise NotImplementedError
464
 
 
465
 
        def getSendingComboValue(self):
466
 
                raise NotImplementedError
467
 
 
468
 
class UseSecureConnection:
469
 
        NEVER, WHENEVER, ALWAYS = ("NEVER", "WHENEVER", "ALWAYS")
470
 
 
471
 
class ExchangeAccount(Account):
472
 
        """
473
 
        Subclass of Account representing an Exchange account
474
 
        """
475
 
        def __init__(self, fullName, emailAddress, windowsUsername, server="", urlForOWA="", replyTo="", organisation="", password=""):
476
 
                Account.__init__(self, fullName, emailAddress, replyTo, organisation, password)
477
 
                self.windowsUsername = windowsUsername
478
 
                self.server = server
479
 
                self.urlForOWA = urlForOWA
480
 
 
481
 
        def getReceivingComboValue(self):
482
 
                return "Microsoft Exchange"
483
 
 
484
 
        def getSendingComboValue(self):
485
 
                return "Microsoft Exchange"
486
 
 
487
 
class MixedAccount(Account):
488
 
        """
489
 
        Subclass of Account representing a combination of a receiving method and a
490
 
        sending method
491
 
        """
492
 
        def __init__(self, fullName, emailAddress, receiveMethod, sendMethod, replyTo="", organisation="", ):
493
 
                Account.__init__(self, fullName, emailAddress, replyTo, organisation, password="")
494
 
                assert isinstance(receiveMethod, ReceiveSettings)
495
 
                assert isinstance(sendMethod, SendSettings)
496
 
                self.receiveMethod = receiveMethod
497
 
                self.sendMethod = sendMethod            
498
 
 
499
 
        def getReceivingComboValue(self):
500
 
                return self.receiveMethod.getServerTypeComboValue()
501
 
 
502
 
        def getSendingComboValue(self):
503
 
                return self.sendMethod.getServerTypeComboValue()
504
 
 
505
 
class ReceiveSettings:
506
 
        def getServerTypeComboValue(self):
507
 
                raise NotImplementedError
508
 
        
509
 
class SendSettings:
510
 
        def getServerTypeComboValue(self):
511
 
                raise NotImplementedError
512
 
 
513
 
class IMAPSettings(ReceiveSettings):
514
 
        def __init__(self, server, username, useSecureConnection, authenticationType, rememberPassword=False):
515
 
                self.server = server
516
 
                self.username = username
517
 
                self.useSecureConnection = useSecureConnection
518
 
                self.authenticationType = authenticationType
519
 
                self.rememberPassword = rememberPassword
520
 
 
521
 
        def getServerTypeComboValue(self):
522
 
                return "IMAP"
523
 
 
524
 
class SMTPSettings(SendSettings):
525
 
        def __init__(self, server, useSecureConnection, authenticationType="plain", requireAuth=False, username="", rememberPassword=False):
526
 
                self.server = server
527
 
                self.username = username
528
 
                self.useSecureConnection = useSecureConnection
529
 
                self.authenticationType = authenticationType
530
 
                self.rememberPassword = rememberPassword
531
 
                self.requireAuth = requireAuth
532
 
 
533
 
        def getServerTypeComboValue(self):
534
 
                return "SMTP"
535
 
 
536
 
class SendmailSettings(SendSettings):
537
 
        def getServerTypeComboValue(self):
538
 
                return "Sendmail"
539
 
 
540
 
class ReceiptOptions:
541
 
        """
542
 
        Class containing the options found on the 'Receiving Email' page of the
543
 
        configuration dialogs.
544
 
        """
545
 
        def __init__(self, autocheckOn=False, autocheckInterval=10, customConnectionCommand=None, showOnlySubscribedFolders=False, overrideNamespace=None, applyFiltersToNewInInbox=False, checkNewForJunk=False, onlyCheckForJunkInInbox=False, autosyncRemoteMailLocally=False):
546
 
                raise NotImplementedError
547
 
 
548
 
def TestFocus():
549
 
        focus.application("evolution")
550
 
        focus.menu("File")
551
 
        click("Import...")
552
 
        focus.application("evolution")
553
 
        focus.dialog("Evolution Import Assistant")
554
 
        click("Forward") # grrr... selects the Forward menu item, rather than the Forward button
555
 
 
556
 
def blowAwayEvolution():
557
 
        """
558
 
        Helper function for testing Evolution.
559
 
 
560
 
        Use with caution.
561
 
 
562
 
        This forcibly shuts down evolution, then blows away all Evolution settings.
563
 
        (FIXME: first copy the GConf data first to ./evolution-gconf-backup.xml ???)    
564
 
        """
565
 
        os.system ('evolution --force-shutdown')
566
 
        sleep(5)
567
 
        os.system ('gconftool-2 --recursive-unset /apps/evolution')
568
 
 
569
 
 
570
 
def doFirstTimeWizard(account, accountName, timezoneName):
571
 
        """
572
 
        Helper function for testing Evolution.
573
 
 
574
 
        Use with caution.
575
 
 
576
 
        This forcibly shuts down evolution, then blows away all Evolution settings.
577
 
        (FIXME: first copy the GConf data first to ./evolution-gconf-backup.xml ???)
578
 
 
579
 
        It then runs the first time wizard with the given settings.
580
 
 
581
 
        Returns an EvolutionApp instance.
582
 
        """
583
 
        blowAwayEvolution()
584
 
        
585
 
        run('evolution')
586
 
        evo = EvolutionApp()
587
 
        evo.doFirstTimeWizard(account, accountName, timezoneName)
588
 
 
589
 
        return evo
590
 
        
591
 
def setBogusGConfAccountData():
592
 
        """
593
 
        Helper function for testing Evolution.
594
 
 
595
 
        Use with caution.
596
 
        
597
 
        This writes totally bogus account data into the GConf key 
598
 
        "/apps/evolution/mail/accounts", in order to hack past the first-time
599
 
        wizard.
600
 
        """
601
 
        os.system('gconftool-2 --type list --list-type=string --set /apps/evolution/mail/accounts ["This is bogus data that is not even an attempt at well-formed XML"]')
602