13992.1.1
by Gary Poster
Add yui xhr integration test support. |
1 |
# Copyright 2011 Canonical Ltd. This software is licensed under the
|
2 |
# GNU Affero General Public License version 3 (see the file LICENSE).
|
|
3 |
||
4 |
"""Fixture code for YUITest + XHR integration testing."""
|
|
5 |
||
6 |
__metaclass__ = type |
|
7 |
__all__ = [ |
|
8 |
'login_as_person', |
|
9 |
'make_suite', |
|
10 |
'setup', |
|
11 |
'YUITestFixtureControllerView', |
|
12 |
]
|
|
13 |
||
14151.2.1
by Gary Poster
add yuixhr test improvements back |
14 |
from fnmatch import fnmatchcase |
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
15 |
import os |
16 |
import sys |
|
17 |
from textwrap import dedent |
|
18 |
import traceback |
|
19 |
import unittest |
|
20 |
||
21 |
from lazr.restful import ResourceJSONEncoder |
|
22 |
from lazr.restful.utils import get_current_browser_request |
|
14550.1.1
by Steve Kowalik
Run format-imports over lib/lp and lib/canonical/launchpad |
23 |
import simplejson |
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
24 |
from zope.component import getUtility |
25 |
from zope.exceptions.exceptionformatter import format_exception |
|
26 |
from zope.interface import implements |
|
27 |
from zope.publisher.interfaces import NotFound |
|
28 |
from zope.publisher.interfaces.http import IResult |
|
29 |
from zope.security.checker import ( |
|
30 |
NamesChecker, |
|
14550.1.1
by Steve Kowalik
Run format-imports over lib/lp and lib/canonical/launchpad |
31 |
ProxyFactory, |
32 |
)
|
|
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
33 |
from zope.security.proxy import removeSecurityProxy |
34 |
from zope.session.interfaces import IClientIdManager |
|
35 |
||
14612.2.1
by William Grant
format-imports on lib/. So many imports. |
36 |
from lp.app.versioninfo import revno |
14605.1.1
by Curtis Hovey
Moved canonical.config to lp.services. |
37 |
from lp.services.config import config |
14600.2.2
by Curtis Hovey
Moved webapp to lp.services. |
38 |
from lp.services.webapp.interfaces import ( |
14550.1.1
by Steve Kowalik
Run format-imports over lib/lp and lib/canonical/launchpad |
39 |
IOpenLaunchBag, |
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
40 |
IPlacelessAuthUtility, |
41 |
)
|
|
14600.2.2
by Curtis Hovey
Moved webapp to lp.services. |
42 |
from lp.services.webapp.login import logInPrincipal |
43 |
from lp.services.webapp.publisher import LaunchpadView |
|
14612.2.1
by William Grant
format-imports on lib/. So many imports. |
44 |
from lp.testing import AbstractYUITestCase |
14604.1.1
by Curtis Hovey
Separate test-authoring classes from test-running classes. |
45 |
from lp.testing.layers import ( |
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
46 |
DatabaseLayer, |
47 |
LaunchpadLayer, |
|
14550.1.1
by Steve Kowalik
Run format-imports over lib/lp and lib/canonical/launchpad |
48 |
LayerProcessController, |
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
49 |
LibrarianLayer, |
50 |
YUIAppServerLayer, |
|
51 |
)
|
|
52 |
||
14550.1.1
by Steve Kowalik
Run format-imports over lib/lp and lib/canonical/launchpad |
53 |
|
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
54 |
EXPLOSIVE_ERRORS = (SystemExit, MemoryError, KeyboardInterrupt) |
55 |
||
13992.1.3
by Gary Poster
clean more lint |
56 |
|
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
57 |
class setup: |
58 |
"""Decorator to mark a function as a fixture available from JavaScript.
|
|
59 |
||
60 |
This makes the function available to call from JS integration tests over
|
|
61 |
XHR. The fixture setup can have one or more cleanups tied to it with
|
|
62 |
``add_cleanup`` decorator/callable and can be composed with another
|
|
63 |
function with the ``extend`` decorator/callable.
|
|
64 |
"""
|
|
65 |
def __init__(self, function, extends=None): |
|
66 |
self._cleanups = [] |
|
67 |
self._function = function |
|
68 |
self._extends = extends |
|
69 |
# We can't use locals because we want to affect the function's module,
|
|
70 |
# not this one.
|
|
71 |
module = sys.modules[function.__module__] |
|
72 |
fixtures = getattr(module, '_fixtures_', None) |
|
73 |
if fixtures is None: |
|
74 |
fixtures = module._fixtures_ = {} |
|
75 |
fixtures[function.__name__] = self |
|
76 |
||
77 |
def __call__(self, request, data): |
|
78 |
"""Call the originally decorated setup function."""
|
|
79 |
if self._extends is not None: |
|
80 |
self._extends(request, data) |
|
81 |
self._function(request, data) |
|
82 |
||
83 |
def add_cleanup(self, function): |
|
84 |
"""Add a cleanup function to be executed on teardown, FILO."""
|
|
85 |
self._cleanups.append(function) |
|
86 |
return self |
|
87 |
||
88 |
def teardown(self, request, data): |
|
89 |
"""Run all registered cleanups. If no cleanups, a no-op."""
|
|
90 |
for f in reversed(self._cleanups): |
|
91 |
f(request, data) |
|
92 |
if self._extends is not None: |
|
93 |
self._extends.teardown(request, data) |
|
94 |
||
95 |
def extend(self, function): |
|
96 |
return setup(function, self) |
|
97 |
||
98 |
||
99 |
def login_as_person(person): |
|
100 |
"""This is a helper function designed to be used within a fixture.
|
|
13992.1.3
by Gary Poster
clean more lint |
101 |
|
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
102 |
Provide a person, such as one generated by LaunchpadObjectFactory, and
|
103 |
the browser will become logged in as this person.
|
|
13992.1.3
by Gary Poster
clean more lint |
104 |
|
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
105 |
Explicit tear-down is unnecessary because the database is reset at the end
|
106 |
of every test, and the cookie is discarded.
|
|
107 |
"""
|
|
108 |
if person.is_team: |
|
109 |
raise AssertionError("Please do not try to login as a team") |
|
110 |
email = removeSecurityProxy(person.preferredemail).email |
|
111 |
request = get_current_browser_request() |
|
112 |
assert request is not None, "We do not have a browser request." |
|
113 |
authutil = getUtility(IPlacelessAuthUtility) |
|
114 |
principal = authutil.getPrincipalByLogin(email, want_password=False) |
|
115 |
launchbag = getUtility(IOpenLaunchBag) |
|
116 |
launchbag.setLogin(email) |
|
117 |
logInPrincipal(request, principal, email) |
|
118 |
||
119 |
||
120 |
class CloseDbResult: |
|
121 |
implements(IResult) |
|
122 |
||
123 |
# This is machinery, not content. We specify our security checker here
|
|
124 |
# directly for clarity.
|
|
125 |
__Security_checker__ = NamesChecker(['next', '__iter__']) |
|
126 |
||
127 |
def __iter__(self): |
|
128 |
try: |
|
129 |
# Reset the session.
|
|
130 |
LaunchpadLayer.resetSessionDb() |
|
13992.1.3
by Gary Poster
clean more lint |
131 |
# Yield control to asyncore for a second, just to be a
|
132 |
# little bit nice. We could be even nicer by moving this
|
|
133 |
# whole teardown/setup dance to a thread and waiting for
|
|
134 |
# it to be done, but there's not a (known) compelling need
|
|
135 |
# for that right now, and doing it this way is slightly
|
|
136 |
# simpler.
|
|
137 |
yield '' |
|
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
138 |
DatabaseLayer.testSetUp() |
13992.1.3
by Gary Poster
clean more lint |
139 |
yield '' |
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
140 |
# Reset the librarian.
|
141 |
LibrarianLayer.testTearDown() |
|
13992.1.3
by Gary Poster
clean more lint |
142 |
yield '' |
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
143 |
# Reset the database.
|
144 |
DatabaseLayer.testTearDown() |
|
13992.1.3
by Gary Poster
clean more lint |
145 |
yield '' |
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
146 |
LibrarianLayer.testSetUp() |
147 |
except (SystemExit, KeyboardInterrupt): |
|
148 |
raise
|
|
149 |
except: |
|
150 |
print "Hm, serious error when trying to clean up the test." |
|
151 |
traceback.print_exc() |
|
152 |
# We're done, so we can yield the body.
|
|
153 |
yield '\n' |
|
154 |
||
155 |
||
156 |
class YUITestFixtureControllerView(LaunchpadView): |
|
157 |
"""Dynamically loads YUI test along their fixtures run over an app server.
|
|
158 |
"""
|
|
159 |
||
160 |
JAVASCRIPT = 'JAVASCRIPT' |
|
161 |
HTML = 'HTML' |
|
162 |
SETUP = 'SETUP' |
|
163 |
TEARDOWN = 'TEARDOWN' |
|
14151.2.1
by Gary Poster
add yuixhr test improvements back |
164 |
INDEX = 'INDEX' |
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
165 |
|
166 |
page_template = dedent("""\ |
|
167 |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
|
168 |
"http://www.w3.org/TR/html4/strict.dtd">
|
|
169 |
<html>
|
|
170 |
<head>
|
|
171 |
<title>Test</title>
|
|
172 |
<script type="text/javascript"
|
|
173 |
src="/+icing/rev%(revno)s/build/launchpad.js"></script> |
|
174 |
<link rel="stylesheet"
|
|
175 |
href="/+icing/yui/assets/skins/sam/skin.css"/>
|
|
176 |
<link rel="stylesheet" href="/+icing/rev%(revno)s/combo.css"/> |
|
177 |
<style>
|
|
178 |
/* Taken and customized from testlogger.css */
|
|
179 |
.yui-console-entry-src { display:none; }
|
|
180 |
.yui-console-entry.yui-console-entry-pass .yui-console-entry-cat {
|
|
181 |
background-color: green;
|
|
182 |
font-weight: bold;
|
|
183 |
color: white;
|
|
184 |
}
|
|
185 |
.yui-console-entry.yui-console-entry-fail .yui-console-entry-cat {
|
|
186 |
background-color: red;
|
|
187 |
font-weight: bold;
|
|
188 |
color: white;
|
|
189 |
}
|
|
190 |
.yui-console-entry.yui-console-entry-ignore .yui-console-entry-cat {
|
|
191 |
background-color: #666;
|
|
192 |
font-weight: bold;
|
|
193 |
color: white;
|
|
194 |
}
|
|
195 |
</style>
|
|
196 |
<script type="text/javascript" src="%(test_module)s"></script> |
|
197 |
</head>
|
|
198 |
<body class="yui3-skin-sam">
|
|
199 |
<div id="log"></div>
|
|
14151.2.1
by Gary Poster
add yuixhr test improvements back |
200 |
<p>Want to re-run your test?</p>
|
201 |
<ul>
|
|
202 |
<li><a href="?">Reload test JS</a></li>
|
|
203 |
<li><a href="?reload=1">Reload test JS and the associated
|
|
204 |
Python fixtures</a></li>
|
|
205 |
</ul>
|
|
206 |
<p>Don't forget to run <code>make jsbuild</code> and then do a
|
|
207 |
hard reload of this page if you change a file that is built
|
|
208 |
into launchpad.js!</p>
|
|
209 |
<p>If you change Python code other than the fixtures, you must
|
|
210 |
restart the server. Sorry.</p>
|
|
211 |
</body>
|
|
212 |
</html>
|
|
213 |
""") |
|
214 |
||
215 |
index_template = dedent("""\ |
|
216 |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
|
217 |
"http://www.w3.org/TR/html4/strict.dtd">
|
|
218 |
<html>
|
|
219 |
<head>
|
|
220 |
<title>YUI XHR Tests</title>
|
|
221 |
<script type="text/javascript"
|
|
222 |
src="/+icing/rev%(revno)s/build/launchpad.js"></script> |
|
223 |
<link rel="stylesheet"
|
|
224 |
href="/+icing/yui/assets/skins/sam/skin.css"/>
|
|
225 |
<link rel="stylesheet" href="/+icing/rev%(revno)s/combo.css"/> |
|
226 |
<style>
|
|
227 |
ul {
|
|
228 |
text-align: left;
|
|
229 |
}
|
|
230 |
body, ul, h1 {
|
|
231 |
margin: 0.3em;
|
|
232 |
padding: 0.3em;
|
|
233 |
}
|
|
234 |
</style>
|
|
235 |
</head>
|
|
236 |
<body class="yui3-skin-sam">
|
|
237 |
<h1>YUI XHR Tests</h1>
|
|
238 |
<ul>%(tests)s</ul> |
|
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
239 |
</body>
|
240 |
</html>
|
|
241 |
""") |
|
242 |
||
243 |
def __init__(self, context, request): |
|
244 |
super(YUITestFixtureControllerView, self).__init__(context, request) |
|
245 |
self.names = [] |
|
246 |
self.action = None |
|
247 |
self.fixtures = [] |
|
248 |
||
249 |
@property
|
|
250 |
def traversed_path(self): |
|
251 |
return os.path.join(*self.names) |
|
252 |
||
253 |
def initialize(self): |
|
14151.2.1
by Gary Poster
add yuixhr test improvements back |
254 |
if not self.names: |
255 |
self.action = self.INDEX |
|
256 |
return
|
|
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
257 |
path, ext = os.path.splitext(self.traversed_path) |
258 |
full_path = os.path.join(config.root, 'lib', path) |
|
259 |
if not os.path.exists(full_path + '.py'): |
|
260 |
raise NotFound(self, full_path + '.py', self.request) |
|
261 |
if not os.path.exists(full_path + '.js'): |
|
262 |
raise NotFound(self, full_path + '.js', self.request) |
|
263 |
||
264 |
if ext == '.js': |
|
265 |
self.action = self.JAVASCRIPT |
|
266 |
else: |
|
267 |
if self.request.method == 'GET': |
|
268 |
self.action = self.HTML |
|
269 |
else: |
|
270 |
self.fixtures = self.request.form['fixtures'].split(',') |
|
271 |
if self.request.form['action'] == 'setup': |
|
272 |
self.action = self.SETUP |
|
273 |
else: |
|
274 |
self.action = self.TEARDOWN |
|
275 |
||
276 |
# The following two zope methods publishTraverse and browserDefault
|
|
277 |
# allow this view class to take control of traversal from this point
|
|
278 |
# onwards. Traversed names just end up in self.names.
|
|
279 |
def publishTraverse(self, request, name): |
|
280 |
"""Traverse to the given name."""
|
|
281 |
# The two following constraints are enforced by the publisher.
|
|
282 |
assert os.path.sep not in name, ( |
|
283 |
'traversed name contains os.path.sep: %s' % name) |
|
284 |
assert name != '..', 'traversing to ..' |
|
14151.2.1
by Gary Poster
add yuixhr test improvements back |
285 |
if name: |
286 |
self.names.append(name) |
|
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
287 |
return self |
288 |
||
289 |
def browserDefault(self, request): |
|
290 |
return self, () |
|
291 |
||
14151.2.1
by Gary Poster
add yuixhr test improvements back |
292 |
@property
|
293 |
def module_name(self): |
|
294 |
return '.'.join(self.names) |
|
295 |
||
296 |
def get_fixtures(self): |
|
297 |
module = __import__( |
|
298 |
self.module_name, globals(), locals(), ['_fixtures_'], 0) |
|
299 |
return module._fixtures_ |
|
300 |
||
301 |
def renderINDEX(self): |
|
302 |
root = os.path.join(config.root, 'lib') |
|
303 |
test_lines = [] |
|
304 |
for path in find_tests(root): |
|
305 |
test_path = '/+yuitest/' + '/'.join(path) |
|
306 |
module_name = '.'.join(path) |
|
307 |
try: |
|
308 |
module = __import__( |
|
309 |
module_name, globals(), locals(), ['test_suite'], 0) |
|
310 |
except ImportError: |
|
311 |
warning = 'cannot import Python fixture file' |
|
312 |
else: |
|
313 |
try: |
|
314 |
suite_factory = module.test_suite |
|
315 |
except AttributeError: |
|
316 |
warning = 'cannot find test_suite' |
|
317 |
else: |
|
318 |
try: |
|
319 |
suite = suite_factory() |
|
320 |
except EXPLOSIVE_ERRORS: |
|
321 |
raise
|
|
322 |
except: |
|
323 |
warning = 'test_suite raises errors' |
|
324 |
else: |
|
325 |
case = None |
|
326 |
for case in suite: |
|
327 |
if isinstance(case, YUIAppServerTestCase): |
|
328 |
root_url = config.appserver_root_url( |
|
329 |
case.facet) |
|
330 |
if root_url != 'None': |
|
331 |
test_path = root_url + test_path |
|
332 |
warning = '' |
|
333 |
break
|
|
334 |
else: |
|
335 |
warning = ( |
|
336 |
'test suite is not instance of '
|
|
337 |
'YUIAppServerTestCase') |
|
338 |
link = '<a href="%s">%s</a>' % (test_path, test_path) |
|
339 |
if warning: |
|
340 |
warning = ' <span class="warning">%s</span>' % warning |
|
341 |
test_lines.append('<li>%s%s</li>' % (link, warning)) |
|
342 |
return self.index_template % { |
|
343 |
'revno': revno, |
|
344 |
'tests': '\n'.join(test_lines)} |
|
345 |
||
346 |
def renderJAVASCRIPT(self): |
|
347 |
self.request.response.setHeader('Content-Type', 'text/javascript') |
|
348 |
self.request.response.setHeader('Cache-Control', 'no-cache') |
|
349 |
return open( |
|
350 |
os.path.join(config.root, 'lib', self.traversed_path)) |
|
351 |
||
352 |
def renderHTML(self): |
|
353 |
self.request.response.setHeader('Content-Type', 'text/html') |
|
354 |
self.request.response.setHeader('Cache-Control', 'no-cache') |
|
355 |
if ('INTERACTIVE_TESTS' in os.environ and |
|
356 |
'reload' in self.request.form): |
|
357 |
# We should try to reload the module.
|
|
358 |
module = sys.modules.get(self.module_name) |
|
359 |
if module is not None: |
|
360 |
del module._fixtures_ |
|
361 |
reload(module) |
|
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
362 |
return self.page_template % dict( |
363 |
test_module='/+yuitest/%s.js' % self.traversed_path, |
|
364 |
revno=revno) |
|
365 |
||
14151.2.1
by Gary Poster
add yuixhr test improvements back |
366 |
def renderSETUP(self): |
367 |
data = {} |
|
368 |
fixtures = self.get_fixtures() |
|
369 |
try: |
|
370 |
for fixture_name in self.fixtures: |
|
371 |
__traceback_info__ = (fixture_name, data) |
|
372 |
fixtures[fixture_name](self.request, data) |
|
373 |
except EXPLOSIVE_ERRORS: |
|
374 |
raise
|
|
375 |
except: |
|
376 |
self.request.response.setStatus(500) |
|
377 |
result = ''.join(format_exception(*sys.exc_info())) |
|
378 |
else: |
|
379 |
self.request.response.setHeader( |
|
380 |
'Content-Type', 'application/json') |
|
381 |
# We use the ProxyFactory so that the restful
|
|
382 |
# redaction code is always used.
|
|
383 |
result = simplejson.dumps( |
|
384 |
ProxyFactory(data), cls=ResourceJSONEncoder) |
|
385 |
return result |
|
386 |
||
387 |
def renderTEARDOWN(self): |
|
388 |
data = simplejson.loads(self.request.form['data']) |
|
389 |
fixtures = self.get_fixtures() |
|
390 |
try: |
|
391 |
for fixture_name in reversed(self.fixtures): |
|
392 |
__traceback_info__ = (fixture_name, data) |
|
393 |
fixtures[fixture_name].teardown(self.request, data) |
|
394 |
except EXPLOSIVE_ERRORS: |
|
395 |
raise
|
|
396 |
except: |
|
397 |
self.request.response.setStatus(500) |
|
398 |
result = ''.join(format_exception(*sys.exc_info())) |
|
399 |
else: |
|
400 |
# Remove the session cookie, in case we have one.
|
|
401 |
self.request.response.expireCookie( |
|
402 |
getUtility(IClientIdManager).namespace) |
|
403 |
# Blow up the database once we are out of this transaction
|
|
404 |
# by passing a result that will do so when it is iterated
|
|
405 |
# through in asyncore.
|
|
406 |
self.request.response.setHeader('Content-Length', 1) |
|
407 |
result = CloseDbResult() |
|
408 |
return result |
|
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
409 |
|
410 |
def render(self): |
|
14151.2.1
by Gary Poster
add yuixhr test improvements back |
411 |
return getattr(self, 'render' + self.action)() |
412 |
||
413 |
||
414 |
def find_tests(root): |
|
415 |
for dirpath, dirnames, filenames in os.walk(root): |
|
416 |
dirpath = os.path.relpath(dirpath, root) |
|
417 |
for filename in filenames: |
|
418 |
if fnmatchcase(filename, 'test_*.js'): |
|
419 |
name, ext = os.path.splitext(filename) |
|
420 |
if name + '.py' in filenames: |
|
421 |
names = dirpath.split(os.path.sep) |
|
422 |
names.append(name) |
|
423 |
yield names |
|
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
424 |
|
13992.1.3
by Gary Poster
clean more lint |
425 |
|
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
426 |
# This class cannot be imported directly into a test suite because
|
427 |
# then the test loader will sniff and (try to) run it. Use make_suite
|
|
428 |
# instead (or import this module rather than this class).
|
|
429 |
class YUIAppServerTestCase(AbstractYUITestCase): |
|
430 |
"Instantiate this test case with the Python fixture module name."
|
|
431 |
||
432 |
layer = YUIAppServerLayer |
|
433 |
_testMethodName = 'runTest' |
|
14151.2.4
by Gary Poster
incorporate timing limits per test on yuixhr tests |
434 |
# 5 minutes for the suite. Hopefully we never get close to this.
|
435 |
suite_timeout = 300000 |
|
14301.1.1
by Gary Poster
double the per-test timeout for yuixhr tests |
436 |
# 12 seconds for each test. Hopefully they are three or less for
|
437 |
# yuixhr tests, and less than one for pure JS tests, but
|
|
438 |
# occasionally buildbot runs over six seconds even for tests that
|
|
439 |
# are well-behaved locally and on ec2, so we up the limit to 12..
|
|
440 |
incremental_timeout = 12000 |
|
14362.1.1
by Gary Poster
increase time for first yuixhr test. This is only necessary on buildbot, and it is not clear why. |
441 |
# 45 seconds for the first test, to include warmup time. These times
|
442 |
# are wildly large, and they are only necessary on buildbot. ec2 and
|
|
443 |
# local instances are much, much faster. We have not yet investigated
|
|
444 |
# why buildbot is so slow for these.
|
|
445 |
initial_timeout = 45000 |
|
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
446 |
|
14151.2.1
by Gary Poster
add yuixhr test improvements back |
447 |
def __init__(self, module_name, facet='mainsite'): |
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
448 |
self.module_name = module_name |
14151.2.1
by Gary Poster
add yuixhr test improvements back |
449 |
self.facet = facet |
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
450 |
# This needs to be done early so the "id" is set correctly.
|
451 |
self.test_path = self.module_name.replace('.', '/') |
|
452 |
super(YUIAppServerTestCase, self).__init__() |
|
453 |
||
454 |
def setUp(self): |
|
14151.2.1
by Gary Poster
add yuixhr test improvements back |
455 |
config = LayerProcessController.appserver_config |
456 |
root_url = config.appserver_root_url(self.facet) |
|
457 |
self.html_uri = '%s/+yuitest/%s' % (root_url, self.test_path) |
|
13992.1.1
by Gary Poster
Add yui xhr integration test support. |
458 |
super(YUIAppServerTestCase, self).setUp() |
459 |
||
460 |
runTest = AbstractYUITestCase.checkResults |
|
461 |
||
462 |
||
14151.2.1
by Gary Poster
add yuixhr test improvements back |
463 |
def make_suite(module_name, facet='mainsite'): |
464 |
return unittest.TestSuite([YUIAppServerTestCase(module_name, facet)]) |