source: main/waeup.kofa/trunk/src/waeup/kofa/doctests/batchprocessing_browser.txt @ 13418

Last change on this file since 13418 was 13394, checked in by Henrik Bettermann, 9 years ago

Implement portal maintenance mode.

File size: 20.5 KB
RevLine 
[12920]1Batch Processing via Browser
[4857]2****************************
3
[4869]4Preliminaries:
5
6We define a function that looks up a form with several submit buttons
7for the one with a given value (this functionality is missing in
8zope.testbrowser):
9
10    >>> def lookup_submit_value(name, value, browser):
11    ...   """Find a button with a certain value."""
12    ...   for num in range(0, 100):
13    ...     try:
14    ...       button = browser.getControl(name=name, index=num)
[4899]15    ...       if button.value.endswith(value):
[4869]16    ...         return button
17    ...     except IndexError:
18    ...       break
19    ...   return None
20
[4857]21Create a site:
22
[7811]23    >>> from waeup.kofa.app import University
[4857]24    >>> getRootFolder()['app'] = University()
[9312]25    >>> from zope.component.hooks import setSite
26    >>> setSite(getRootFolder()['app'])
[4857]27
28Create a datacenter storage path:
29
30    >>> import os
31    >>> import tempfile
32    >>> dc_path = tempfile.mkdtemp()
33
34Log in:
35
36    >>> from zope.testbrowser.testing import Browser
37    >>> browser = Browser()
38    >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
39    >>> browser.handleErrors = False
40
41Set datacenter path and deselect moving old data:
42
43    >>> browser.open('http://localhost/app')
44    >>> browser.getLink('Data Center').click()
45    >>> browser.getLink('Edit settings').click()
46    >>> browser.getControl(name='newpath').value = dc_path
47    >>> browser.getControl(name='move').value = False
48    >>> browser.getControl(name='save').click()
49
[6611]50Set non-usable datacenter path:
51
52    >>> browser.getLink('Edit settings').click()
53    >>> browser.getControl(name='newpath').value = '/'
54    >>> browser.getControl(name='save').click()
55    >>> 'Given storage path cannot be used.' in browser.contents
56    True
[11254]57    >>> browser.getControl('Back to Data Center').click()
[6611]58
59
[12920]60Batch Processing Faculties
[4857]61==========================
62
63Go to datacenter page:
64
65    >>> browser.open('http://localhost/app/datacenter')
66
[9919]67Prepare a CSV file for faculties (extended ascii values are accepted):
[4857]68
69    >>> open('faculties.csv', 'wb').write(
[6823]70    ... """code,title,title_prefix
71    ... FAC1,Faculty 1,faculty
72    ... FAC2,Faculty 2,institute
[9919]73    ... FAC3,Fäcülty 3,school
[4857]74    ... """)
75
76Upload the file:
77
78    >>> import cStringIO
[9024]79    >>> browser.getLink('Upload data').click()
[4857]80    >>> filecontents = cStringIO.StringIO(
81    ...   open('faculties.csv', 'rb').read())
82    >>> filewidget = browser.getControl(name='uploadfile:file')
83    >>> filewidget.add_file(filecontents, 'text/plain', 'faculties.csv')
84    >>> browser.getControl(name='SUBMIT').click()
85
86Step 1: start batch processing:
87
[13394]88    >>> browser.getLink('Switch maintenance mode').click()
[9024]89    >>> browser.getLink('Process data').click()
[4869]90    >>> button = lookup_submit_value(
91    ...   'select', 'faculties_zope.mgr.csv', browser)
92    >>> button.click()
[4857]93
94Step 2: select a processor and mode:
95
96    >>> importerselect = browser.getControl(name='importer')
97    >>> importerselect.displayOptions
[12439]98    ['AccessCodeBatch Processor',
99    'AccessCode Processor',
100    'Applicant Processor',
101    'ApplicantsContainer Processor',
102    'CertificateCourse Processor',
103    'Certificate Processor',
[9420]104    'Course Processor',
[9418]105    'CourseTicket Processor',
[12439]106    'Department Processor',
107    'Faculty Processor',
[9203]108    'Hostel Processor',
[12439]109    'Public HTML Document Processor',
110    'StudentOnlinePayment Processor',
111    'Public PDF Document Processor',
112    'Public REST Document Processor',
113    'Student Processor',
[7954]114    'StudentStudyCourse Processor (update only)',
[8973]115    'StudentStudyLevel Processor',
116    'User Processor',
[9418]117    'Verdict Processor (special processor, update only)']
[4857]118
[7933]119    >>> importerselect.getControl('Faculty Processor').selected = True
[4857]120
121    >>> modeselect = browser.getControl(name='mode')
122    >>> modeselect.options
123    ['create', 'update', 'remove']
124
125    >>> modeselect.getControl(value='create').selected = True
[7705]126    >>> browser.getControl('Proceed to step 3').click()
[4857]127
128Step 3: Fix headerlines
129
130We get informed that there are no problems with the current header:
131
132    >>> print browser.contents
133    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
134    ...
135    Header fields OK
136    ...
137
138The submit button is enabled:
139
[7705]140    >>> browser.getControl('Perform import').disabled
[4857]141    False
142
[7705]143    >>> browser.getControl('Perform import').click()
[4857]144
145Step 4: See import results
146
147The import was successful:
148
149    >>> print browser.contents
150    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
151    ...Successfully processed 3 rows...
152    ...Batch processing finished...
153    ...File:...faculties_zope.mgr.csv...
154
[7749]155We can grep the entries generated in logfile:
[4857]156
[10099]157    >>> browser.open('http://localhost/app/datacenter/logs')
158    >>> browser.getControl('Show', index=0).click()
[4857]159    >>> print browser.contents
160    <!DOCTYPE ...
[10207]161    ...<h1 class="kofa-content-label">Logfile datacenter.log</h1>...
[4857]162
[7749]163    >>> browser.getControl(name='query').value = "zope.mgr"
164    >>> browser.getControl('Search').click()
[9739]165    >>> 'zope.mgr - processed' in browser.contents
[7749]166    True
[4857]167
[7749]168
[12920]169Batch Processing Departments
[4857]170============================
171
172    >>> browser.open('http://localhost/app/datacenter')
173
174Prepare a CSV file for departments:
175
176    >>> open('departments.csv', 'wb').write(
[6823]177    ... """code,faculty_code,title,title_prefix
178    ... DEP1,FAC1,Department 1,department
179    ... DEP2,FAC2,Department 2,centre
[4857]180    ... """)
181
182Upload the file:
183
184    >>> import cStringIO
[9024]185    >>> browser.getLink('Upload data').click()
[4857]186    >>> filecontents = cStringIO.StringIO(
187    ...   open('departments.csv', 'rb').read())
188    >>> filewidget = browser.getControl(name='uploadfile:file')
189    >>> filewidget.add_file(filecontents, 'text/plain', 'departments.csv')
190    >>> browser.getControl(name='SUBMIT').click()
191
192Step 1: start batch processing:
193
[13394]194    >>> browser.getLink('Switch maintenance mode').click()
[9024]195    >>> browser.getLink('Process data').click()
[4869]196    >>> button = lookup_submit_value(
197    ...   'select', 'departments_zope.mgr.csv', browser)
198    >>> button.click()
[4857]199
200Step 2: select a processor and mode:
201
202    >>> importerselect = browser.getControl(name='importer')
[7933]203    >>> importerselect.getControl('Department Processor').selected = True
[4857]204    >>> modeselect = browser.getControl(name='mode')
205    >>> modeselect.getControl(value='create').selected = True
[7705]206    >>> browser.getControl('Proceed to step 3').click()
[4857]207
208Step 3: Fix headerlines
209
210We get informed that there are no problems with the current header:
211
212    >>> print browser.contents
213    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
214    ...
215    Header fields OK
216    ...
217
218The submit button is enabled:
219
[7705]220    >>> browser.getControl('Perform import').disabled
[4857]221    False
222
[7705]223    >>> browser.getControl('Perform import').click()
[4857]224
225Step 4: See import results
226
227The import was successful:
228
229    >>> print browser.contents
230    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
231    ...Successfully processed 2 rows...
232    ...Batch processing finished...
233    ...File:...departments_zope.mgr.csv...
234
[12920]235Batch Processing Courses
[4857]236========================
237
238    >>> browser.open('http://localhost/app/datacenter')
239
240Prepare a CSV file for courses:
241
242    >>> open('courses.csv', 'wb').write(
243    ... """code,faculty_code,department_code,title,level,passmark,credits,semester
244    ... CRS1,FAC1,DEP1,Course 1,100,40,2,1
245    ... CRS2,FAC1,DEP1,Course 2,100,40,2,2
246    ... """)
247
248Upload the file:
249
250    >>> import cStringIO
[9024]251    >>> browser.getLink('Upload data').click()
[4857]252    >>> filecontents = cStringIO.StringIO(
253    ...   open('courses.csv', 'rb').read())
254    >>> filewidget = browser.getControl(name='uploadfile:file')
255    >>> filewidget.add_file(filecontents, 'text/plain', 'courses.csv')
256    >>> browser.getControl(name='SUBMIT').click()
257
258Step 1: start batch processing:
259
[13394]260    >>> browser.getLink('Switch maintenance mode').click()
[9024]261    >>> browser.getLink('Process data').click()
[4869]262    >>> button = lookup_submit_value(
263    ...   'select', 'courses_zope.mgr.csv', browser)
264    >>> button.click()
[4857]265
266Step 2: select a processor and mode:
267
268    >>> importerselect = browser.getControl(name='importer')
[7954]269    >>> importerselect.getControl('Course Processor', index=1).selected = True
[4857]270    >>> modeselect = browser.getControl(name='mode')
271    >>> modeselect.getControl(value='create').selected = True
[7705]272    >>> browser.getControl('Proceed to step 3').click()
[4857]273
274Step 3: Fix headerlines
275
276We get informed that there are no problems with the current header:
277
278    >>> print browser.contents
279    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
280    ...
281    Header fields OK
282    ...
283
284The submit button is enabled:
285
[7705]286    >>> browser.getControl('Perform import').disabled
[4857]287    False
288
[7705]289    >>> browser.getControl('Perform import').click()
[4857]290
291Step 4: See import results
292
293The import was successful:
294
295    >>> print browser.contents
296    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
297    ...Successfully processed 2 rows...
298    ...Batch processing finished...
299    ...File:...courses_zope.mgr.csv...
300
[12920]301Batch Processing Certificates
[4857]302=============================
303
304    >>> browser.open('http://localhost/app/datacenter')
305
306Prepare a CSV file for certificates:
307
308    >>> open('certificates.csv', 'wb').write(
[5947]309    ... """code,faculty_code,department_code,title,study_mode,start_level,end_level,application_category
[8472]310    ... CERT1,FAC1,DEP1,Certificate 1,pg_ft,999,999,basic
[5986]311    ... CERT2,FAC1,DEP1,Certificate 2,ug_ft,200,300,cest
[4857]312    ... """)
313
314Upload the file:
315
316    >>> import cStringIO
[9024]317    >>> browser.getLink('Upload data').click()
[4857]318    >>> filecontents = cStringIO.StringIO(
319    ...   open('certificates.csv', 'rb').read())
320    >>> filewidget = browser.getControl(name='uploadfile:file')
321    >>> filewidget.add_file(filecontents, 'text/plain', 'certificates.csv')
322    >>> browser.getControl(name='SUBMIT').click()
323
324Step 1: start batch processing:
325
[13394]326    >>> browser.getLink('Switch maintenance mode').click()
[9024]327    >>> browser.getLink('Process data').click()
[4869]328    >>> button = lookup_submit_value(
329    ...   'select', 'certificates_zope.mgr.csv', browser)
330    >>> button.click()
[4857]331
[4869]332
[4857]333Step 2: select a processor and mode:
334
335    >>> importerselect = browser.getControl(name='importer')
[7933]336    >>> importerselect.getControl('Certificate Processor').selected = True
[4857]337    >>> modeselect = browser.getControl(name='mode')
338    >>> modeselect.getControl(value='create').selected = True
[7705]339    >>> browser.getControl('Proceed to step 3').click()
[4857]340
341Step 3: Fix headerlines
342
343We get informed that there are no problems with the current header:
344
345    >>> print browser.contents
346    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
347    ...
348    Header fields OK
349    ...
350
351The submit button is enabled:
352
[7705]353    >>> browser.getControl('Perform import').disabled
[4857]354    False
355
[7705]356    >>> browser.getControl('Perform import').click()
[4857]357
358Step 4: See import results
359
360The import was successful:
361
362    >>> print browser.contents
363    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
364    ...Successfully processed 2 rows...
365    ...Batch processing finished...
366    ...File:...certificates_zope.mgr.csv...
367
[12920]368Batch Processing Certificate Courses
[4857]369====================================
370
371    >>> browser.open('http://localhost/app/datacenter')
372
373Prepare a CSV file for certificate courses:
374
375    >>> open('mycertcourses.csv', 'wb').write(
[7665]376    ... """course,faculty_code,department_code,certificate_code,level,mandatory
[4857]377    ... CRS1,FAC1,DEP1,CERT1,100,True
378    ... CRS2,FAC1,DEP1,CERT1,100,True
379    ... """)
380
381Upload the file:
382
383    >>> import cStringIO
[9024]384    >>> browser.getLink('Upload data').click()
[4857]385    >>> filecontents = cStringIO.StringIO(
386    ...   open('mycertcourses.csv', 'rb').read())
387    >>> filewidget = browser.getControl(name='uploadfile:file')
388    >>> filewidget.add_file(filecontents, 'text/plain', 'mycertcourses.csv')
389    >>> browser.getControl(name='SUBMIT').click()
390
391Step 1: start batch processing:
392
[13394]393    >>> browser.getLink('Switch maintenance mode').click()
[9024]394    >>> browser.getLink('Process data').click()
[4869]395    >>> button = lookup_submit_value(
396    ...   'select', 'mycertcourses_zope.mgr.csv', browser)
397    >>> button.click()
[4857]398
399Step 2: select a processor and mode:
400
401    >>> importerselect = browser.getControl(name='importer')
[7933]402    >>> importerselect.getControl('CertificateCourse Processor').selected = True
[4857]403    >>> modeselect = browser.getControl(name='mode')
404    >>> modeselect.getControl(value='create').selected = True
[7705]405    >>> browser.getControl('Proceed to step 3').click()
[4857]406
407Step 3: Fix headerlines
408
409We get informed that there are no problems with the current header:
410
411    >>> print browser.contents
412    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
413    ...
414    Header fields OK
415    ...
416
417The submit button is enabled:
418
[7705]419    >>> browser.getControl('Perform import').disabled
[4857]420    False
421
[7705]422    >>> browser.getControl('Perform import').click()
[4857]423
424Step 4: See import results
425
426The import was successful:
427
428    >>> print browser.contents
429    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
430    ...Successfully processed 2 rows...
431    ...Batch processing finished...
432    ...File:...mycertcourses_zope.mgr.csv...
433
[12920]434Batch Processing Users
[8973]435======================
[4857]436
[8973]437    >>> browser.open('http://localhost/app/datacenter')
438
[9203]439Prepare a CSV file for users:
[8973]440
441    >>> open('users.csv', 'wb').write(
[8976]442    ... """name,title,public_name,email,phone,roles
[9310]443    ... uli,Uli Fouquet,Chief Developer,uli@abc.de,+49-234-567,[]
444    ... henrik,Henrik Bettermann,Admin,henrik@abc.de,+49-234-567,"['waeup.PortalManager', 'waeup.ImportManager']"
[12190]445    ... anne,Anne Palina,,anne@abc.de,+49-234-567,"['waeup.Nonsense']"
[8973]446    ... """)
447
448Upload the file:
449
450    >>> import cStringIO
[9024]451    >>> browser.getLink('Upload data').click()
[8973]452    >>> filecontents = cStringIO.StringIO(
453    ...   open('users.csv', 'rb').read())
454    >>> filewidget = browser.getControl(name='uploadfile:file')
455    >>> filewidget.add_file(filecontents, 'text/plain', 'users.csv')
456    >>> browser.getControl(name='SUBMIT').click()
457
458Step 1: start batch processing:
459
[13394]460    >>> browser.getLink('Switch maintenance mode').click()
[9024]461    >>> browser.getLink('Process data').click()
[8973]462    >>> button = lookup_submit_value(
463    ...   'select', 'users_zope.mgr.csv', browser)
464    >>> button.click()
465
466Step 2: select a processor and mode:
467
468    >>> importerselect = browser.getControl(name='importer')
469    >>> importerselect.getControl('User Processor').selected = True
470    >>> modeselect = browser.getControl(name='mode')
471    >>> modeselect.getControl(value='create').selected = True
472    >>> browser.getControl('Proceed to step 3').click()
473
474Step 3: Fix headerlines
475
476We get informed that there are no problems with the current header:
477
478    >>> print browser.contents
479    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
480    ...
481    Header fields OK
482    ...
483
484The submit button is enabled:
485
486    >>> browser.getControl('Perform import').disabled
487    False
488
489    >>> browser.getControl('Perform import').click()
490
491Step 4: See import results
492
493The import was successful:
494
495    >>> print browser.contents
496    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
497    ...Successfully processed 2 rows...
498    ...Batch processing finished...
499    ...File:...users_zope.mgr.csv...
500
[9310]501User henrik has got the global roles:
502
503   >>> henrik = getRootFolder()['app']['users']['henrik']
504   >>> henrik.roles
[9312]505   ['waeup.PortalManager', 'waeup.AcademicsOfficer', 'waeup.ImportManager']
[9310]506
[12920]507Pending Files
[4899]508=============
509
510When an error occurs during an import, two files are generated: a CSV
511file with finished files and a CSV file with pending data. Both are
512stored in the appropriate subdirectories in datacenter. We try to
513create faculties, from which one already exists.
514
515Go to datacenter page:
516
517    >>> browser.open('http://localhost/app/datacenter')
518
519Prepare a CSV file for faculties:
520
521    >>> open('newfaculties.csv', 'wb').write(
[6823]522    ... """code,title,title_prefix
523    ... FAC1,Faculty 1,faculty
524    ... FAC4,Faculty 4,school
[12191]525    ... FAC 5,Faculty 5,faculty
[4899]526    ... """)
527
528Upload the file:
529
530    >>> import cStringIO
[9024]531    >>> browser.getLink('Upload data').click()
[4899]532    >>> filecontents = cStringIO.StringIO(
533    ...   open('newfaculties.csv', 'rb').read())
534    >>> filewidget = browser.getControl(name='uploadfile:file')
535    >>> filewidget.add_file(filecontents, 'text/plain', 'newfaculties.csv')
536    >>> browser.getControl(name='SUBMIT').click()
537
[9310]538Since we now have a user with waeup.ImportManager role, an email has been sent:
539    >>> print browser.contents
540    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
541    ...
542    ...All import managers have been notified by email...
543    ...
544
[4899]545Step 1: start batch processing:
546
[13394]547    >>> browser.getLink('Switch maintenance mode').click()
[9024]548    >>> browser.getLink('Process data').click()
[4899]549    >>> button = lookup_submit_value(
550    ...   'select', 'newfaculties_zope.mgr.csv', browser)
551    >>> button.click()
552
553Step 2: select a processor and mode:
554
555    >>> importerselect = browser.getControl(name='importer')
[7933]556    >>> importerselect.getControl('Faculty Processor').selected = True
[4899]557    >>> modeselect = browser.getControl(name='mode')
558    >>> modeselect.getControl(value='create').selected = True
[7705]559    >>> browser.getControl('Proceed to step 3').click()
[4899]560
561Step 3: Fix headerlines
562
563As there should be no problem with the headers, we can immediately
564perfom the import:
565
[7705]566    >>> browser.getControl('Perform import').click()
[4899]567
[12191]568Two lines could not be imported:
[4899]569
570    >>> print browser.contents
571    <!DOCTYPE html PUBLIC...
572    ...
[12191]573    ...Processing of 2 rows failed...
[4899]574    ...Successfully processed 1 rows...
575    ...
576
577Now there are two files as a result in datacenter storage's root and
578``finished`` dirs:
579
[4998]580    >>> pending_file = dc_path + '/newfaculties_zope.mgr.create.pending.csv'
[4899]581    >>> print open(pending_file).read()
[6824]582    title_prefix,code,title,--ERRORS--
[12868]583    faculty,FAC1,Faculty 1,This object already exists.
[12415]584    faculty,FAC 5,Faculty 5,code: Invalid input
[4899]585
[4998]586    >>> finished_file = dc_path + '/finished/newfaculties_zope.mgr.create.finished.csv'
[4899]587    >>> print open(finished_file).read()
[6824]588    title_prefix,code,title
[6823]589    school,FAC4,Faculty 4
[4899]590
591The finished-file contains the dataset we could import, while the
592pending file contains the dataset that failed, appended by an error
593message.
594
595
[12920]596Fixing the Pending File
[4981]597-----------------------
598
599We 'edit' the pending file (setting code to ``FAC5`` and title
600appropriately, and removing the --ERROR-- column) and finish the
601import this way:
602
[4998]603    >>> open(dc_path + '/newfaculties_zope.mgr.create.pending.csv', 'wb').write(
[4981]604    ... """title_prefix,--IGNORE--,code,title
[12191]605    ... faculty,,FAC5,Faculty 5
[4981]606    ... """)
607
608Step 1: start batch processing:
609
610    >>> browser.open('http://localhost/app/datacenter')
[13394]611    >>> browser.getLink('Switch maintenance mode').click()
[9024]612    >>> browser.getLink('Process data').click()
[4981]613    >>> button = lookup_submit_value(
[4998]614    ...   'select', 'newfaculties_zope.mgr.create.pending.csv', browser)
[4981]615    >>> button.click()
616
617Step 2: select a processor and mode:
618
619    >>> importerselect = browser.getControl(name='importer')
[7933]620    >>> importerselect.getControl('Faculty Processor').selected = True
[4981]621    >>> modeselect = browser.getControl(name='mode')
622    >>> modeselect.getControl(value='create').selected = True
[7705]623    >>> browser.getControl('Proceed to step 3').click()
[4981]624
625Step 3/4: Fix headerlines and import:
626
627As there should be no problem with the headers, we can immediately
628perfom the import:
629
[7705]630    >>> browser.getControl('Perform import').click()
[4981]631
632This time everything should work:
633
634    >>> print browser.contents
635    <!DOCTYPE html PUBLIC...
636    ...
637    ...Successfully processed 1 rows...
638    ...
639
[12190]640Oh no, we forgot Anne Palina. Her user record was not imported because
641she has a non-existent role:
642
[4981]643    >>> sorted(os.listdir(dc_path))
[12190]644    ['deleted', 'finished', 'logs', 'unfinished', 'users_zope.mgr.create.pending.csv']
[4981]645
646    >>> os.listdir(dc_path + '/unfinished')
[12190]647    ['users_zope.mgr.csv']
[4981]648
[12190]649    >>> pending_file = dc_path + '/users_zope.mgr.create.pending.csv'
650    >>> print open(pending_file).read()
651    name,roles,title,public_name,phone,email,--ERRORS--
[12981]652    anne,['waeup.Nonsense'],Anne Palina,<IGNORE>,+49-234-567,anne@abc.de,roles: invalid role
[12190]653
654There are many finished-files:
655
[4981]656    >>> sorted(os.listdir(dc_path + '/finished'))
[8372]657    ['certificates_zope.mgr.create.finished.csv', ...,
[12190]658    'users_zope.mgr.create.finished.csv']
[4981]659
[9023]660Processed (finished) Files
661==========================
[4981]662
[9023]663    >>> browser.open('http://localhost/app/datacenter/processed')
[11460]664    >>> 'download?filename=finished/certificates_zope.mgr.create.finished.csv' in browser.contents
[9023]665    True
666
[6608]667Log Files
668=========
669
670    >>> browser.open('http://localhost/app/datacenter/logs')
671    >>> 'datacenter.log' in browser.contents
672    True
[6754]673    >>> browser.getControl('Show', index=0).click()
[6611]674    >>> browser.getControl('Back', index=0).click()
675    >>> browser.getControl('Back to Data Center').click()
676    >>> 'Storage path:' in browser.contents
677    True
[6608]678
679
[4857]680Clean up:
681
682    >>> import shutil
[6734]683    >>> shutil.rmtree(dc_path)
Note: See TracBrowser for help on using the repository browser.