@@ -119,7 +119,7 @@ def wrapper(*args, **kwargs):
119119 func (* args , ** kwargs )
120120 break # if successful
121121 except Exception as e :
122- if retry == max_tries :
122+ if retry == max_tries - 1 :
123123 raise e
124124 else :
125125 print ("failed during setup in {}.\n Retrying" .format (
@@ -151,20 +151,27 @@ def export_pub_key():
151151
152152@retry_if_failed (max_tries = 3 )
153153def enter_imap_passwd (tb ):
154- # check new mail so client can realize IMAP requires entering a password
155- get_messages (tb )
154+ try :
155+ pass_prompt = tb .app .findChild (orPredicate (
156+ GenericPredicate (name = 'Enter your password for user' , roleName = 'frame' ),
157+ GenericPredicate (name = 'Enter your password for user' , roleName = 'dialog' )
158+ ))
159+ except tree .SearchError :
160+ # check new mail so client can realize IMAP requires entering a password
161+ get_messages (tb )
156162 # password entry
157163 pass_prompt = tb .app .findChild (orPredicate (
158164 GenericPredicate (name = 'Enter your password for user' , roleName = 'frame' ),
159165 GenericPredicate (name = 'Enter your password for user' , roleName = 'dialog' )
160166 ))
161167 pass_textbox = pass_prompt .findChild (GenericPredicate (roleName = 'password text' ))
162- pass_textbox .text = tb .imap_pw
168+ pass_textbox .typeText ( tb .imap_pw )
163169 pass_prompt .childNamed ("Use Password Manager to remember this password." )\
164170 .doActionNamed ('check' )
165171 pass_prompt .findChild (orPredicate (
166172 GenericPredicate (name = 'OK' , roleName = 'push button' ), # tb < 91
167- GenericPredicate (name = 'Sign in' , roleName = 'push button' )) # tb >= 91
173+ GenericPredicate (name = 'Sign in' , roleName = 'push button' ), # tb >= 91, tb < 128
174+ GenericPredicate (name = 'OK' , roleName = 'button' )) # tb >= 128
168175 ).doActionNamed ('press' )
169176
170177def accept_qubes_attachments (tb ):
@@ -237,8 +244,14 @@ def configure_openpgp_account(tb):
237244 accept_dialog = tb .app .findChild (orPredicate (
238245 GenericPredicate (name = '.*(%s).*' % keyid ),
239246 GenericPredicate (name = '.[0-9A-F]*%s' % keyid ),
240- )).parent
241- accept_dialog .childNamed ('OK' ).doActionNamed ('press' )
247+ GenericPredicate (name = 'ID: 0x%s' % keyid ),
248+ )).parent .parent
249+ try :
250+ accept_dialog .childNamed ("Accepted.*" ).doActionNamed ("select" )
251+ except tree .SearchError :
252+ # old TB
253+ pass
254+ accept_dialog .childNamed ('OK|Import' ).doActionNamed ('press' )
242255 tb .app .childNamed ('Success! Keys imported.*' ).childNamed ('OK' ).doActionNamed (
243256 'press' )
244257 doubleClick (* key_manager .findChild (
@@ -256,16 +269,37 @@ def configure_openpgp_account(tb):
256269
257270
258271def get_messages (tb ):
259- tb .app .child (name = 'user@localhost' ,
260- roleName = 'table row' ).doActionNamed ('activate' )
261- tb .app .button ('Get Messages' ).doActionNamed ('press' )
262- tb .app .menuItem ('Get All New Messages' ).doActionNamed ('click' )
263- tb .app .child (name = 'Inbox.*' , roleName = 'table row' ).doActionNamed (
264- 'activate' )
272+ try :
273+ # TB >= 115
274+ try :
275+ # TB >= 128
276+ tb .app .child ('Get Messages' , roleName = 'button' ).doActionNamed ('press' )
277+ except tree .SearchError :
278+ # TB < 128
279+ tb .app .button ('Get Messages' ).doActionNamed ('press' )
280+ tb .app .child (name = 'Inbox.*' , roleName = 'tree item' ).doActionNamed (
281+ 'activate' )
282+ except tree .SearchError :
283+ # TB < 115
284+ tb .app .child (name = 'user@localhost' ,
285+ roleName = 'table row' ).doActionNamed ('activate' )
286+ tb .app .button ('Get Messages' ).doActionNamed ('press' )
287+ tb .app .menuItem ('Get All New Messages' ).doActionNamed ('click' )
288+ tb .app .child (name = 'Inbox.*' , roleName = 'table row' ).doActionNamed (
289+ 'activate' )
290+
265291
266292def attach (tb , compose_window , path ):
267- compose_window .button ('Attach' ).button ('Attach' ).doActionNamed ('press' )
268- compose_window .button ('Attach' ).menuItem ('File.*' ).doActionNamed ('click' )
293+ try :
294+ # TB >= 128
295+ compose_window .child ('Attach' , roleName = 'button' ).\
296+ doActionNamed ('press' )
297+ compose_window .child ('Attach' , roleName = 'button' ).\
298+ menuItem ('File.*' ).doActionNamed ('click' )
299+ except tree .SearchError :
300+ # TB < 128
301+ compose_window .button ('Attach' ).button ('Attach' ).doActionNamed ('press' )
302+ compose_window .button ('Attach' ).menuItem ('File.*' ).doActionNamed ('click' )
269303 # for some reason on some thunderbird versions do not expose 'Attach File'
270304 # dialog through accessibility API, use xdotool instead
271305 subprocess .check_call (
@@ -293,18 +327,25 @@ def attach(tb, compose_window, path):
293327
294328def send_email (tb , sign = False , encrypt = False , inline = False , attachment = None ):
295329 config .searchCutoffCount = 20
296- write = tb .app .button ('Write' )
330+ try :
331+ # TB >= 128
332+ write = tb .app .child (name = 'New Message' , roleName = 'button' )
333+ except tree .SearchError :
334+ try :
335+ write = tb .app .button ('New Message' )
336+ except tree .SearchError :
337+ write = tb .app .button ('Write' )
297338 config .searchCutoffCount = defaultCutoffCount
298339 write .doActionNamed ('press' )
299340 compose = tb .app .child (name = 'Write: .*' , roleName = 'frame' )
300341 to_entry = compose .findChild (TBEntry (name = 'To' ))
301- to_entry .text = 'user@localhost'
342+ to_entry .typeText ( 'user@localhost' )
302343 # lets thunderbird settle down on default values (after filling recipients)
303344 time .sleep (1 )
304345 subject_entry = compose .findChild (
305346 orPredicate (GenericPredicate (name = 'Subject:' , roleName = 'entry' ),
306347 TBEntry (name = 'Subject' )))
307- subject_entry .text = subject
348+ subject_entry .typeText ( subject )
308349 try :
309350 compose_document = compose .child (roleName = 'document web' )
310351 try :
@@ -315,18 +356,29 @@ def send_email(tb, sign=False, encrypt=False, inline=False, attachment=None):
315356 except tree .SearchError :
316357 compose .child (
317358 roleName = 'document frame' ).text = 'This is test message'
318- security = compose .findChild (
319- GenericPredicate (name = 'Security' , roleName = 'push button' ))
359+ try :
360+ # TB >= 128
361+ security = compose .findChild (
362+ GenericPredicate (name = 'Security|OpenPGP' , roleName = 'button' ))
363+ except tree .SearchError :
364+ # TB < 128
365+ security = compose .findChild (
366+ GenericPredicate (name = 'Security|OpenPGP' , roleName = 'push button' ))
320367 security .doActionNamed ('press' )
321- sign_button = security .childNamed ('Digitally Sign This Message ' )
322- encrypt_button = security .childNamed ('Require Encryption' )
368+ sign_button = security .childNamed ('Digitally Sign.* ' )
369+ encrypt_button = security .childNamed ('Require Encryption|Encrypt ' )
323370 if sign_button .checked != sign :
324371 sign_button .doActionNamed ('click' )
325372 if encrypt_button .checked != encrypt :
326373 encrypt_button .doActionNamed ('click' )
327374 if attachment :
328375 attach (tb , compose , attachment )
329- compose .button ('Send' ).doActionNamed ('press' )
376+ try :
377+ # TB >= 128
378+ compose .child ('Send' , roleName = 'button' ).doActionNamed ('press' )
379+ except tree .SearchError :
380+ # TB < 128
381+ compose .button ('Send' ).doActionNamed ('press' )
330382 config .searchCutoffCount = 5
331383 try :
332384 if encrypt :
@@ -363,16 +415,36 @@ def send_email(tb, sign=False, encrypt=False, inline=False, attachment=None):
363415
364416def receive_message (tb , signed = False , encrypted = False , attachment = None ):
365417 get_messages (tb )
366- config .searchCutoffCount = 5
418+ if encrypted :
419+ config .searchCutoffCount = 5
420+ try :
421+ # TB >= 128
422+ tb .app .child (name = 'user[^,]*, .*, \.\.\..*' ,
423+ roleName = 'table row' ).doActionNamed ('clickAncestor' )
424+ except tree .SearchError :
425+ try :
426+ # TB >= 115
427+ tb .app .child (name = 'user[^,]*, .*, \.\.\..*' ,
428+ roleName = 'tree item' ).doActionNamed ('activate' )
429+ except tree .SearchError :
430+ # TB < 115
431+ tb .app .child (name = 'Encrypted Message .*|.*\.\.\. .*' ,
432+ roleName = 'table row' ).doActionNamed ('activate' )
433+ finally :
434+ config .searchCutoffCount = defaultCutoffCount
367435 try :
368- tb .app .child (name = 'Encrypted Message .*|.*\.\.\. .*' ,
369- roleName = 'table row' ).doActionNamed ('activate' )
436+ # TB >= 128
437+ tb .app .child (name = '.*{}.*' .format (subject ),
438+ roleName = 'table row' ).doActionNamed ('clickAncestor' )
370439 except tree .SearchError :
371- pass
372- finally :
373- config .searchCutoffCount = defaultCutoffCount
374- tb .app .child (name = '.*{}.*' .format (subject ),
375- roleName = 'table row' ).doActionNamed ('activate' )
440+ try :
441+ # TB >= 115
442+ tb .app .child (name = '.*{}.*' .format (subject ),
443+ roleName = 'tree item' ).doActionNamed ('activate' )
444+ except tree .SearchError :
445+ # TB < 115
446+ tb .app .child (name = '.*{}.*' .format (subject ),
447+ roleName = 'table row' ).doActionNamed ('activate' )
376448 # wait a little to TB decrypt/check the message
377449 time .sleep (2 )
378450 # dogtail always add '$' at the end of regexp; and also "Escape all
@@ -399,11 +471,10 @@ def receive_message(tb, signed=False, encrypted=False, attachment=None):
399471 # msg_body = msg.text
400472 config .searchCutoffCount = 5
401473 try :
402- if signed or encrypted :
403- tb .app .button ('OpenPGP.*' ).doActionNamed ('press' )
404- # 'Message Security - OpenPGP' is an internal label,
405- # nested 2 levels into the popup
406- message_security = tb .app .child ('Message Security - OpenPGP' )
474+ tb .app .button ('OpenPGP.*' ).doActionNamed ('press' )
475+ # 'Message Security - OpenPGP' is an internal label,
476+ # nested 2 levels into the popup
477+ message_security = tb .app .child ('Message Security - OpenPGP' )
407478 except tree .SearchError :
408479 # alternative way of opening 'message security'
409480 keyCombo ('<Control><Alt>s' )
@@ -430,8 +501,14 @@ def receive_message(tb, signed=False, encrypted=False, attachment=None):
430501 attachment_size = attachment_label .parent .children [
431502 attachment_label .indexInParent + 1 + offset ]
432503 assert attachment_size .text [0 ] != '0'
433- attachment_save = attachment_label .parent .children [
434- attachment_label .indexInParent + 2 + offset ].button ('Save.*' )
504+ attachment_save_parent = attachment_label .parent .children [
505+ attachment_label .indexInParent + 2 + offset ]
506+ try :
507+ # TB >= 128
508+ attachment_save = attachment_save_parent .child ('Save.*' , roleName = 'button' )
509+ except tree .SearchError :
510+ # TB < 128
511+ attachment_save = attachment_save_parent .button ('Save.*' )
435512 try :
436513 # try child button first
437514 attachment_save .children [1 ].doActionNamed ('press' )
@@ -444,11 +521,14 @@ def receive_message(tb, signed=False, encrypted=False, attachment=None):
444521 # for some reasons some Thunderbird versions do not expose 'Attach File'
445522 # dialog through accessibility API, use xdotool instead
446523 save_as = tb .app .findChild (
447- GenericPredicate (name = 'Save All Attachments' ,
524+ GenericPredicate (name = 'Save All Attachments|Save Attachment ' ,
448525 roleName = 'file chooser' ))
449526 click (* save_as .childNamed ('Home' ).position )
450527 click (* save_as .childNamed ('Desktop' ).position )
451- save_as .childNamed ('Open' ).doActionNamed ('click' )
528+ if save_as .name == 'Save Attachment' :
529+ save_as .childNamed ('Save' ).doActionNamed ('click' )
530+ else :
531+ save_as .childNamed ('Open' ).doActionNamed ('click' )
452532 # save_as = tb.app.dialog('Save .*Attachment.*')
453533 # places = save_as.child(roleName='table',
454534 # name='Places')
0 commit comments