Merge lp:~elopio/selenium-simple-test/logging into lp:selenium-simple-test

Proposed by Leo Arias
Status: Merged
Approved by: Corey Goldberg
Approved revision: 367
Merged at revision: 359
Proposed branch: lp:~elopio/selenium-simple-test/logging
Merge into: lp:selenium-simple-test
Diff against target: 589 lines (+85/-78)
3 files modified
src/sst/actions.py (+75/-74)
src/sst/command.py (+6/-1)
src/sst/tests/test_actions.py (+4/-3)
To merge this branch: bzr merge lp:~elopio/selenium-simple-test/logging
Reviewer Review Type Date Requested Status
Corey Goldberg (community) Approve
Review via email: mp+147709@code.launchpad.net

Commit message

Use a logger for SST messages.

Description of the change

I added logging facilities instead, so messages can go to the log instead of just priting them.
Currently it just have a basic configuration so it will still go to the command line.
And currently the runner accepts only the -q option, that will set a high logging level so nothing is printed in the command line. Default level is DEBUG, but in the future we should handle this better.

To post a comment you must log in.
Revision history for this message
Leo Arias (elopio) wrote :

This branch was born because we need to set the logging level while running tests in U1.
That's done here: https://code.launchpad.net/~elopio/ubuntuone-servers/acceptance_tests_logger/+merge/147710

365. By Leo Arias

Fixed the retry on stale element test.

366. By Leo Arias

Merged with trunk.

367. By Leo Arias

Indent the log messages with 4 spaces and print a newline. This is almost the same behavior as before the log.

Revision history for this message
Corey Goldberg (coreygoldberg) wrote :

thanks.
this looks nice.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/sst/actions.py'
2--- src/sst/actions.py 2013-01-29 19:45:06 +0000
3+++ src/sst/actions.py 2013-02-11 20:53:24 +0000
4@@ -1,5 +1,5 @@
5 #
6-# Copyright (c) 2011-2012 Canonical Ltd.
7+# Copyright (c) 2011,2012,2013 Canonical Ltd.
8 #
9 # This file is part of: SST (selenium-simple-test)
10 # https://launchpad.net/selenium-simple-test
11@@ -37,13 +37,13 @@
12 """
13
14
15+import logging
16 import os
17 import re
18 import time
19
20 from datetime import datetime
21 from pdb import set_trace as debug
22-from textwrap import TextWrapper
23 from urlparse import urljoin, urlparse
24
25 from selenium import webdriver
26@@ -97,7 +97,8 @@
27
28 BASE_URL = 'http://localhost:8000/'
29 __DEFAULT_BASE_URL__ = BASE_URL
30-VERBOSE = True
31+
32+logger = logging.getLogger('SST')
33
34
35 class EndTest(StandardError):
36@@ -114,7 +115,7 @@
37
38
39 def _raise(msg):
40- _print(msg)
41+ logger.debug(msg)
42 raise AssertionError(msg)
43
44
45@@ -133,7 +134,7 @@
46 try:
47 return func(*args, **kwargs)
48 except StaleElementReferenceException as e:
49- _print('Retrying after catching: %r' % e)
50+ logger.warning('Retrying after catching: %r' % e)
51 return func(*args, **kwargs)
52 return wrapped
53
54@@ -143,7 +144,7 @@
55 global BASE_URL
56 if not url.startswith('http') and not url.startswith('file'):
57 url = 'http://' + url
58- _print('Setting base url to: %r' % url)
59+ logger.debug('Setting base url to: %r' % url)
60 BASE_URL = url
61
62
63@@ -174,16 +175,6 @@
64 _test.skipTest(reason)
65
66
67-def _print(text):
68- if VERBOSE:
69- text_wrapper = TextWrapper(
70- width=80,
71- initial_indent=(' ' * 4),
72- subsequent_indent=(' ' * 8),
73- )
74- print text_wrapper.fill(text)
75-
76-
77 def start(browser_type=None, browser_version='',
78 browser_platform='ANY', session_name='',
79 javascript_disabled=False, assume_trusted_cert_issuer=False,
80@@ -197,8 +188,14 @@
81 if browser_type is None:
82 browser_type = config.browser_type
83
84- _print('')
85- _print('Starting browser: %s' % browser_type)
86+ if logger.isEnabledFor(logging.DEBUG):
87+ # XXX We print a new line because otherwise the first debug message
88+ # will be printed on the same line as the name of the test. This is
89+ # hacky and doesn't cover cases when the script logs things higher
90+ # than debug, but this way we are keeping the same behavior we had
91+ # before adding the log.
92+ print
93+ logger.debug('Starting browser: %s' % browser_type)
94
95 if webdriver_remote is None:
96 if browser_type == 'Firefox':
97@@ -244,13 +241,13 @@
98 global browser
99 global browsermob_proxy
100
101- _print('Stopping browser')
102+ logger.debug('Stopping browser')
103 # quit calls close() and does cleanup
104 browser.quit()
105 browser = None
106
107 if browsermob_proxy is not None:
108- _print('Closing http proxy')
109+ logger.debug('Closing http proxy')
110 browsermob_proxy.close()
111 browsermob_proxy = None
112
113@@ -263,17 +260,17 @@
114 available after the click. You can switch off this behaviour by passing
115 `wait=False`."""
116 if browsermob_proxy is not None:
117- _print('Capturing http traffic...')
118+ logger.debug('Capturing http traffic...')
119 browsermob_proxy.new_har()
120
121- _print('Refreshing current page')
122+ logger.debug('Refreshing current page')
123 browser.refresh()
124
125 if wait:
126 _waitforbody()
127
128 if browsermob_proxy is not None:
129- _print('Saving HAR output')
130+ logger.debug('Saving HAR output')
131 _make_results_dir()
132 browsermob_proxy.save_har(_make_useable_har_name())
133
134@@ -284,7 +281,7 @@
135 when running in `-s` mode.
136
137 Return the path to the saved screenshot."""
138- _print('Capturing Screenshot')
139+ logger.debug('Capturing Screenshot')
140 _make_results_dir()
141 if add_timestamp:
142 filename = _add_time_stamp(filename)
143@@ -305,7 +302,7 @@
144 Called automatically on failures when running `-s` mode.
145
146 Return the path to the saved file."""
147- _print('Saving page source')
148+ logger.debug('Saving page source')
149 _make_results_dir()
150 if add_timestamp:
151 filename = _add_time_stamp(filename)
152@@ -328,7 +325,7 @@
153 """
154 Delay execution for a given number of seconds. The argument may be a
155 floating point number for subsecond precision."""
156- _print('Sleeping %s secs' % secs)
157+ logger.debug('Sleeping %s secs' % secs)
158 time.sleep(secs)
159
160
161@@ -387,7 +384,7 @@
162 when `run_test` returns."""
163 # delayed import to workaround circular imports
164 from sst import context
165- _print('Executing test: %s' % name)
166+ logger.debug('Executing test: %s' % name)
167 return context.run_test(name, kwargs)
168
169
170@@ -418,17 +415,17 @@
171 url = _fix_url(url)
172
173 if browsermob_proxy is not None:
174- _print('Capturing http traffic...')
175+ logger.debug('Capturing http traffic...')
176 browsermob_proxy.new_har()
177
178- _print('Going to... %s' % url)
179+ logger.debug('Going to... %s' % url)
180 browser.get(url)
181
182 if wait:
183 _waitforbody()
184
185 if browsermob_proxy is not None:
186- _print('Saving HAR output')
187+ logger.debug('Saving HAR output')
188 _make_results_dir()
189 browsermob_proxy.save_har(_make_useable_har_name(url))
190
191@@ -441,17 +438,17 @@
192 available after the click. You can switch off this behaviour by passing
193 `wait=False`."""
194 if browsermob_proxy is not None:
195- _print('Capturing http traffic...')
196+ logger.debug('Capturing http traffic...')
197 browsermob_proxy.new_har()
198
199- _print('Going back one step in browser history')
200+ logger.debug('Going back one step in browser history')
201 browser.back()
202
203 if wait:
204 _waitforbody()
205
206 if browsermob_proxy is not None:
207- _print('Saving HAR output')
208+ logger.debug('Saving HAR output')
209 _make_results_dir()
210 browsermob_proxy.save_har(_make_useable_har_name())
211
212@@ -485,7 +482,7 @@
213 Toggle the checkbox value. Takes an element id or object. Raises a failure
214 exception if the element specified doesn't exist or isn't a checkbox."""
215 checkbox = assert_checkbox(id_or_elem)
216- _print('Toggling checkbox: %r' % _get_text(checkbox))
217+ logger.debug('Toggling checkbox: %r' % _get_text(checkbox))
218 before = checkbox.is_selected()
219 checkbox.click()
220 after = checkbox.is_selected()
221@@ -500,7 +497,8 @@
222 Set a checkbox to a specific value, either True or False. Raises a failure
223 exception if the element specified doesn't exist or isn't a checkbox."""
224 checkbox = assert_checkbox(id_or_elem)
225- _print('Setting checkbox %r to %r' % (_get_text(checkbox), new_value))
226+ logger.debug(
227+ 'Setting checkbox %r to %r' % (_get_text(checkbox), new_value))
228 # There is no method to 'unset' a checkbox in the browser object
229 current_value = checkbox.is_selected()
230 if new_value != current_value:
231@@ -528,7 +526,7 @@
232 key_element = _get_elem(id_or_elem)
233 msg = 'Simulating keypress on %r with %r key' \
234 % (_get_text(key_element), key_to_press)
235- _print(msg)
236+ logger.debug(msg)
237 key_code = _make_keycode(key_to_press)
238 key_element.send_keys(key_code)
239
240@@ -560,7 +558,7 @@
241 textfield = assert_textfield(id_or_elem)
242 msg = 'Writing to textfield %r with text %r' \
243 % (_get_text(textfield), new_text)
244- _print(msg)
245+ logger.debug(msg)
246
247 # clear field like this, don't use clear()
248 if clear:
249@@ -573,7 +571,7 @@
250 textfield.send_keys(str(new_text))
251 if not check:
252 return
253- _print('Check text wrote correctly')
254+ logger.debug('Check text wrote correctly')
255 current_text = textfield.get_attribute('value')
256 if current_text != new_text:
257 msg = 'Textfield: %r - did not write. Text was: %r' \
258@@ -597,7 +595,7 @@
259
260 def get_link_url(id_or_elem):
261 """Return the URL from a link."""
262- _print('Getting url from link %r' % id_or_elem)
263+ logger.debug('Getting url from link %r' % id_or_elem)
264 link = assert_link(id_or_elem)
265 link_url = link.get_attribute('href')
266 return link_url
267@@ -621,17 +619,17 @@
268 link_url = link.get_attribute('href')
269
270 if browsermob_proxy is not None:
271- _print('Capturing http traffic...')
272+ _logger.debug('Capturing http traffic...')
273 browsermob_proxy.new_har()
274
275- _print('Clicking link %r' % _get_text(link))
276+ logger.debug('Clicking link %r' % _get_text(link))
277 link.click()
278
279 if wait:
280 _waitforbody()
281
282 if browsermob_proxy is not None:
283- _print('Saving HAR output')
284+ logger.debug('Saving HAR output')
285 _make_results_dir()
286 browsermob_proxy.save_har(_make_useable_har_name())
287
288@@ -665,17 +663,17 @@
289 elem = _get_elem(id_or_elem)
290
291 if browsermob_proxy is not None:
292- _print('Capturing http traffic...')
293+ logger.debug('Capturing http traffic...')
294 browsermob_proxy.new_har()
295
296- _print('Clicking element %r' % _get_text(elem))
297+ logger.debug('Clicking element %r' % _get_text(elem))
298 elem.click()
299
300 if wait:
301 _waitforbody()
302
303 if browsermob_proxy is not None:
304- _print('Saving HAR output')
305+ logger.debug('Saving HAR output')
306 _make_results_dir()
307 browsermob_proxy.save_har(_make_useable_har_name())
308
309@@ -746,7 +744,7 @@
310 msg = 'Setting wait timeout to %rs' % timeout
311 if poll is not None:
312 msg += ('. Setting poll time to %rs' % poll)
313- _print(msg)
314+ logger.debug(msg)
315 _set_wait_timeout(timeout, poll)
316
317
318@@ -771,10 +769,9 @@
319
320
321 def _wait_for(condition, refresh_page, timeout, poll, *args, **kwargs):
322- global VERBOSE
323- _print('Waiting for %r' % _get_name(condition))
324- original = VERBOSE
325- VERBOSE = False
326+ logger.debug('Waiting for %r' % _get_name(condition))
327+ # Disable logging levels equal to or lower than INFO.
328+ logging.disable(logging.INFO)
329 try:
330 max_time = time.time() + timeout
331 msg = _get_name(condition)
332@@ -797,7 +794,8 @@
333 _raise(error)
334 time.sleep(poll)
335 finally:
336- VERBOSE = original
337+ # Re-enable logging.
338+ logging.disable(logging.NOTSET)
339
340
341 @retry_on_stale_element
342@@ -850,7 +848,7 @@
343 `fails` succeeds. If the function does *not* raise an AssertionError then
344 this action raises the appropriate failure exception. Alll other
345 exceptions will be propagated normally."""
346- _print('Trying action failure: %s' % _get_name(action))
347+ logger.debug('Trying action failure: %s' % _get_name(action))
348 try:
349 action(*args, **kwargs)
350 except AssertionError:
351@@ -892,7 +890,8 @@
352 def set_dropdown_value(id_or_elem, text=None, value=None):
353 """Set the select drop-list to a text or value specified."""
354 elem = assert_dropdown(id_or_elem)
355- _print('Setting %r option list to %r' % (_get_text(elem), text or value))
356+ logger.debug(
357+ 'Setting %r option list to %r' % (_get_text(elem), text or value))
358 if text and not value:
359 for element in elem.find_elements_by_tag_name('option'):
360 if element.text == text:
361@@ -954,7 +953,7 @@
362 def set_radio_value(id_or_elem):
363 """Select the specified radio button."""
364 elem = assert_radio(id_or_elem)
365- _print('Selecting radio button item %r' % _get_text(elem))
366+ logger.debug('Selecting radio button item %r' % _get_text(elem))
367 elem.click()
368
369
370@@ -1154,17 +1153,17 @@
371 button = assert_button(id_or_elem)
372
373 if browsermob_proxy is not None:
374- _print('Capturing http traffic...')
375+ logger.debug('Capturing http traffic...')
376 browsermob_proxy.new_har()
377
378- _print('Clicking button %r' % _get_text(button))
379+ logger.debug('Clicking button %r' % _get_text(button))
380 button.click()
381
382 if wait:
383 _waitforbody()
384
385 if browsermob_proxy is not None:
386- _print('Saving HAR output')
387+ logger.debug('Saving HAR output')
388 _make_results_dir()
389 browsermob_proxy.save_har(_make_useable_har_name())
390
391@@ -1216,7 +1215,7 @@
392
393 def close_window():
394 """ Closes the current window """
395- _print('Closing the current window')
396+ logger.debug('Closing the current window')
397 browser.close()
398
399
400@@ -1226,7 +1225,7 @@
401
402 if no window is given, switch focus to the default window."""
403 if index_or_name is None:
404- _print('Switching to default window')
405+ logger.debug('Switching to default window')
406 browser.switch_to_window('')
407 elif isinstance(index_or_name, int):
408 index = index_or_name
409@@ -1236,7 +1235,7 @@
410 _raise(msg)
411 window = window_handles[index]
412 try:
413- _print('Switching to window: %r' % window)
414+ logger.debug('Switching to window: %r' % window)
415 browser.switch_to_window(window)
416 except NoSuchWindowException:
417 msg = 'Could not find window: %r' % window
418@@ -1244,7 +1243,7 @@
419 else:
420 name = index_or_name
421 try:
422- _print('Switching to window: %r' % name)
423+ logger.debug('Switching to window: %r' % name)
424 browser.switch_to_window(name)
425 except NoSuchWindowException:
426 msg = 'Could not find window: %r' % name
427@@ -1257,10 +1256,10 @@
428
429 if no frame is given, switch focus to the default content frame."""
430 if index_or_name is None:
431- _print('Switching to default content frame')
432+ logger.debug('Switching to default content frame')
433 browser.switch_to_default_content()
434 else:
435- _print('Switching to frame: %r' % index_or_name)
436+ logger.debug('Switching to frame: %r' % index_or_name)
437 try:
438 browser.switch_to_frame(index_or_name)
439 except NoSuchFrameException:
440@@ -1301,7 +1300,7 @@
441 Note that the action that opens the alert should not wait for a page with
442 a body element. This means that you should call functions like
443 click_element with the argument wait=Fase."""
444- _print('Accepting Alert')
445+ logger.debug('Accepting Alert')
446 _alert_action('accept', expected_text, text_to_write)
447
448
449@@ -1315,7 +1314,7 @@
450 Note that the action that opens the alert should not wait for a page with
451 a body element. This means that you should call functions like
452 click_element with the argument wait=Fase."""
453- _print('Dismissing Alert')
454+ logger.debug('Dismissing Alert')
455 _alert_action('dismiss', expected_text, text_to_write)
456
457
458@@ -1324,7 +1323,7 @@
459 Assert table `id_or_elem` has headers (<th> tags) where the text matches
460 the sequence `headers`.
461 """
462- _print('Checking headers for %r' % (id_or_elem,))
463+ logger.debug('Checking headers for %r' % (id_or_elem,))
464 elem = _get_elem(id_or_elem)
465 if not elem.tag_name == 'table':
466 _raise('Element %r is not a table.' % (id_or_elem,))
467@@ -1341,7 +1340,7 @@
468 Assert the specified table has the specified number of rows (<tr> tags
469 inside the <tbody>).
470 """
471- _print('Checking table %r has %s rows' % (id_or_elem, num_rows))
472+ logger.debug('Checking table %r has %s rows' % (id_or_elem, num_rows))
473 elem = _get_elem(id_or_elem)
474 if not elem.tag_name == 'table':
475 _raise('Element %r is not a table.' % (id_or_elem,))
476@@ -1368,7 +1367,8 @@
477 The row will be looked for inside the <tbody>, to check headers use
478 `assert_table_headers`.
479 """
480- _print('Checking the contents of table %r, row %s.' % (id_or_elem, row))
481+ logger.debug(
482+ 'Checking the contents of table %r, row %s.' % (id_or_elem, row))
483 elem = _get_elem(id_or_elem)
484 if not elem.tag_name == 'table':
485 _raise('Element %r is not a table.' % (id_or_elem,))
486@@ -1403,7 +1403,7 @@
487 the attribute using a regular expression search.
488 """
489 elem = _get_elem(id_or_elem)
490- _print('Checking attribute %r of %r' % (attribute, _get_text(elem)))
491+ logger.debug('Checking attribute %r of %r' % (attribute, _get_text(elem)))
492 actual = elem.get_attribute(attribute)
493 if not regex:
494 success = value == actual
495@@ -1423,8 +1423,9 @@
496 the property using a regular expression search.
497 """
498 elem = _get_elem(id_or_elem)
499- _print('Checking css property %r: %r of %r' %
500- (property, value, _get_text(elem)))
501+ logger.debug(
502+ 'Checking css property %r: %r of %r' % (
503+ property, value, _get_text(elem)))
504 actual = elem.value_of_css_property(property)
505 # some browsers return string with space padded commas, some don't.
506 actual = actual.replace(', ', ',')
507@@ -1487,13 +1488,13 @@
508
509 def clear_cookies():
510 """Clear the cookies of current session."""
511- _print('Clearing browser session cookies')
512+ logger.debug('Clearing browser session cookies')
513 browser.delete_all_cookies()
514
515
516 def set_window_size(width, height):
517 """Resize the current window (width, height) in pixels."""
518- _print('Resizing window to: %s x %s' % (width, height))
519+ logger.debug('Resizing window to: %s x %s' % (width, height))
520 orig_width, orig_height = get_window_size()
521 if (orig_width == width) and (orig_height == height):
522 return (width, height)
523@@ -1531,7 +1532,7 @@
524
525 args will be made available to the script if given.
526 """
527- _print('Executing script')
528+ logger.debug('Executing script')
529 return browser.execute_script(script, *args)
530
531
532
533=== modified file 'src/sst/command.py'
534--- src/sst/command.py 2013-01-24 06:16:28 +0000
535+++ src/sst/command.py 2013-02-11 20:53:24 +0000
536@@ -18,6 +18,7 @@
537 #
538
539 import __main__
540+import logging
541 import os
542 import sys
543 import shutil
544@@ -158,8 +159,12 @@
545 print 'run "%s -h" or "%s --help" to see run options.' % (prog, prog)
546 sys.exit(1)
547
548+ logging.basicConfig(format=' %(levelname)s:%(name)s:%(message)s')
549+ logger = logging.getLogger('SST')
550 if cmd_opts.quiet:
551- actions.VERBOSE = False
552+ logger.setLevel(logging.WARNING)
553+ else:
554+ logger.setLevel(logging.DEBUG)
555 if cmd_opts.disable_flags:
556 actions._check_flags = False
557
558
559=== modified file 'src/sst/tests/test_actions.py'
560--- src/sst/tests/test_actions.py 2013-01-24 06:07:20 +0000
561+++ src/sst/tests/test_actions.py 2013-02-11 20:53:24 +0000
562@@ -18,7 +18,7 @@
563
564
565 from cStringIO import StringIO
566-import sys
567+import logging
568
569
570 import testtools
571@@ -33,7 +33,8 @@
572 super(TestRetryOnStale, self).setUp()
573 self.out = StringIO()
574 # Capture output from retry_on_stale_element calls
575- self.patch(sys, 'stdout', self.out)
576+ logger = logging.getLogger('SST')
577+ logger.addHandler(logging.StreamHandler(self.out))
578 self.nb_calls = 0
579
580 def raise_stale_element(self):
581@@ -49,7 +50,7 @@
582 self.assertEqual(2, self.nb_calls)
583 # And we get some feedback about the exception
584 self.assertIn(
585- ' Retrying after catching: StaleElementReferenceException()\n',
586+ 'Retrying after catching: StaleElementReferenceException()',
587 self.out.getvalue())
588
589 def test_retry_on_stale_only_once(self):

Subscribers

People subscribed via source and target branches