@@ -630,17 +630,19 @@ def run_tests(context, app=None, module=None, doctype=None, test=(), driver=None | |||
tests = test | |||
site = get_single_site(context) | |||
frappe.init(site=site) | |||
# sel.start(verbose, driver) | |||
if frappe.conf.run_selenium_tests: | |||
sel.start(context.verbose, driver) | |||
try: | |||
frappe.init(site=site) | |||
ret = frappe.test_runner.main(app, module, doctype, context.verbose, tests=tests, force=context.force) | |||
if len(ret.failures) == 0 and len(ret.errors) == 0: | |||
ret = 0 | |||
finally: | |||
pass | |||
# sel.close() | |||
if frappe.conf.run_selenium_tests: | |||
sel.close() | |||
sys.exit(ret) | |||
@@ -44,7 +44,7 @@ | |||
<div class="checkbox"> | |||
<label> | |||
<input type="checkbox" name="always_insert"> | |||
{%= __("Always insert, even if ID is given.") %} | |||
{%= __("Don't update, but insert new records.") %} | |||
</label> | |||
</div> | |||
<div class="checkbox"> | |||
@@ -127,6 +127,8 @@ frappe.request.call = function(opts) { | |||
// call execute serverside request | |||
frappe.request.prepare = function(opts) { | |||
$("body").attr("data-ajax-state", "triggered"); | |||
// btn indicator | |||
if(opts.btn) $(opts.btn).prop("disabled", true); | |||
@@ -157,6 +159,8 @@ frappe.request.cleanup = function(opts, r) { | |||
// stop button indicator | |||
if(opts.btn) $(opts.btn).prop("disabled", false); | |||
$("body").attr("data-ajax-state", "complete"); | |||
// un-freeze page | |||
if(opts.freeze) frappe.dom.unfreeze(); | |||
@@ -112,6 +112,11 @@ def _add_test(path, filename, verbose, test_suite=None): | |||
# in /doctype/doctype/boilerplate/ | |||
return | |||
module = imp.load_source(filename[:-3], os.path.join(path, filename)) | |||
if getattr(module, "selenium_tests", False) and not frappe.conf.run_selenium_tests: | |||
return | |||
if not test_suite: | |||
test_suite = unittest.TestSuite() | |||
@@ -122,7 +127,6 @@ def _add_test(path, filename, verbose, test_suite=None): | |||
doctype = doc["name"] | |||
make_test_records(doctype, verbose) | |||
module = imp.load_source(filename[:-3], os.path.join(path, filename)) | |||
test_suite.addTest(unittest.TestLoader().loadTestsFromModule(module)) | |||
def make_test_records(doctype, verbose=0, force=False): | |||
@@ -5,26 +5,28 @@ from __future__ import unicode_literals | |||
import unittest, frappe | |||
from frappe.utils import sel | |||
# class TestLogin(unittest.TestCase): | |||
# def setUp(self): | |||
# sel.login() | |||
# | |||
# def test_login(self): | |||
# self.assertEquals(sel._driver.current_url, sel.get_localhost() + "/desk") | |||
# | |||
# def test_to_do(self): | |||
# sel.go_to_module("ToDo") | |||
# sel.find('.appframe-iconbar .icon-plus')[0].click() | |||
# sel.wait_for_page("Form/ToDo") | |||
# sel.set_field("description", "test description", "textarea") | |||
# sel.primary_action() | |||
# self.assertTrue(sel.wait_for_state("clean")) | |||
selenium_tests = True | |||
# def test_material_request(self): | |||
# sel.new_doc("Stock", "Material Request") | |||
# sel.add_child("items") | |||
# sel.set_field("item_code", "_Test Item") | |||
# sel.set_field("schedule_date", "10-10-2014") | |||
# sel.primary_action() | |||
# sel.wait_for_state("clean") | |||
class TestLogin(unittest.TestCase): | |||
def setUp(self): | |||
sel.login() | |||
def test_login(self): | |||
self.assertEquals(sel._driver.current_url, sel.get_localhost() + "/desk") | |||
def test_to_do(self): | |||
sel.go_to_module("ToDo") | |||
sel.primary_action() | |||
sel.wait_for_page("Form/ToDo") | |||
sel.set_field("description", "test description", "textarea") | |||
sel.primary_action() | |||
self.assertTrue(sel.wait_for_state("clean")) | |||
# def test_material_request(self): | |||
# sel.new_doc("Stock", "Material Request") | |||
# sel.add_child("items") | |||
# sel.set_field("item_code", "_Test Item") | |||
# sel.set_field("schedule_date", "10-10-2014") | |||
# sel.primary_action() | |||
# sel.wait_for_state("clean") | |||
@@ -17,7 +17,7 @@ import sys | |||
host = "http://localhost" | |||
pipe = None | |||
port = "8888" | |||
port = "8000" | |||
_driver = None | |||
_verbose = None | |||
logged_in = False | |||
@@ -32,6 +32,7 @@ def start(verbose=None, driver=None): | |||
_verbose = verbose | |||
_driver = getattr(webdriver, driver or "PhantomJS")() | |||
_driver.set_window_size(1080,800) | |||
signal.signal(signal.SIGINT, signal_handler) | |||
@@ -41,7 +42,7 @@ def signal_handler(signal, frame): | |||
def start_test_server(verbose): | |||
global pipe | |||
pipe = subprocess.Popen(["frappe", "--serve", "--port", port], stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |||
pipe = subprocess.Popen(["bench", "serve", "--port", port], stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |||
#time.sleep(5) | |||
while not pipe.stderr.readline(): | |||
time.sleep(0.5) | |||
@@ -67,15 +68,15 @@ def go_to_module(module_name, item=None): | |||
global cur_route | |||
# desktop | |||
find(".navbar-brand")[0].click() | |||
find(".navbar-home", True)[0].click() | |||
cur_route = None | |||
wait("#page-desktop") | |||
page = "Module/" + module_name | |||
m = find('#page-desktop [data-link="{0}"]'.format(page)) | |||
m = find('#page-desktop [data-link="{0}"] .app-icon'.format(page)) | |||
if not m: | |||
page = "List/" + module_name | |||
m = find('#page-desktop [data-link="{0}"]'.format(page)) | |||
m = find('#page-desktop [data-link="{0}"] .app-icon'.format(page)) | |||
if not m: | |||
raise Exception, "Module {0} not found".format(module_name) | |||
@@ -90,7 +91,7 @@ def go_to_module(module_name, item=None): | |||
def new_doc(module, doctype): | |||
go_to_module(module, doctype) | |||
find('.appframe-iconbar .icon-plus')[0].click() | |||
primary_action() | |||
wait_for_page("Form/" + doctype) | |||
def add_child(fieldname): | |||
@@ -112,37 +113,45 @@ def set_select(fieldname, value): | |||
wait_for_ajax() | |||
def primary_action(): | |||
find(".appframe-titlebar .btn-primary")[0].click() | |||
wait_till_visible(".page-actions .primary-action").click() | |||
wait_for_ajax() | |||
def wait_for_ajax(): | |||
wait('body[data-ajax-state="complete"]', True) | |||
def wait_for_page(name): | |||
global cur_route | |||
cur_route = None | |||
route = '[data-page-route="{0}"]'.format(name) | |||
wait_for_ajax() | |||
elem = wait(route) | |||
wait_for_ajax() | |||
cur_route = route | |||
return elem | |||
def wait_till_clickable(selector): | |||
if cur_route: | |||
selector = cur_route + " " + selector | |||
return get_wait().until(EC.element_to_be_clickable((By.CSS_SELECTOR, selector))) | |||
def wait_till_visible(selector): | |||
if cur_route: | |||
selector = cur_route + " " + selector | |||
return get_wait().until(EC.visibility_of_element_located((By.CSS_SELECTOR, selector))) | |||
def wait_for_ajax(): | |||
wait('body[data-ajax-state="complete"]', True) | |||
def wait_for_state(state): | |||
return wait(cur_route + '[data-state="{0}"]'.format(state), True) | |||
def wait(selector, everywhere=False): | |||
if cur_route and not everywhere: | |||
selector = cur_route + " " + selector | |||
try: | |||
elem = WebDriverWait(_driver, 20).until( | |||
EC.presence_of_element_located((By.CSS_SELECTOR, selector))) | |||
if _verbose: | |||
print "found " + selector | |||
except TimeoutException: | |||
print "not found " + selector | |||
raise | |||
elem = get_wait().until(EC.presence_of_element_located((By.CSS_SELECTOR, selector))) | |||
return elem | |||
def get_wait(): | |||
return WebDriverWait(_driver, 10) | |||
def set_input(selector, text): | |||
elem = find(selector)[0] | |||
elem.clear() | |||
@@ -5,5 +5,6 @@ | |||
"mail_server": "smtp.example.com", | |||
"mail_login": "test@example.com", | |||
"mail_password": "test", | |||
"admin_password": "admin" | |||
"admin_password": "admin", | |||
"run_selenium_tests": 1 | |||
} |