diff --git a/addons/website/data/website_data.xml b/addons/website/data/website_data.xml index 9e33a43b5d2..bc387b609ae 100644 --- a/addons/website/data/website_data.xml +++ b/addons/website/data/website_data.xml @@ -75,6 +75,11 @@ /?tutorial.banner=true self + + Website Homepage + /page/website.homepage + self + Website diff --git a/addons/website/tests/test_ui.py b/addons/website/tests/test_ui.py index 32675717943..fbc729aefad 100644 --- a/addons/website/tests/test_ui.py +++ b/addons/website/tests/test_ui.py @@ -13,24 +13,24 @@ __all__ = ['load_tests', 'WebsiteUiSuite'] def _exc_info_to_string(err, test): return err -class LineReader(object): - def __init__(self, fd): - self._fd = fd - self._buf = '' +class LineReader: + def __init__(self, file_descriptor): + self._file_descriptor = file_descriptor + self._buffer = '' def fileno(self): - return self._fd + return self._file_descriptor def readlines(self): - data = os.read(self._fd, 4096) + data = os.read(self._file_descriptor, 4096) if not data: # EOF return None - self._buf += data + self._buffer += data if '\n' not in data: return [] - tmp = self._buf.split('\n') - lines, self._buf = tmp[:-1], tmp[-1] + tmp = self._buffer.split('\n') + lines, self._buffer = tmp[:-1], tmp[-1] return lines class WebsiteUiTest(unittest.TestCase): @@ -42,24 +42,22 @@ class WebsiteUiTest(unittest.TestCase): return self.name class WebsiteUiSuite(unittest.TestSuite): - # timeout is in seconds - def __init__(self, testfile, timeout=5): - self.testfile = testfile - self.timeout = timeout + # timeout in seconds + def __init__(self, testfile, options, timeout=10.0): + self._testfile = testfile + self._timeout = timeout + self._options = options self._test = None def __iter__(self): return iter([self]) def run(self, result): - # Test if phantom is correctly installed + # is PhantomJS correctly installed? try: - subprocess.call([ - 'phantomjs', - '-v' - ], - stdout=open(os.devnull, 'w'), - stderr=subprocess.STDOUT) + subprocess.call([ 'phantomjs', '-v' ], + stdout=open(os.devnull, 'w'), + stderr=subprocess.STDOUT) except OSError: test = WebsiteUiTest('UI Tests') result.startTest(test) @@ -74,49 +72,45 @@ class WebsiteUiSuite(unittest.TestSuite): del result._exc_info_to_string def _run(self, result): - self._test = WebsiteUiTest(self.testfile) - self.start_time = time.time() + self._test = WebsiteUiTest(self._testfile) + start_time = time.time() + last_check_time = time.time() + + self._options['timeout'] = self._timeout + self._options['port'] = tools.config['xmlrpc_port'] - phantomOptions = json.dumps({ - 'timeout': self.timeout, - 'port': tools.config['xmlrpc_port'] - }) phantom = subprocess.Popen([ - 'phantomjs', - os.path.join(ROOT, self.testfile), - phantomOptions - ], - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) - + 'phantomjs', + os.path.join(ROOT, self._testfile), + json.dumps(self._options) + ], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) proc_stdout = LineReader(phantom.stdout.fileno()) readable = [proc_stdout] - - last_check_time = time.time() try: - while readable and last_check_time < self.start_time + self.timeout: - ready, _, _ = select.select(readable, [], [], 0) + while phantom.poll() is None and readable and last_check_time < start_time + self._timeout: + ready, _, _ = select.select(readable, [], [], 0.1) if not ready: last_check_time = time.time() continue for stream in ready: lines = stream.readlines() if lines is None: - # got EOF on this stream + # EOF readable.remove(stream) - break; - for line in lines: + else: + self.process(lines[0], result) # the runner expects only one output line - self.process(line, result) - break - - if last_check_time >= (self.start_time + self.timeout): - result.addError(self._test, "Timeout after %s s" % (last_check_time - self.start_time )) - result.stopTest(self._test) + # any subsequent line is ignored + readable.remove(stream) + if last_check_time >= (start_time + self._timeout): + result.addError(self._test, "Timeout after %s s" % (last_check_time - start_time )) finally: # kill phantomjs if phantom.exit() wasn't called in the test if phantom.poll() is None: phantom.terminate() + result.stopTest(self._test) def process(self, line, result): # Test protocol @@ -124,6 +118,7 @@ class WebsiteUiSuite(unittest.TestSuite): # use console.log in phantomjs to output test results using the following format: # - for a success: { "event": "success" } # - for a failure: { "event": "failure", "message": "Failure description" } + # - for an error: { "event": "error", "message": "Error description" } # any other message is treated as an error result.startTest(self._test) try: @@ -134,12 +129,15 @@ class WebsiteUiSuite(unittest.TestSuite): elif event == 'failure': message = args.get('message', "") result.addFailure(self._test, message) + elif event == 'error': + message = args.get('message', "") + result.addError(self._test, message) else: - result.addError(self._test, "Unexpected message: %s" % line) + result.addError(self._test, 'Unexpected JSON: "%s"' % line) except ValueError: - result.addError(self._test, "Unexpected message: %s" % line) + result.addError(self._test, 'Unexpected message: "%s"' % line) def load_tests(loader, base, _): - base.addTest(WebsiteUiSuite('sample_test.js')) - base.addTest(WebsiteUiSuite('banner_tour.js')) - return base \ No newline at end of file + base.addTest(WebsiteUiSuite('dummy_test.js', {})) + base.addTest(WebsiteUiSuite('banner_tour_test.js', { 'path': '/web#action=website.action_website_homepage&login=admin&password=admin' })) + return base diff --git a/addons/website/tests/ui_suite/banner_tour.js b/addons/website/tests/ui_suite/banner_tour.js deleted file mode 100644 index 686f86e446e..00000000000 --- a/addons/website/tests/ui_suite/banner_tour.js +++ /dev/null @@ -1,17 +0,0 @@ -var options = JSON.parse(phantom.args); -var page = require('webpage').create(); -var url = 'http://localhost:'+options.port; -page.open(url, function (status) { - if (status !== 'success') { - console.log('{ "event": "failure", "message": "'+url+' failed to load"}'); - phantom.exit(); - } else { - page.evaluate(function() { - $(document).on("tour:ready", function () { - openerp.website.TestConsole.test('banner').run(true) - console.log('{ "event": "success" }'); - phantom.exit(); - }); - }); - } -}); \ No newline at end of file diff --git a/addons/website/tests/ui_suite/banner_tour_test.js b/addons/website/tests/ui_suite/banner_tour_test.js new file mode 100644 index 00000000000..b8ebb079934 --- /dev/null +++ b/addons/website/tests/ui_suite/banner_tour_test.js @@ -0,0 +1,30 @@ +var testTemplate = require('./ui_test_template.js'); + +testTemplate.runTest(function testBannerTour (page) { + var waitFor = testTemplate.waitFor; + page.evaluate(function () { + localStorage.clear(); + }); + waitFor(function () { + return page.evaluate(function () { + return window.openerp && window.openerp.website && window.openerp.website.TestConsole && window.openerp.website.TestConsole.test('banner'); + }); + }, function () { + page.evaluate(function () { + window.openerp.website.TestConsole.test('banner').run(true); + }); + waitFor(function () { + return page.evaluate(function () { + var $edit = $('button[data-action=edit]'); + var $carousel = $('#wrap [data-snippet-id=carousel]'); + var $columns = $('#wrap [data-snippet-id=three-columns]'); + return $carousel && $carousel.length === 1 + && $columns && $columns.length === 1 + && $('button[data-action=edit]').is(":visible"); + }); + }, function () { + console.log('{ "event": "success" }'); + phantom.exit(); + }); + }); +}); \ No newline at end of file diff --git a/addons/website/tests/ui_suite/sample_test.js b/addons/website/tests/ui_suite/dummy_test.js similarity index 100% rename from addons/website/tests/ui_suite/sample_test.js rename to addons/website/tests/ui_suite/dummy_test.js diff --git a/addons/website/tests/ui_suite/ui_test_template.js b/addons/website/tests/ui_suite/ui_test_template.js new file mode 100644 index 00000000000..e0af7a02307 --- /dev/null +++ b/addons/website/tests/ui_suite/ui_test_template.js @@ -0,0 +1,44 @@ +function waitFor(ready, callback, timeout) { + var timeoutMillis = timeout ? Math.round(timeout*1000) : 30000; + var start = new Date().getTime(); + var condition = ready(); + var interval = setInterval(function() { + if ((new Date().getTime() - start < timeoutMillis) && !condition ) { + condition = ready(); + } else { + if(!condition) { + console.log('{ "event": "error", "message": "Timeout after '+timeoutMillis+' ms" }'); + phantom.exit(1); + } else { + clearInterval(interval); + callback(); + } + } + }, 100); +}; + +function runTest (test) { + var options = JSON.parse(phantom.args); + var port = options.port ? ':'+options.port : ''; + var path = options.path ? options.path : ''; + var url = 'http://localhost'+port+path; + var page = require('webpage').create(); + page.viewportSize = { width: 1920, height: 1080 }; + page.onError = function(message, trace) { + console.log('{ "event": "error", "message": "'+message+'"}'); + phantom.exit(1); + }; + page.open(url, function (status) { + if (status !== 'success') { + console.log('{ "event": "failure", "message": "'+url+' failed to load"}'); + phantom.exit(1); + } else { + test(page); + } + }); +} + +module.exports = { + waitFor: waitFor, + runTest: runTest +} \ No newline at end of file diff --git a/addons/website_event_track/views/website_event.xml b/addons/website_event_track/views/website_event.xml index 282d5fdadd9..a678414ae9c 100644 --- a/addons/website_event_track/views/website_event.xml +++ b/addons/website_event_track/views/website_event.xml @@ -39,7 +39,7 @@
-

You can click on cells to highlight your interests.

+

You can click on cells to highlight your interests.