1
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2
# Copyright 2013 Canonical
4
# This program is free software: you can redistribute it and/or modify it
5
# under the terms of the GNU Lesser General Public License version 3, as published
6
# by the Free Software Foundation.
8
"""Tests for the Ubuntu HTML5 package """
16
HTTP_SERVER_PORT = 8383
18
from testtools.matchers import Contains, Equals, GreaterThan
19
from autopilot.matchers import Eventually
20
from autopilot.testcase import AutopilotTestCase
21
from autopilot.input import Mouse, Touch, Pointer
23
# from autopilot.introspection.qt import QtIntrospectionTestMixin
26
class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
27
BASE_PATH_FOR_SERVED_APPS = {'rss-reader': "%s/%s" % (os.path.dirname(os.path.realpath(__file__)), '../../../../0.1/examples/apps/rss-reader')}
29
def get_served_filename(self, appname, filename):
30
if len(filename) == 0 or filename == '/':
31
filename = 'autopilot.html'
32
print os.path.join(self.BASE_PATH_FOR_SERVED_APPS[appname], filename)
33
return os.path.join(self.BASE_PATH_FOR_SERVED_APPS[appname], filename)
35
def serve_file(self, filename):
38
content_type = mimetypes.guess_type(filename)[0]
40
f = open(filename, 'rb')
41
self.send_response(200)
42
self.send_header('Content-length', os.fstat(f.fileno())[6])
43
self.send_header('Content-type', content_type)
45
self.wfile.write(f.read())
48
# FIXME: more generic & cleaner
49
if self.path.startswith('/rss-reader'):
50
filename = self.path[len('/rss-reader'):]
51
self.send_response(200)
52
self.serve_file(self.get_served_filename('rss-reader', filename))
57
class UbuntuHTML5HTTPServer(threading.Thread):
58
def __init__(self, port):
59
super(UbuntuHTML5HTTPServer, self).__init__()
60
self.server = BaseHTTPServer.HTTPServer(("", port), RequestHandler)
61
self.server.allow_reuse_address = True
64
self.server.serve_forever()
67
self.server.shutdown()
68
self.server.server_close()
71
class UbuntuHTML5TestCaseBase(AutopilotTestCase):
72
BROWSER_CONTAINER_PATH = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)), '../../tools/qml/webview.qml')
73
INSTALLED_BROWSER_CONTAINER_PATH = '/usr/share/ubuntu-html5-ui-toolkit/autopilot-tests/qml/webview.qml'
74
arch = subprocess.check_output(
75
["dpkg-architecture", "-qDEB_HOST_MULTIARCH"]).strip()
76
BROWSER_QML_APP_LAUNCHER = "/usr/lib/" + arch + "/qt5/bin/qmlscene"
79
LOCAL_HTML_EXAMPLES_PATH = os.path.abspath("%s/%s" % (os.path.dirname(os.path.realpath(__file__)), '../../../../examples/html5-theme'))
80
INSTALLED_HTML_EXAMPLES_PATH = '/usr/share/ubuntu-html5-ui-toolkit/0.1/examples'
82
APPS_SUBFOLDER_NAME = 'apps'
86
def get_browser_container_path(self):
87
if os.path.exists(self.BROWSER_CONTAINER_PATH):
88
return self.BROWSER_CONTAINER_PATH
89
return self.INSTALLED_BROWSER_CONTAINER_PATH
91
def create_file_url_from(self, filepath):
92
return 'file://' + filepath
94
def setup_base_path(self):
95
if os.path.exists(self.LOCAL_HTML_EXAMPLES_PATH):
96
self.BASE_PATH = self.LOCAL_HTML_EXAMPLES_PATH
98
self.BASE_PATH = self.INSTALLED_HTML_EXAMPLES_PATH
101
self.setup_base_path()
102
self.pointer = Pointer(Mouse.create())
103
self.app = self.launch_test_application(self.BROWSER_QML_APP_LAUNCHER, self.get_browser_container_path())
104
self.webviewContainer = self.get_webviewContainer()
105
self.watcher = self.webviewContainer.watch_signal('resultUpdated(QString)')
106
super(UbuntuHTML5TestCaseBase, self).setUp()
109
super(UbuntuHTML5TestCaseBase, self).tearDown()
111
def pick_app_launcher(self, app_path):
112
# force Qt app introspection:
113
from autopilot.introspection.qt import QtApplicationLauncher
114
return QtApplicationLauncher()
116
def get_webviewContainer(self):
117
return self.app.select_single(objectName="webviewContainer")
119
def get_webview(self):
120
return self.app.select_single(objectName="webview")
122
def get_addressbar(self):
123
return self.app.select_single(objectName="addressbar")
125
def get_button(self):
126
return self.app.select_single(objectName="browseButton")
129
return self.get_webview().title
131
def assert_url_eventually_loaded(self, url):
132
webview = self.get_webview()
133
self.assertThat(webview.loadProgress, Eventually(Equals(100)))
134
self.assertThat(webview.loading, Eventually(Equals(False)))
135
self.assertThat(webview.url, Eventually(Equals(url)))
137
def click_dom_node_with_id(self, id):
138
webview = self.get_webviewContainer()
139
webview.slots.clickElementById(id)
140
self.assertThat(lambda: self.watcher.num_emissions, Eventually(Equals(1)))
142
def click_any_dom_node_by_selector(self, selector):
143
webview = self.get_webviewContainer()
144
webview.slots.clickAnyElementBySelector(selector)
145
self.assertThat(lambda: self.watcher.num_emissions, Eventually(Equals(1)))
147
def is_dom_node_visible(self, id):
148
webview = self.get_webviewContainer()
149
prev_emissions = self.watcher.num_emissions
150
webview.slots.isNodeWithIdVisible(id)
151
self.assertThat(lambda: self.watcher.num_emissions, Eventually(GreaterThan(prev_emissions)))
152
return json.loads(webview.get_signal_emissions('resultUpdated(QString)')[-1][0])['result']
154
def eval_expression_in_page_unsafe(self, expr):
155
webview = self.get_webviewContainer()
156
prev_emissions = self.watcher.num_emissions
157
webview.slots.evalInPageUnsafe(expr)
158
self.assertThat(lambda: self.watcher.num_emissions, Eventually(GreaterThan(prev_emissions)))
159
return json.loads(webview.get_signal_emissions('resultUpdated(QString)')[-1][0])['result']
161
def get_dom_node_id_attribute(self, id, attribute):
162
webview = self.get_webviewContainer()
163
prev_emissions = self.watcher.num_emissions
164
webview.slots.getAttributeForElementWithId(id, attribute)
165
self.assertThat(lambda: self.watcher.num_emissions, Eventually(GreaterThan(prev_emissions)))
166
return json.loads(webview.get_signal_emissions('resultUpdated(QString)')[-1][0])['result']
168
def browse_to_url(self, url):
169
addressbar = self.get_addressbar()
170
self.pointer.move_to_object(addressbar)
173
self.keyboard.type(url, 0.001)
175
button = self.get_button()
176
self.pointer.move_to_object(button)
179
self.assert_url_eventually_loaded(url);
181
def browse_to_app(self, appname):
182
APP_HTML_PATH = self.create_file_url_from(os.path.abspath(self.BASE_PATH + '/../../tests/data/html/' + self.APPS_SUBFOLDER_NAME + '/' + appname + '/index.html'))
183
self.browse_to_url(APP_HTML_PATH)
185
def browse_to_test_html(self, html_filename):
186
self.browse_to_url(self.create_file_url_from(os.path.abspath(self.BASE_PATH + '/../../tests/data/html/' + html_filename)))
189
class UbuntuThemeWithHttpServerTestCaseBase(UbuntuHTML5TestCaseBase):
191
self.server = UbuntuHTML5HTTPServer(HTTP_SERVER_PORT)
193
super(UbuntuThemeWithHttpServerTestCaseBase, self).setUp()
196
super(UbuntuThemeWithHttpServerTestCaseBase, self).tearDown()
197
self.server.shutdown()
200
class UbuntuThemeRemotePageTestCaseBase(UbuntuThemeWithHttpServerTestCaseBase):
202
super(UbuntuThemeRemotePageTestCaseBase, self).setUp()