Merge lp:~pedro/mago/gnome-about-me into lp:~mago-contributors/mago/mago-1.0
- gnome-about-me
- Merge into mago-1.0
Proposed by
Pedro Villavicencio
Status: | Merged |
---|---|
Merged at revision: | 145 |
Proposed branch: | lp:~pedro/mago/gnome-about-me |
Merge into: | lp:~mago-contributors/mago/mago-1.0 |
Diff against target: |
453 lines (+420/-0) 6 files modified
gnome-about-me/README (+21/-0) gnome-about-me/data/avatar.svg (+138/-0) gnome-about-me/gnome_about_me_tests.py (+69/-0) gnome-about-me/gnome_about_me_tests.xml (+29/-0) mago/application/gnome_about_me.py (+140/-0) mago/test_suite/gnome_about_me.py (+23/-0) |
To merge this branch: | bzr merge lp:~pedro/mago/gnome-about-me |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Nagappan Alagappan | Approve | ||
Review via email: mp+41608@code.launchpad.net |
Commit message
Description of the change
Tests for Gnome About me, the tests change the user personal information and do checking to see if the right info was added,
as said they will change the user personal info so please be careful if you have useful information in the about-me or evolution
for your profile, but they don't touch any password on the system. Available tests are:
* Change Text values.
* Change Photo to PNG.
* Change Photo to SVG.
* Clean up values and check.
Those need to be ported to e-d-s in the future using evolution-python or dbus.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added directory 'gnome-about-me' |
2 | === added file 'gnome-about-me/README' |
3 | --- gnome-about-me/README 1970-01-01 00:00:00 +0000 |
4 | +++ gnome-about-me/README 2010-11-23 14:54:13 +0000 |
5 | @@ -0,0 +1,21 @@ |
6 | +GNOME ABOUT ME TESTS |
7 | +==================== |
8 | + |
9 | +Safety |
10 | +------ |
11 | + |
12 | +The tests will change the user personal information previously added, so please be careful if you have useful information |
13 | +in the about-me or evolution for your profile, but they don't touch any password on the system. |
14 | + |
15 | +Configuration |
16 | +------------- |
17 | + |
18 | +The tests don't need any special configuration. |
19 | + |
20 | +Available Tests |
21 | +--------------- |
22 | + |
23 | +* Change Text values. |
24 | +* Change Photo to PNG. |
25 | +* Change Photo to SVG. |
26 | +* Clean up values and check. |
27 | |
28 | === added directory 'gnome-about-me/data' |
29 | === added file 'gnome-about-me/data/avatar.png' |
30 | Binary files gnome-about-me/data/avatar.png 1970-01-01 00:00:00 +0000 and gnome-about-me/data/avatar.png 2010-11-23 14:54:13 +0000 differ |
31 | === added file 'gnome-about-me/data/avatar.svg' |
32 | --- gnome-about-me/data/avatar.svg 1970-01-01 00:00:00 +0000 |
33 | +++ gnome-about-me/data/avatar.svg 2010-11-23 14:54:13 +0000 |
34 | @@ -0,0 +1,138 @@ |
35 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
36 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> |
37 | +<svg |
38 | + xmlns:dc="http://purl.org/dc/elements/1.1/" |
39 | + xmlns:cc="http://web.resource.org/cc/" |
40 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
41 | + xmlns:svg="http://www.w3.org/2000/svg" |
42 | + xmlns="http://www.w3.org/2000/svg" |
43 | + xmlns:xlink="http://www.w3.org/1999/xlink" |
44 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
45 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
46 | + width="48px" |
47 | + height="48px" |
48 | + id="svg1872" |
49 | + sodipodi:version="0.32" |
50 | + inkscape:version="0.44" |
51 | + sodipodi:docbase="/home/luca/Artwork/blackwhite-icon-theme/scalable/emotes" |
52 | + sodipodi:docname="face-smile-big.svg"> |
53 | + <defs |
54 | + id="defs1874" /> |
55 | + <sodipodi:namedview |
56 | + id="base" |
57 | + pagecolor="#ffffff" |
58 | + bordercolor="#666666" |
59 | + borderopacity="1.0" |
60 | + inkscape:pageopacity="0.0" |
61 | + inkscape:pageshadow="2" |
62 | + inkscape:zoom="14.729167" |
63 | + inkscape:cx="24" |
64 | + inkscape:cy="24" |
65 | + inkscape:current-layer="layer1" |
66 | + showgrid="true" |
67 | + inkscape:grid-bbox="true" |
68 | + inkscape:document-units="px" |
69 | + inkscape:grid-points="true" |
70 | + inkscape:window-width="1274" |
71 | + inkscape:window-height="921" |
72 | + inkscape:window-x="0" |
73 | + inkscape:window-y="25" /> |
74 | + <metadata |
75 | + id="metadata1877"> |
76 | + <rdf:RDF> |
77 | + <cc:Work |
78 | + rdf:about=""> |
79 | + <dc:format>image/svg+xml</dc:format> |
80 | + <dc:type |
81 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
82 | + <dc:title>Face smile </dc:title> |
83 | + <dc:creator> |
84 | + <cc:Agent> |
85 | + <dc:title>Luca Ferretti <elle.uca@libero.it></dc:title> |
86 | + </cc:Agent> |
87 | + </dc:creator> |
88 | + <dc:subject> |
89 | + <rdf:Bag> |
90 | + <rdf:li>face</rdf:li> |
91 | + <rdf:li>smiley</rdf:li> |
92 | + <rdf:li>happy</rdf:li> |
93 | + <rdf:li>smile big</rdf:li> |
94 | + <rdf:li>:-D</rdf:li> |
95 | + </rdf:Bag> |
96 | + </dc:subject> |
97 | + <cc:license |
98 | + rdf:resource="http://creativecommons.org/licenses/LGPL/2.1/" /> |
99 | + </cc:Work> |
100 | + <cc:License |
101 | + rdf:about="http://creativecommons.org/licenses/LGPL/2.1/"> |
102 | + <cc:permits |
103 | + rdf:resource="http://web.resource.org/cc/Reproduction" /> |
104 | + <cc:permits |
105 | + rdf:resource="http://web.resource.org/cc/Distribution" /> |
106 | + <cc:requires |
107 | + rdf:resource="http://web.resource.org/cc/Notice" /> |
108 | + <cc:permits |
109 | + rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> |
110 | + <cc:requires |
111 | + rdf:resource="http://web.resource.org/cc/ShareAlike" /> |
112 | + <cc:requires |
113 | + rdf:resource="http://web.resource.org/cc/SourceCode" /> |
114 | + </cc:License> |
115 | + </rdf:RDF> |
116 | + </metadata> |
117 | + <g |
118 | + id="layer1" |
119 | + inkscape:label="Layer 1" |
120 | + inkscape:groupmode="layer"> |
121 | + <path |
122 | + sodipodi:type="arc" |
123 | + style="fill:white;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" |
124 | + id="path3653" |
125 | + sodipodi:cx="24" |
126 | + sodipodi:cy="24" |
127 | + sodipodi:rx="24" |
128 | + sodipodi:ry="24" |
129 | + d="M 48 24 A 24 24 0 1 1 0,24 A 24 24 0 1 1 48 24 z" /> |
130 | + <path |
131 | + sodipodi:type="arc" |
132 | + style="fill:black;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" |
133 | + id="path1880" |
134 | + sodipodi:cx="23.932585" |
135 | + sodipodi:cy="23.932585" |
136 | + sodipodi:rx="20.022472" |
137 | + sodipodi:ry="20.022472" |
138 | + d="M 43.955057 23.932585 A 20.022472 20.022472 0 1 1 3.9101124,23.932585 A 20.022472 20.022472 0 1 1 43.955057 23.932585 z" /> |
139 | + <path |
140 | + sodipodi:type="arc" |
141 | + style="fill:white;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" |
142 | + id="path4540" |
143 | + sodipodi:cx="24" |
144 | + sodipodi:cy="24" |
145 | + sodipodi:rx="16" |
146 | + sodipodi:ry="16" |
147 | + d="M 40 24 A 16 16 0 1 1 8,24 A 16 16 0 1 1 40 24 z" /> |
148 | + <path |
149 | + sodipodi:type="arc" |
150 | + style="fill:black;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" |
151 | + id="path5427" |
152 | + sodipodi:cx="15" |
153 | + sodipodi:cy="18" |
154 | + sodipodi:rx="4" |
155 | + sodipodi:ry="6.07096" |
156 | + d="M 19 18 A 4 6.07096 0 1 1 11,18 A 4 6.07096 0 1 1 19 18 z" |
157 | + transform="translate(2,0)" /> |
158 | + <path |
159 | + style="fill:black;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" |
160 | + d="M 34,28 C 27.49505,28 21,28 14,28 C 18,38 30,38 34,28 z " |
161 | + id="path6316" |
162 | + sodipodi:nodetypes="ccc" /> |
163 | + <use |
164 | + x="0" |
165 | + y="0" |
166 | + xlink:href="#path5427" |
167 | + id="use7203" |
168 | + transform="translate(14,0)" |
169 | + width="48" |
170 | + height="48" /> |
171 | + </g> |
172 | +</svg> |
173 | |
174 | === added file 'gnome-about-me/gnome_about_me_tests.py' |
175 | --- gnome-about-me/gnome_about_me_tests.py 1970-01-01 00:00:00 +0000 |
176 | +++ gnome-about-me/gnome_about_me_tests.py 2010-11-23 14:54:13 +0000 |
177 | @@ -0,0 +1,69 @@ |
178 | +# -*- coding: utf-8 -*- |
179 | +import os |
180 | +from time import time, gmtime, strftime |
181 | + |
182 | +from mago.test_suite.gnome_about_me import GnomeAboutMeTestSuite |
183 | + |
184 | +class GnomeAboutMeTests(GnomeAboutMeTestSuite): |
185 | + |
186 | + #define values for the texts inside the about me dialog. |
187 | + values = { "txtAIM/iChat" : "299010@190019.net", |
188 | + "txtAddress" : "742 Evergreen Terrace", |
189 | + "txtAddress1" : "bibendum, urna sem ipsum, ultricies a, imperdiet ut, ligula. Cras tempus enim", |
190 | + "txtAssistant" : "John Doe", |
191 | + "txtCalendar" : "123", |
192 | + "txtCity" : "Springfield", |
193 | + "txtCity1" : "Santiago", |
194 | + "txtCompany" : "Springfield Nuclear Power Plant", |
195 | + "txtCountry" : "Pitcairn Islands", |
196 | + "txtCountry1" : "Monaco", |
197 | + "txtDepartment" : "digr gal-gal-gu-ne-ra", |
198 | + "txtGroupWise" : "9190190190@91091901901.com", |
199 | + "txtHome" : "119111@91191919.com", |
200 | + "txtHome1" : "0191939102", |
201 | + "txtHomepage" : "bloh@blah.com", |
202 | + "txtICQ" : "89123281290", |
203 | + "txtMSN" : "912101@91090.com", |
204 | + "txtManager" : "fringilla sollicitudin, odio at libero. Aliquam in massa non nunc. Sed males", |
205 | + "txtMobile" : "1231313132132", |
206 | + "txtPObox" : "9193910919129", |
207 | + "txtPObox1" : "9190190190910", |
208 | + "txtProfession" : "spendisse diam. Pellentesque scelerisque vel, lacinia quam at arcu turpis non tincidunt rutrum molesti", |
209 | + "txtState/Province" : "Adamstown", |
210 | + "txtState/Province1" : "Bounty Bay", |
211 | + "txtTitle" : "se platea dictumst. Duis ut mauris mattis eget, bibendum leo, aliquet tincid", |
212 | + "txtWeblog" : "iam. Pellentesque scelerisque vel, lacinia quam", |
213 | + "txtWork" : "91929010921@9019191.com", |
214 | + "txtWork1" : "n odio. Donec sollicitudin posuere, odio. Nam eu sodal", |
215 | + "txtWorkfax" : "1290390190", |
216 | + "txtXMPP" : "9012391290@90191901.com", |
217 | + "txtYahoo" : "901921901901@01219191.com", |
218 | + "txtZIP/Postalcode" : "123456789", |
219 | + "txtZIP/Postalcode1" : "987654321" |
220 | + } |
221 | + |
222 | + def change_text_values(self): |
223 | + |
224 | + self.application.file_values(self.values) |
225 | + #Re open the window and check if the values presented |
226 | + #to the users are the ones we added before. |
227 | + #if they are not the check_values method will raise an exception. |
228 | + self.application.open() |
229 | + |
230 | + self.application.check_values(self.values) |
231 | + |
232 | + def change_picture_to_png(self, photo_path): |
233 | + path = os.path.join(self.get_test_dir(), photo_path) |
234 | + self.application.change_picture(path) |
235 | + |
236 | + def change_picture_to_svg(self, photo_path): |
237 | + path = os.path.join(self.get_test_dir(), photo_path) |
238 | + self.application.change_picture(path) |
239 | + |
240 | + def clean_up_fields_and_picture(self): |
241 | + self.application.change_picture_to_default() |
242 | + self.application.clean_up_text_values(self.values) |
243 | + |
244 | +if __name__ == "__main__": |
245 | + gnome_about_me_test = GnomeAboutMeTests() |
246 | + gnome_about_me_test.run() |
247 | |
248 | === added file 'gnome-about-me/gnome_about_me_tests.xml' |
249 | --- gnome-about-me/gnome_about_me_tests.xml 1970-01-01 00:00:00 +0000 |
250 | +++ gnome-about-me/gnome_about_me_tests.xml 2010-11-23 14:54:13 +0000 |
251 | @@ -0,0 +1,29 @@ |
252 | +<?xml version="1.0"?> |
253 | +<suite name="GnomeAboutMe"> |
254 | + <class>gnome_about_me_tests.GnomeAboutMeTests</class> |
255 | + <description> |
256 | + Tests which verify Gnome_about_me basics functionality. |
257 | + </description> |
258 | + <case name="Change Text Values"> |
259 | + <method>change_text_values</method> |
260 | + <description>Change the text values of about me and check if they were saved correctly</description> |
261 | + </case> |
262 | + <case name="Change Picture to PNG"> |
263 | + <method>change_picture_to_png</method> |
264 | + <description>Change the picture to a PNG image</description> |
265 | + <args> |
266 | + <photo_path>data/avatar.png</photo_path> |
267 | + </args> |
268 | + </case> |
269 | + <case name="Change Picture to SVG"> |
270 | + <method>change_picture_to_svg</method> |
271 | + <description>Changethe picture to a SVG image</description> |
272 | + <args> |
273 | + <photo_path>data/avatar.svg</photo_path> |
274 | + </args> |
275 | + </case> |
276 | + <case name="Clean up values"> |
277 | + <method>clean_up_fields_and_picture</method> |
278 | + <description>Clean up values and check if they were really removed.</description> |
279 | + </case> |
280 | +</suite> |
281 | |
282 | === added file 'mago/application/gnome_about_me.py' |
283 | --- mago/application/gnome_about_me.py 1970-01-01 00:00:00 +0000 |
284 | +++ mago/application/gnome_about_me.py 2010-11-23 14:54:13 +0000 |
285 | @@ -0,0 +1,140 @@ |
286 | +PACKAGE = "mago" |
287 | + |
288 | +#-*- coding:utf-8 -*- |
289 | +""" |
290 | +This is the "gnome_about_me" module. |
291 | + |
292 | +This module provides a wrapper for LDTP to make writing Gnome_about_me tests easier. |
293 | +""" |
294 | +import ooldtp |
295 | +import ldtp |
296 | +import os |
297 | +from .main import Application |
298 | +from ..gconfwrapper import GConf |
299 | +from ..cmd import globals |
300 | +import time |
301 | +import gettext |
302 | + |
303 | +gettext.install (True) |
304 | +gettext.bindtextdomain (PACKAGE, globals.LOCALE_SHARE) |
305 | +gettext.textdomain (PACKAGE) |
306 | +t = gettext.translation(PACKAGE, globals.LOCALE_SHARE, fallback = True) |
307 | +_ = t.gettext |
308 | + |
309 | + |
310 | +class GnomeAboutMe(Application): |
311 | + """ |
312 | + gnome_about_me manages the Gnome_about_me application. |
313 | + """ |
314 | + |
315 | + LAUNCHER = 'gnome-about-me' |
316 | + LAUNCHER_ARGS = [] |
317 | + WINDOW = 'dlgAbout*' |
318 | + |
319 | + BTN_0 = _('btn0') |
320 | + BTN_CHANGEPASSWORD = _('btnChangePassword') |
321 | + BTN_CLOSE = _('btnClose') |
322 | + BTN_DISABLEFINGERPRINTLOGIN = _('btnDisableFingerprintLogin') |
323 | + BTN_ENABLEFINGERPRINTLOGIN = _('btnEnableFingerprintLogin') |
324 | + BTN_NOIMAGE = _('btnNoImage') |
325 | + DLG_SELECTIMAGE = _('dlgSelectImage') |
326 | + TXT_AIM_ICHAT = _('txtAIM/iChat') |
327 | + TXT_ADDRESS = _('txtAddress') |
328 | + TXT_ADDRESS1 = _('txtAddress1') |
329 | + TXT_ASSISTANT = _('txtAssistant') |
330 | + TXT_CALENDAR = _('txtCalendar') |
331 | + TXT_CITY = _('txtCity') |
332 | + TXT_CITY1 = _('txtCity1') |
333 | + TXT_COMPANY = _('txtCompany') |
334 | + TXT_COUNTRY = _('txtCountry') |
335 | + TXT_COUNTRY1 = _('txtCountry1') |
336 | + TXT_DEPARTMENT = _('txtDepartment') |
337 | + TXT_GROUPWISE = _('txtGroupWise') |
338 | + TXT_HOME = _('txtHome') |
339 | + TXT_HOME1 = _('txtHome1') |
340 | + TXT_HOMEPAGE = _('txtHomepage') |
341 | + TXT_ICQ = _('txtICQ') |
342 | + TXT_MSN = _('txtMSN') |
343 | + TXT_MANAGER = _('txtManager') |
344 | + TXT_MOBILE = _('txtMobile') |
345 | + TXT_POBOX = _('txtPObox') |
346 | + TXT_POBOX1 = _('txtPObox1') |
347 | + TXT_PROFESSION = _('txtProfession') |
348 | + TXT_STATE_PROVINCE = _('txtState/Province') |
349 | + TXT_STATE_PROVINCE1 = _('txtState/Province1') |
350 | + TXT_TITLE = _('txtTitle') |
351 | + TXT_WEBLOG = _('txtWeblog') |
352 | + TXT_WORK = _('txtWork') |
353 | + TXT_WORK1 = _('txtWork1') |
354 | + TXT_WORKFAX = _('txtWorkfax') |
355 | + TXT_XMPP = _('txtXMPP') |
356 | + TXT_YAHOO = _('txtYahoo') |
357 | + TXT_ZIP_POSTALCODE = _('txtZIP/Postalcode') |
358 | + TXT_ZIP_POSTALCODE1 = _('txtZIP/Postalcode1') |
359 | + TXT_LOCATION = _('txtLocation') |
360 | + |
361 | + def file_values(self, values): |
362 | + about_me = ooldtp.context(self.WINDOW) |
363 | + for widget, text in values.iteritems(): |
364 | + textWidget = about_me.getchild(widget) |
365 | + textWidget.settextvalue(text) |
366 | + about_me.getchild(self.BTN_CLOSE).click() |
367 | + |
368 | + def check_values(self, new_values): |
369 | + ldtp.waittillguiexist(self.WINDOW) |
370 | + about_me = ooldtp.context(self.WINDOW) |
371 | + |
372 | + for widget, text in new_values.iteritems(): |
373 | + saved_text = about_me.gettextvalue(widget) |
374 | + if not text == saved_text: |
375 | + raise AssertionError('entered text wasn\'t saved correctly, entered: %s saved: %s' |
376 | + % (text, saved_text)) |
377 | + |
378 | + def change_picture(self, photo_path): |
379 | + about_me = ooldtp.context(self.WINDOW) |
380 | + |
381 | + about_me.getchild(self.BTN_0).click() |
382 | + |
383 | + ldtp.wait(2) |
384 | + |
385 | + if (ldtp.guiexist(self.DLG_SELECTIMAGE)): |
386 | + selectImage = ooldtp.context(self.DLG_SELECTIMAGE) |
387 | + if not (selectImage.getchild(self.TXT_LOCATION)): |
388 | + ldtp.generatekeyevent('<ctrl>l') |
389 | + |
390 | + selectImage.settextvalue('txtLocation', photo_path) |
391 | + ldtp.wait(2) |
392 | + selectImage.getchild('btnOpen').click() |
393 | + ldtp.wait(2) |
394 | + ldtp.waittillguiexist(self.WINDOW) |
395 | + |
396 | + def change_picture_to_default(self): |
397 | + about_me = ooldtp.context(self.WINDOW) |
398 | + |
399 | + #set the photo to no image |
400 | + about_me.getchild(self.BTN_0).click() |
401 | + ldtp.wait(2) |
402 | + selectImage = ooldtp.context(self.DLG_SELECTIMAGE) |
403 | + selectImage.getchild(self.BTN_NOIMAGE).click() |
404 | + |
405 | + def clean_up_text_values(self, values): |
406 | + about_me = ooldtp.context(self.WINDOW) |
407 | + #clean up all the fields on the |
408 | + for widget, text in values.iteritems(): |
409 | + about_me.settextvalue(widget, '') |
410 | + #there's probably a bug in evolution-data-server or about-me |
411 | + #but if we don't wait to remove another field one of those might not get removed. |
412 | + ldtp.wait(1) |
413 | + ldtp.wait(3) |
414 | + |
415 | + #check that the values were cleaned, otherwise raise an error. |
416 | + for widget, text in values.iteritems(): |
417 | + saved_text = about_me.gettextvalue(widget) |
418 | + if not '' == saved_text: |
419 | + raise AssertionError('the text: %s in widget: %s was not removed' |
420 | + % (saved_text, widget)) |
421 | + |
422 | + |
423 | + def __init__(self): |
424 | + Application.__init__(self) |
425 | + self.main_window = ooldtp.context(self.WINDOW) |
426 | |
427 | === added file 'mago/test_suite/gnome_about_me.py' |
428 | --- mago/test_suite/gnome_about_me.py 1970-01-01 00:00:00 +0000 |
429 | +++ mago/test_suite/gnome_about_me.py 2010-11-23 14:54:13 +0000 |
430 | @@ -0,0 +1,23 @@ |
431 | +""" |
432 | +This module contains the definition of the test suite for Gnome_about_me testing. |
433 | +""" |
434 | +import ldtp, ooldtp |
435 | +from .main import SingleApplicationTestSuite |
436 | +from ..application.gnome_about_me import Application, GnomeAboutMe |
437 | + |
438 | +class GnomeAboutMeTestSuite(SingleApplicationTestSuite): |
439 | + """ |
440 | + Default test suite for Gnome_about_me |
441 | + """ |
442 | + APPLICATION_FACTORY = GnomeAboutMe |
443 | + def setup(self): |
444 | + self.application.open() |
445 | + |
446 | + |
447 | + def teardown(self): |
448 | + self.application.set_close_type('button') |
449 | + self.application.set_close_name('btnClose') |
450 | + self.application.close() |
451 | + |
452 | + def cleanup(self): |
453 | + pass |
In line 390 maybe you can use TXT_LOCATION instead of txtLocation, the same applies to other names as well.
Rest all fine to me.