chore: dropped legacy selenium dependant tests

selenium TestDriver deprecated
--ui-tests flag in `bench run-tests` deprecated
This commit is contained in:
Gavin D'souza 2019-11-13 15:01:05 +05:30
parent cbd89842ee
commit ae48dfe2b4
24 changed files with 3 additions and 1348 deletions

View file

@ -507,26 +507,6 @@ def run_ui_tests(context, app, headless=False):
formatted_command = command.format(site_env=site_env, password_env=password_env, run_or_open=run_or_open)
frappe.commands.popen(formatted_command, cwd=app_base_path, raise_err=True)
@click.command('run-setup-wizard-ui-test')
@click.option('--app', help="App to run tests on, leave blank for all apps")
@click.option('--profile', is_flag=True, default=False)
@pass_context
def run_setup_wizard_ui_test(context, app=None, profile=False):
"Run setup wizard UI test"
import frappe.test_runner
site = get_site(context)
frappe.init(site=site)
frappe.connect()
ret = frappe.test_runner.run_setup_wizard_ui_test(app=app, verbose=context.verbose,
profile=profile)
if len(ret.failures) == 0 and len(ret.errors) == 0:
ret = 0
if os.environ.get('CI'):
sys.exit(ret)
@click.command('serve')
@click.option('--port', default=8000)
@click.option('--profile', is_flag=True, default=False)
@ -752,7 +732,6 @@ commands = [
reset_perms,
run_tests,
run_ui_tests,
run_setup_wizard_ui_test,
serve,
set_config,
show_config,

View file

@ -36,6 +36,9 @@ def main(app=None, module=None, doctype=None, verbose=False, tests=(),
with open(frappe.get_app_path(app, doctype_list_path), 'r') as f:
doctype = f.read().strip().splitlines()
if ui_tests:
print("Selenium testing has been deprecated\nUse bench --site {site_name} run-ui-tests for Cypress tests")
xmloutput_fh = None
if junit_xml_output:
xmloutput_fh = open(junit_xml_output, 'w')
@ -170,21 +173,6 @@ def run_tests_for_module(module, verbose=False, tests=(), profile=False):
return _run_unittest(module, verbose=verbose, tests=tests, profile=profile)
def run_setup_wizard_ui_test(app=None, verbose=False, profile=False):
'''Run setup wizard UI test using test_test_runner'''
frappe.flags.run_setup_wizard_ui_test = 1
return run_ui_tests(app=app, test=None, verbose=verbose, profile=profile)
def run_ui_tests(app=None, test=None, test_list=None, verbose=False, profile=False):
'''Run a single unit test for UI using test_test_runner'''
module = importlib.import_module('frappe.tests.ui.test_test_runner')
frappe.flags.ui_test_app = app
if test_list:
frappe.flags.ui_test_list = test_list
else:
frappe.flags.ui_test_path = test
return _run_unittest(module, verbose=verbose, tests=(), profile=profile)
def _run_unittest(modules, verbose=False, tests=(), profile=False):
test_suite = unittest.TestSuite()

View file

@ -1,85 +0,0 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
from __future__ import unicode_literals
import unittest, frappe, requests, time
from frappe.test_runner import make_test_records
from frappe.utils.selenium_testdriver import TestDriver
from six.moves.urllib.parse import urlparse
from frappe.frappeclient import FrappeOAuth2Client
class TestFrappeOAuth2Client(unittest.TestCase):
def setUp(self):
self.driver = TestDriver()
make_test_records("OAuth Client")
make_test_records("User")
self.client_id = frappe.get_all("OAuth Client", fields=["*"])[0].get("client_id")
# Set Frappe server URL reqired for id_token generation
try:
frappe_login_key = frappe.get_doc("Social Login Key", "frappe")
except frappe.DoesNotExistError:
frappe_login_key = frappe.new_doc("Social Login Key")
frappe_login_key.get_social_login_provider("Frappe", initialize=True)
frappe_login_key.base_url = "http://localhost:8000"
frappe_login_key.save()
def test_insert_note(self):
# Go to Authorize url
self.driver.get(
"api/method/frappe.integrations.oauth2.authorize?client_id=" +
self.client_id +
"&scope=all%20openid&response_type=code&redirect_uri=http%3A%2F%2Flocalhost"
)
time.sleep(2)
# Login
username = self.driver.find("#login_email")[0]
username.send_keys("test@example.com")
password = self.driver.find("#login_password")[0]
password.send_keys("Eastern_43A1W")
sign_in = self.driver.find(".btn-login")[0]
sign_in.submit()
time.sleep(2)
# Allow access to resource
allow = self.driver.find("#allow")[0]
allow.click()
time.sleep(2)
# Get authorization code from redirected URL
auth_code = urlparse(self.driver.driver.current_url).query.split("=")[1]
payload = "grant_type=authorization_code&code="
payload += auth_code
payload += "&redirect_uri=http%3A%2F%2Flocalhost&client_id="
payload += self.client_id
headers = {'content-type':'application/x-www-form-urlencoded'}
# Request for bearer token
token_response = requests.post( frappe.get_site_config().host_name +
"/api/method/frappe.integrations.oauth2.get_token", data=payload, headers=headers)
# Parse bearer token json
bearer_token = token_response.json()
client = FrappeOAuth2Client(frappe.get_site_config().host_name, bearer_token.get("access_token"))
notes = [
{"doctype": "Note", "title": "Sing", "public": True},
{"doctype": "Note", "title": "a", "public": True},
{"doctype": "Note", "title": "Song", "public": True},
{"doctype": "Note", "title": "of", "public": True},
{"doctype": "Note", "title": "sixpence", "public": True}
]
for note in notes:
client.insert(note)
self.assertTrue(len(frappe.get_all("Note")) == 5)

View file

@ -1,249 +0,0 @@
frappe.tests = {
data: {},
make: function(doctype, data) {
let dialog_is_active = () => {
return (
cur_dialog && (!cur_frm || cur_frm.doc.doctype != doctype)
);
};
return frappe.run_serially([
() => frappe.set_route('List', doctype),
() => frappe.new_doc(doctype),
() => {
if (frappe.quick_entry) {
frappe.quick_entry.dialog.$wrapper.find('.edit-full').click();
return frappe.timeout(1);
} else {
let root_node;
if (cur_tree) {
for (const key in cur_tree.nodes) {
if (cur_tree.nodes[key].parent_label && cur_tree.nodes[key].expandable) {
root_node = cur_tree.nodes[key].label;
break;
}
}
}
if (root_node){
frappe.tests.open_add_child_dialog(root_node);
return frappe.timeout(1);
}
}
},
() => {
if(dialog_is_active()) {
return frappe.tests.set_dialog_values(cur_dialog, data);
} else {
return frappe.tests.set_form_values(cur_frm, data);
}
},
() => {
if(dialog_is_active()) {
return cur_dialog.get_primary_btn().click();
} else {
return frappe.quick_entry ? frappe.quick_entry.insert() : cur_frm.save();
}
}
]);
},
open_add_child_dialog: (root_node) => {
frappe.tests.click_link(root_node);
frappe.timeout(1);
frappe.tests.click_button('Add Child');
},
set_form_values: (frm, data) => {
let tasks = [];
data.forEach(item => {
for (let key in item) {
let task = () => {
let value = item[key];
if ($.isArray(value)) {
return frappe.tests.set_grid_values(frm, key, value);
} else {
// single value
return frm.set_value(key, value);
}
};
tasks.push(task);
tasks.push(frappe.after_ajax);
tasks.push(() => frappe.timeout(0.4));
}
});
// set values
return frappe.run_serially(tasks);
},
set_dialog_values: (dialog, data) => {
let tasks = [];
data.forEach(item => {
for (let key in item) {
let task = () => {
let value = item[key];
return dialog.set_value(key, value);
};
tasks.push(task);
tasks.push(frappe.after_ajax);
tasks.push(() => frappe.timeout(0.4));
}
});
return frappe.run_serially(tasks);
},
set_grid_values: (frm, key, value) => {
// set value in grid
let grid = frm.get_field(key).grid;
grid.remove_all();
let grid_row_tasks = [];
// build tasks for each row
value.forEach(d => {
grid_row_tasks.push(() => {
let grid_value_tasks = [];
grid_value_tasks.push(() => grid.add_new_row());
grid_value_tasks.push(() => grid.get_row(-1).toggle_view(true));
grid_value_tasks.push(() => frappe.timeout(0.5));
// build tasks to set each row value
d.forEach(child_value => {
for (let child_key in child_value) {
grid_value_tasks.push(() => {
let grid_row = grid.get_row(-1);
return frappe.model.set_value(grid_row.doc.doctype,
grid_row.doc.name, child_key, child_value[child_key]);
});
grid_value_tasks.push(frappe.after_ajax);
grid_value_tasks.push(() => frappe.timeout(0.4));
}
});
return frappe.run_serially(grid_value_tasks);
});
});
return frappe.run_serially(grid_row_tasks);
},
setup_doctype: (doctype, data) => {
return frappe.run_serially([
() => frappe.set_route('List', doctype),
() => frappe.timeout(1),
() => {
frappe.tests.data[doctype] = [];
let expected = Object.keys(data);
cur_list.data.forEach((d) => {
frappe.tests.data[doctype].push(d.name);
if(expected.indexOf(d.name) !== -1) {
expected[expected.indexOf(d.name)] = null;
}
});
let tasks = [];
expected.forEach(function(d) {
if(d) {
tasks.push(() => frappe.tests.make(doctype,
data[d]));
}
});
return frappe.run_serially(tasks);
}]);
},
click_page_head_item: (text) => {
// Method to items present on the page header like New, Save, Delete etc.
let possible_texts = ["New", "Delete", "Save", "Yes"];
return frappe.run_serially([
() => {
if (text == "Menu"){
$(`span.menu-btn-group-label:contains('Menu'):visible`).click();
} else if (text == "Refresh") {
$(`.btn-secondary:contains('Refresh'):visible`).click();
} else if (possible_texts.includes(text)) {
$(`.btn-primary:contains("${text}"):visible`).click();
}
},
() => frappe.timeout(1)
]);
},
click_dropdown_item: (text) => {
// Method to click dropdown elements
return frappe.run_serially([
() => {
let li = $(`.dropdown-menu li:contains("${text}"):visible`).get(0);
$(li).find(`a`).click();
},
() => frappe.timeout(1)
]);
},
click_desktop_icon: (text) => {
// Method to click the desktop icons on the Desk, by their name
return frappe.run_serially([
() => $("#icon-grid > div > div.app-icon[title="+text+"]").click(),
() => frappe.timeout(1)
]);
},
is_visible: (text, tag='a') => {
// Method to check the visibility of an element
return $(`${tag}:contains("${text}")`).is(`:visible`);
},
/**
* Clicks a button on a form.
* @param {String} text - The button's text
* @return {frappe.timeout}
* @throws will throw an exception if a matching visible button is not found
*/
click_button: function(text) {
let element = $(`.btn:contains("${text}"):visible`);
if(!element.length) {
throw `did not find any button containing ${text}`;
}
element.click();
return frappe.timeout(0.5);
},
/**
* Clicks a link on a form.
* @param {String} text - The text of the link to be clicked
* @return {frappe.timeout}
* @throws will throw an exception if a link with the given text is not found
*/
click_link: function(text) {
let element = $(`a:contains("${text}"):visible`);
if(!element.length) {
throw `did not find any link containing ${text}`;
}
element.get(0).click();
return frappe.timeout(0.5);
},
/**
* Sets the given control to the value given.
* @param {String} fieldname - The Doctype's field name
* @param {String} value - The value the control should be changed to
* @return {frappe.timeout}
* @throws will throw an exception if the field is not found or is not visible
*/
set_control: function(fieldname, value) {
let control = $(`.form-control[data-fieldname="${fieldname}"]:visible`);
if(!control.length) {
throw `did not find any control with fieldname ${fieldname}`;
}
control.val(value).trigger('change');
return frappe.timeout(0.5);
},
/**
* Checks if given field is disabled.
* @param {String} fieldname - The Doctype field name
* @return {Boolean} true if condition is met
* @throws will throw an exception if the field is not found or is not a form control
*/
is_disabled_field: function(fieldname){
let control = $(`.form-control[data-fieldname="${fieldname}"]:disabled`);
if(!control.length) {
throw `did not find any control with fieldname ${fieldname}`;
} else {
return true;
}
}
};

View file

@ -1,79 +0,0 @@
QUnit.module('views');
QUnit.test("Calendar View Tests", function(assert) {
assert.expect(3);
let done = assert.async();
let random_text = frappe.utils.get_random(3);
let today = frappe.datetime.get_today()+" 16:20:35"; //arbitrary value taken to prevent cases like 12a for 12:00am and 12h to 24h conversion
let visible_time = () => {
// Method to return the start-time (hours) of the event visible
return $('.fc-time').text().split('p')[0]; // 'p' because the arbitrary time is pm
};
let event_title_text = () => {
// Method to return the title of the event visible
return $('.fc-title:visible').text();
};
frappe.run_serially([
// create 2 events, one private, one public
() => frappe.tests.make("Event", [
{subject: random_text + ':Pri'},
{starts_on: today},
{event_type: 'Private'}
]),
() => frappe.timeout(1),
() => frappe.tests.make("Event", [
{subject: random_text + ':Pub'},
{starts_on: today},
{event_type: 'Public'}
]),
() => frappe.timeout(1),
// Goto Calendar view
() => frappe.set_route(["List", "Event", "Calendar"]),
// clear filter
() => cur_list.filter_area.remove('event_type'),
() => frappe.timeout(2),
// Check if event is created
() => {
// Check if the event exists and if its title matches with the one created
assert.ok(event_title_text().includes(random_text + ':Pri'),
"Event title verified");
},
// check filter
() => cur_list.filter_area.add('Event', 'event_type', '=', 'Public'),
() => frappe.timeout(1),
() => {
// private event should be hidden
assert.notOk(event_title_text().includes(random_text + ':Pri'),
"Event title verified");
},
// Delete event
// Goto Calendar view
() => frappe.set_route(["List", "Event", "Calendar"]),
() => frappe.timeout(1),
// delete event
() => frappe.click_link(random_text + ':Pub'),
() => {
frappe.tests.click_page_head_item('Menu');
frappe.tests.click_dropdown_item('Delete');
},
() => frappe.timeout(0.5),
() => frappe.click_button('Yes'),
() => frappe.timeout(2),
() => frappe.set_route(["List", "Event", "Calendar"]),
() => frappe.click_button("Refresh"),
() => frappe.timeout(1),
// Check if event is deleted
() => assert.notOk(event_title_text().includes(random_text + ':Pub'),
"Event deleted"),
() => done()
]);
});

View file

@ -1,39 +0,0 @@
QUnit.module('controls');
QUnit.test("Test ControlGeolocation", function(assert) {
assert.expect(1);
const random_name = frappe.utils.get_random(3).toLowerCase();
let done = assert.async();
// geolocation alert dialog suppressed (only secure origins or localhost allowed)
window.alert = function() {
console.log.apply(console, arguments); //eslint-disable-line
};
frappe.run_serially([
() => {
return frappe.tests.make('Custom Field', [
{dt: 'ToDo'},
{fieldtype: 'Geolocation'},
{label: random_name},
]);
},
() => frappe.set_route('List', 'ToDo'),
() => frappe.new_doc('ToDo'),
() => {
if (frappe.quick_entry)
{
frappe.quick_entry.dialog.$wrapper.find('.edit-full').click();
return frappe.timeout(1);
}
},
() => {
const control = $(`.frappe-control[data-fieldname="${random_name}"]`);
return assert.ok(control.data('fieldtype') === 'Geolocation');
},
() => done()
]);
});

View file

@ -1,57 +0,0 @@
QUnit.module('controls');
QUnit.test("Test ControlHTML", function(assert) {
assert.expect(3);
const random_name = frappe.utils.get_random(3).toLowerCase();
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make('Custom Field', [
{dt: 'ToDo'},
{fieldtype: 'HTML'},
{label: random_name},
{options: '<h3> Test </h3>'}
]);
},
() => {
return frappe.tests.make('Custom Field', [
{dt: 'ToDo'},
{fieldtype: 'HTML'},
{label: random_name + "_template"},
{options: '<h3> Test {{ doc.status }} </h3>'}
]);
},
() => frappe.set_route('List', 'ToDo'),
() => frappe.new_doc('ToDo'),
() => {
if (frappe.quick_entry)
{
frappe.quick_entry.dialog.$wrapper.find('.edit-full').click();
return frappe.timeout(1);
}
},
() => {
const control = $(`.frappe-control[data-fieldname="${random_name}"]`)[0];
return assert.ok(control.innerHTML === '<h3> Test </h3>');
},
() => {
const control = $(`.frappe-control[data-fieldname="${random_name}_template"]`)[0];
// refresh input must be called independently
cur_frm.get_field(`${random_name}_template`).refresh_input();
return assert.ok(control.innerHTML === '<h3> Test Open </h3>');
},
() => frappe.tests.set_control("status", "Closed"),
() => frappe.timeout(1),
() => {
const control = $(`.frappe-control[data-fieldname="${random_name}_template"]`)[0];
// refresh input must be called independently
cur_frm.get_field(`${random_name}_template`).refresh_input();
return assert.ok(control.innerHTML === '<h3> Test Closed </h3>');
},
() => done()
]);
});

View file

@ -1,31 +0,0 @@
QUnit.module('views');
QUnit.test("Test: Setting column colour [Kanban view]", function(assert) {
assert.expect(3);
let done = assert.async();
function get_column(name, colour) {
return ('.kanban-column:contains('+name+')>div>div>ul>li>div.'+colour);
}
frappe.run_serially([
() => frappe.set_route("List", "ToDo", "Kanban", "Kanban test"),
() => frappe.timeout(1),
() => assert.deepEqual(["List", "ToDo", "Kanban", "Kanban test"], frappe.get_route(),
"Kanban view opened successfully."),
() => {
// set colour for columns
$(get_column('High', "red")).click();
$(get_column('Medium', "green")).click();
$(get_column('Low', "yellow")).click();
},
() => frappe.timeout(1),
() => {
//check if different colours are set
assert.equal($('.red > span')[0].innerText, 'High',
"Colour is set for kanban column.");
assert.equal($('.green > span')[0].innerText, 'Medium',
"Different colour is set for other column.");
},
() => done()
]);
});

View file

@ -1,34 +0,0 @@
QUnit.module('views');
QUnit.test("Test: Creation [Kanban view]", function(assert) {
assert.expect(2);
let done = assert.async();
const board_name = 'Kanban test';
frappe.run_serially([
() => frappe.set_route("List", "ToDo", "List"),
// wait for cur_list to initialize
() => cur_list.init(),
// click kanban in side bar
() => frappe.tests.click_link('Kanban'),
() => frappe.tests.click_link('New Kanban Board'),
() => frappe.timeout(0.5),
// create new kanban
() => {
assert.equal(cur_dialog.title, 'New Kanban Board',
"Dialog for new kanban opened.");
cur_dialog.set_value('board_name', board_name);
cur_dialog.set_value('field_name', 'Priority');
},
() => frappe.timeout(0.5),
() => cur_dialog.get_primary_btn().click(),
() => frappe.timeout(1),
() => frappe.set_route("List", "Kanban Board", "List"),
() => frappe.timeout(0.5),
// check in kanban list if new kanban is created
() => assert.equal(cur_list.data[0].name, board_name,
"Added kanban is visible in kanban list."),
() => done()
]);
});

View file

@ -1,27 +0,0 @@
QUnit.module('views');
QUnit.test("Test: Filters [Kanban view]", function(assert) {
assert.expect(3);
let done = assert.async();
frappe.run_serially([
() => frappe.set_route("List", "ToDo", "Kanban", "Kanban test"),
() => frappe.timeout(1),
() => {
assert.deepEqual(["List", "ToDo", "Kanban", "Kanban test"], frappe.get_route(),
"Kanban view opened successfully.");
},
// set filter values
() => cur_list.filter_area.add('ToDo', 'priority', '=', 'Low'),
() => frappe.timeout(1),
() => cur_list.page.btn_secondary.click(),
() => frappe.timeout(1),
() => {
assert.equal(cur_list.data[0].priority, 'Low',
'visible element has low priority');
let non_low_items = cur_list.data.filter(d => d.priority != 'Low');
assert.equal(non_low_items.length, 0, 'No item without low priority');
},
() => done()
]);
});

View file

@ -1,29 +0,0 @@
QUnit.module('views');
QUnit.test("Test: Kanban view", function(assert) {
assert.expect(4);
let done = assert.async();
frappe.run_serially([
() => frappe.set_route("List", "ToDo", "List"),
// calculate number of element in list
() => frappe.timeout(1),
() => frappe.set_route("List", "ToDo", "Kanban", "Kanban test"),
() => frappe.timeout(2),
() => {
assert.equal('Kanban', cur_list.view_name,
"Current view is kanban.");
assert.equal("Kanban test", cur_list.page_title,
"Kanban view opened successfully.");
// check if all elements are visible in kanban view
const $high_priority_cards =
$('.kanban-column[data-column-value="High"] .kanban-card-wrapper');
const $low_priority_cards =
$('.kanban-column[data-column-value="Low"] .kanban-card-wrapper');
assert.equal($high_priority_cards.length, 1);
assert.equal($low_priority_cards.length, 1);
},
() => done()
]);
});

View file

@ -1,19 +0,0 @@
QUnit.module('form');
QUnit.test("Test Linked With", function(assert) {
assert.expect(2);
const done = assert.async();
frappe.run_serially([
() => frappe.set_route('Form', 'Module Def', 'Contacts'),
() => frappe.tests.click_page_head_item('Menu'),
() => frappe.tests.click_dropdown_item('Links'),
() => frappe.timeout(4),
() => {
assert.equal(cur_dialog.title, 'Linked With', 'Linked with dialog is opened');
const link_tables_count = cur_dialog.$wrapper.find('.list-item-table').length;
assert.equal(link_tables_count, 2, 'Two DocTypes are linked with Contacts');
},
done
]);
});

View file

@ -1,39 +0,0 @@
QUnit.module('views');
QUnit.test("Test list filters", function(assert) {
assert.expect(3);
let done = assert.async();
frappe.run_serially([
() => {
return frappe.tests.make('ToDo', [
{description: 'low priority'},
{priority: 'Low'}
]);
},
() => {
return frappe.tests.make('ToDo', [
{description: 'high priority'},
{priority: 'High'}
]);
},
() => frappe.set_route('List', 'ToDo', 'List'),
() => frappe.timeout(0.5),
() => {
assert.deepEqual(['List', 'ToDo', 'List'], frappe.get_route(),
"List opened successfully.");
//set filter values
return frappe.set_control('priority', 'Low');
},
() => frappe.timeout(0.5),
() => cur_list.page.btn_secondary.click(),
() => frappe.timeout(1),
() => {
assert.equal(cur_list.data[0].priority, 'Low',
'visible element has low priority');
let non_low_items = cur_list.data.filter(d => d.priority != 'Low');
assert.equal(non_low_items.length, 0, 'no item without low priority');
},
() => done()
]);
});

View file

@ -1,25 +0,0 @@
QUnit.module('views');
QUnit.test("Test paging in list view", function(assert) {
assert.expect(5);
let done = assert.async();
frappe.run_serially([
() => frappe.set_route('List', 'DocType'),
() => frappe.timeout(0.5),
() => assert.deepEqual(['List', 'DocType', 'List'], frappe.get_route(),
"List opened successfully."),
//check elements less then page length [20 in this case]
() => assert.equal(cur_list.data.length, 20, 'show 20 items'),
() => frappe.click_button('More'),
() => frappe.timeout(2),
() => assert.equal(cur_list.data.length, 40, 'show more items'),
() => frappe.tests.click_button('100'),
() => frappe.timeout(2),
() => assert.ok(cur_list.data.length > 40, 'show 100 items'),
() => frappe.tests.click_button('20'),
() => frappe.timeout(2),
() => assert.equal(cur_list.data.length, 20, 'show 20 items again'),
() => done()
]);
});

View file

@ -1,33 +0,0 @@
QUnit.module('Setup');
QUnit.test("Test List Count", function(assert) {
assert.expect(3);
const done = assert.async();
frappe.run_serially([
() => frappe.set_route('List', 'DocType'),
() => frappe.timeout(0.5),
() => {
let count = $('.list-count').text().split(' ')[0];
assert.equal(cur_list.data.length, count, "Correct Count");
},
() => frappe.timeout(1),
() => cur_list.filter_area.add('Doctype', 'module', '=', 'Desk'),
() => frappe.click_button('Refresh'),
() => {
let count = $('.list-count').text().split(' ')[0];
assert.equal(cur_list.data.length, count, "Correct Count");
},
() => cur_list.filter_area.clear(),
() => frappe.timeout(1),
() => {
cur_list.filter_area.add('DocField', 'fieldname', 'like', 'owner');
let count = $('.list-count').text().split(' ')[0];
assert.equal(cur_list.data.length, count, "Correct Count");
},
done
]);
});

View file

@ -1,41 +0,0 @@
QUnit.module('views');
QUnit.test("Test modules view", function(assert) {
assert.expect(4);
let done = assert.async();
frappe.run_serially([
//click Document Share Report in Permissions section [Report]
() => frappe.set_route("modules", "Setup"),
() => frappe.timeout(0.5),
() => frappe.click_link('Document Share Report'),
() => assert.deepEqual(frappe.get_route(), ["List", "DocShare", "Report", "Document Share Report"],
'document share report'),
//click Print Setting in Printing section [Form]
() => frappe.set_route("modules", "Setup"),
() => frappe.timeout(0.5),
() => frappe.click_link('Print Settings'),
() => assert.deepEqual(frappe.get_route(), ["Form", "Print Settings"],
'print settings'),
//click Workflow Action in Workflow section [List]
() => frappe.set_route("modules", "Setup"),
() => frappe.timeout(0.5),
() => frappe.click_link('Workflow Action'),
() => assert.deepEqual(frappe.get_route(), ["List", "Workflow Action", "List"],
'workflow action'),
//click Workflow Action in Workflow section [List]
() => frappe.set_route("modules"),
() => frappe.timeout(0.5),
() => frappe.click_link('Tools'),
() => frappe.timeout(0.5),
() => frappe.click_link('To Do'),
() => assert.deepEqual(frappe.get_route(), ["List", "ToDo", "List"],
'todo list'),
() => done()
]);
});

View file

@ -1,38 +0,0 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
QUnit.module("Number Formatting");
QUnit.test("#,###.##", function(assert) {
assert.equal(format_number(100, "#,###.##"), "100.00");
assert.equal(format_number(1000, "#,###.##"), "1,000.00");
assert.equal(format_number(10000, "#,###.##"), "10,000.00");
assert.equal(format_number(1000000, "#,###.##"), "1,000,000.00");
assert.equal(format_number(1000000.345, "#,###.##"), "1,000,000.35");
});
QUnit.test("#,##,###.##", function(assert) {
assert.equal(format_number(100, "#,##,###.##"), "100.00");
assert.equal(format_number(1000, "#,##,###.##"), "1,000.00");
assert.equal(format_number(10000, "#,##,###.##"), "10,000.00");
assert.equal(format_number(1000000, "#,##,###.##"), "10,00,000.00");
assert.equal(format_number(1000000.341, "#,##,###.##"), "10,00,000.34");
assert.equal(format_number(10000000.341, "#,##,###.##"), "1,00,00,000.34");
});
QUnit.test("#.###,##", function(assert) {
assert.equal(format_number(100, "#.###,##"), "100,00");
assert.equal(format_number(1000, "#.###,##"), "1.000,00");
assert.equal(format_number(10000, "#.###,##"), "10.000,00");
assert.equal(format_number(1000000, "#.###,##"), "1.000.000,00");
assert.equal(format_number(1000000.345, "#.###,##"), "1.000.000,35");
});
QUnit.test("#.###", function(assert) {
assert.equal(format_number(100, "#.###"), "100");
assert.equal(format_number(1000, "#.###"), "1.000");
assert.equal(format_number(10000, "#.###"), "10.000");
assert.equal(format_number(-100000, "#.###"), "-100.000");
assert.equal(format_number(1000000, "#.###"), "1.000.000");
assert.equal(format_number(1000000.345, "#.###"), "1.000.000");
});

View file

@ -1,33 +0,0 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
from __future__ import unicode_literals
import unittest, frappe, time
from frappe.utils.selenium_testdriver import TestDriver
class TestSocialLoginKeyButtons(unittest.TestCase):
def setUp(self):
try:
frappe_login_key = frappe.get_doc("Social Login Key", "frappe")
except frappe.DoesNotExistError:
frappe_login_key = frappe.new_doc("Social Login Key")
frappe_login_key.get_social_login_provider("Frappe", initialize=True)
frappe_login_key.base_url = "http://localhost:8000"
frappe_login_key.enable_social_login = 1
frappe_login_key.client_id = "test_client_id"
frappe_login_key.client_secret = "test_client_secret"
frappe_login_key.save()
self.driver = TestDriver()
def test_login_buttons(self):
# Go to Login Page
self.driver.get("login")
time.sleep(2)
frappe_social_login = self.driver.find(".btn-frappe")
self.assertTrue(len(frappe_social_login) > 0)
def tearDown(self):
self.driver.close()

View file

@ -1,84 +0,0 @@
from __future__ import print_function, unicode_literals
from frappe.utils.selenium_testdriver import TestDriver
import unittest, os, frappe, time
class TestTestRunner(unittest.TestCase):
def test_test_runner(self):
if frappe.flags.run_setup_wizard_ui_test:
for setup_wizard_test in frappe.get_hooks("setup_wizard_test"):
passed = frappe.get_attr(setup_wizard_test)()
self.assertTrue(passed)
return
driver = TestDriver()
frappe.db.set_default('in_selenium', '1')
driver.login()
for test in get_tests():
if test.startswith('#'):
continue
timeout = 60
passed = False
if '#' in test:
test, comment = test.split('#')
test = test.strip()
if comment.strip()=='long':
timeout = 300
print('Running {0}...'.format(test))
frappe.db.set_value('Test Runner', None, 'module_path', test)
frappe.db.commit()
driver.refresh()
driver.set_route('Form', 'Test Runner')
try:
driver.click_primary_action()
driver.wait_for('#frappe-qunit-done', timeout=timeout)
console = driver.get_console()
passed = 'Tests Passed' in console
finally:
console = driver.get_console()
passed = 'Test Passed' in console
if frappe.flags.tests_verbose or not passed:
for line in console:
print(line)
print('-' * 40)
else:
self.assertTrue(passed)
time.sleep(1)
frappe.db.set_default('in_selenium', None)
driver.close()
def get_tests():
'''Get tests base on flag'''
frappe.db.set_value('Test Runner', None, 'app', frappe.flags.ui_test_app or '')
if frappe.flags.ui_test_list:
# list of tests
return get_tests_for(test_list=frappe.flags.ui_test_list)
elif frappe.flags.ui_test_path:
# specific test
return (frappe.flags.ui_test_path,)
elif frappe.flags.ui_test_app:
# specific app
return get_tests_for(frappe.flags.ui_test_app)
else:
# all apps
tests = []
for app in frappe.get_installed_apps():
tests.extend(get_tests_for(app))
return tests
def get_tests_for(app=None, test_list=None):
tests = []
if test_list:
# Get all tests from a particular txt file
app, test_list = test_list.split(os.path.sep, 1)
tests_path = frappe.get_app_path(app, test_list)
else:
# Get all tests for a particular app
tests_path = frappe.get_app_path(app, 'tests', 'ui', 'tests.txt')
if os.path.exists(tests_path):
with open(tests_path, 'r') as fileobj:
tests = fileobj.read().strip().splitlines()
return tests

View file

@ -1,50 +0,0 @@
from __future__ import print_function, unicode_literals
from frappe.utils.selenium_testdriver import TestDriver
import unittest
import time, os
class TestToDo(unittest.TestCase):
def setUp(self):
self.driver = TestDriver()
def test_todo(self):
self.driver.login()
# list view
self.driver.set_route('List', 'ToDo')
time.sleep(2)
# new
self.driver.click_primary_action()
time.sleep(2)
# set input
self.driver.set_text_editor('description', 'hello')
# save
self.driver.click_modal_primary_action()
time.sleep(2)
# refresh
self.driver.click_secondary_action()
time.sleep(2)
result_list = self.driver.get_visible_element('.result-list')
first_element_text = (result_list
.find_element_by_css_selector('.list-item')
.find_element_by_css_selector('.list-id').text)
# if os.environ.get('CI'):
# # we don't run this test in Travis as it always fails
# # reinforcing why we use Unit Testing instead of integration
# # testing
# return
self.assertTrue('hello' in first_element_text)
def tearDown(self):
self.driver.close()

View file

@ -1,20 +0,0 @@
frappe/tests/ui/test_number_format.js
frappe/tests/ui/test_list/test_list_filter.js
frappe/tests/ui/test_list/test_list_paging.js
frappe/tests/ui/test_module_view.js
frappe/tests/ui/test_calendar_view.js
frappe/tests/ui/test_kanban/test_kanban_creation.js
frappe/tests/ui/test_kanban/test_kanban_view.js
frappe/tests/ui/test_kanban/test_kanban_filters.js
frappe/tests/ui/test_kanban/test_kanban_column.js
frappe/core/doctype/report/test_query_report.js
frappe/tests/ui/test_linked_with.js
frappe/custom/doctype/customize_form/test_customize_form.js
frappe/desk/doctype/event/test_event.js
frappe/tests/ui/test_control_html.js
frappe/tests/ui/test_control_geolocation.js
frappe/core/doctype/role_profile/test_role_profile.js
frappe/core/doctype/user/test_user_with_role_profile.js
frappe/tests/ui/test_list_count.js
frappe/workflow/doctype/workflow/tests/test_workflow_create.js
frappe/workflow/doctype/workflow/tests/test_workflow_test.js

View file

@ -1,299 +0,0 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
from __future__ import unicode_literals, print_function
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
#from selenium.webdriver.support.select import Select
from selenium.webdriver.support import expected_conditions as EC
#from selenium.common.exceptions import TimeoutException
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
import time
import signal
import os, sys
import frappe
from ast import literal_eval
class TestDriver(object):
def __init__(self, port=None):
self.port = port or frappe.get_site_config().webserver_port or '8000'
chrome_options = Options()
capabilities = DesiredCapabilities.CHROME
if os.environ.get('CI'):
self.host = 'localhost'
else:
self.host = frappe.local.site
# enable browser logging
capabilities['loggingPrefs'] = {'browser':'ALL'}
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--start-maximized')
self.driver = webdriver.Chrome(chrome_options=chrome_options,
desired_capabilities=capabilities, port=9515)
# self.driver.set_window_size(1080,800)
self.cur_route = None
self.logged_in = False
@property
def localhost(self):
return "http://{host}:{port}".format(host=self.host, port=self.port)
def get(self, url):
return self.driver.get(os.path.join(self.localhost, url))
def start(self):
def signal_handler(signal, frame):
self.close()
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
def refresh(self):
self.driver.refresh()
def close(self):
if self.driver:
self.driver.quit()
self.driver = None
def login(self, wait_for_id="#page-desktop", animate=0, scroll_offset=0):
if self.logged_in:
return
self.get('login')
self.wait_for("#login_email")
self.set_input("#login_email", "Administrator")
self.set_input("#login_password", "admin")
self.click('.btn-login', animate=animate, offset=scroll_offset)
self.wait_for(wait_for_id)
self.logged_in = True
def set_input(self, selector, text, key=None, xpath=None):
elem = self.find(selector, xpath=xpath)[0]
elem.clear()
elem.send_keys(text)
if key:
time.sleep(0.5)
elem.send_keys(key)
time.sleep(0.2)
def set_field(self, fieldname, text):
elem = self.wait_for(xpath='//input[@data-fieldname="{0}"]'.format(fieldname))
time.sleep(0.2)
elem.send_keys(text)
def set_select(self, fieldname, text):
elem = self.wait_for(xpath='//select[@data-fieldname="{0}"]'.format(fieldname))
time.sleep(0.2)
elem.send_keys(text)
def set_multicheck(self, fieldname, values):
for value in values:
path = '//div[@data-fieldname="{0}"]//span[@data-unit="{1}"]'.format(fieldname, value)
elem = self.wait_for(xpath=path)
time.sleep(0.2)
elem.click()
def set_text_editor(self, fieldname, text):
elem = self.wait_for(xpath='//div[@data-fieldname="{0}"]//div[@contenteditable="true"]'.format(fieldname))
time.sleep(0.2)
elem.send_keys(text)
def find(self, selector=None, everywhere=False, xpath=None):
if xpath:
return self.driver.find_elements_by_xpath(xpath)
else:
if self.cur_route and not everywhere:
selector = self.cur_route + " " + selector
return self.driver.find_elements_by_css_selector(selector)
def wait_for(self, selector=None, everywhere=False, timeout=20, xpath=None, for_invisible=False):
if self.cur_route and not everywhere:
selector = self.cur_route + " " + selector
time.sleep(0.5)
if selector:
_by = By.CSS_SELECTOR
if xpath:
_by = By.XPATH
selector = xpath
try:
if not for_invisible:
elem = self.get_wait(timeout).until(
EC.presence_of_element_located((_by, selector)))
else:
elem = self.get_wait(timeout).until(
EC.invisibility_of_element_located((_by, selector)))
return elem
except Exception as e:
# body = self.driver.find_element_by_id('body_div')
# print(body.get_attribute('innerHTML'))
self.print_console()
raise e
def wait_for_invisible(self, selector=None, everywhere=False, timeout=20, xpath=None):
self.wait_for(selector, everywhere, timeout, xpath, True)
def get_console(self):
out = []
for entry in self.driver.get_log('browser'):
source, line_no, message = entry.get('message').split(' ', 2)
if message and message[0] in ('"', "'"):
# message is a quoted/escaped string
message = literal_eval(message)
out.append(source + ' ' + line_no)
out.append(message)
out.append('-'*40)
return out
def print_console(self):
for line in self.get_console():
print(line)
def get_wait(self, timeout=20):
return WebDriverWait(self.driver, timeout)
def scroll_to(self, selector, animate=0, offset=0):
self.execute_script("frappe.ui.scroll('{0}', {1}, {2})".format(selector, animate, offset))
def set_route(self, *args):
self.execute_script('frappe.set_route({0})'\
.format(', '.join(['"{0}"'.format(r) for r in args])))
self.wait_for(xpath='//div[@data-page-route="{0}"]'.format('/'.join(args)), timeout=4)
def click(self, css_selector, xpath=None, timeout=20, animate=0, offset=0):
element = self.wait_till_clickable(css_selector, xpath, timeout)
self.scroll_to(css_selector, animate, offset)
time.sleep(0.5)
element.click()
return element
def click_primary_action(self):
selector = ".page-actions .primary-action"
#self.scroll_to(selector)
self.wait_till_clickable(selector).click()
self.wait_for_ajax()
def click_secondary_action(self):
selector = ".page-actions .btn-secondary"
#self.scroll_to(selector)
self.wait_till_clickable(selector).click()
self.wait_for_ajax()
def click_modal_primary_action(self):
self.get_visible_modal().find_element_by_css_selector('.btn-primary').click()
def get_visible_modal(self):
return self.get_visible_element('.modal-content')
def get_visible_element(self, selector=None, xpath=None):
for elem in self.find(selector=selector, xpath=xpath):
if elem.is_displayed():
return elem
def wait_till_clickable(self, selector=None, xpath=None, timeout=20):
if self.cur_route:
selector = self.cur_route + " " + selector
by = By.CSS_SELECTOR
if xpath:
by = By.XPATH
selector = xpath
return self.get_wait(timeout).until(EC.element_to_be_clickable(
(by, selector)))
def execute_script(self, js):
self.driver.execute_script(js)
def wait_for_ajax(self, freeze = False):
self.wait_for('body[data-ajax-state="complete"]', True)
if freeze:
self.wait_for_invisible(".freeze-message-container")
# def go_to_module(module_name, item=None):
# global cur_route
#
# # desktop
# find(".navbar-home", True)[0].click()
# cur_route = None
# wait("#page-desktop")
#
# page = "Module/" + module_name
# 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}"] .app-icon'.format(page))
# if not m:
# raise Exception("Module {0} not found".format(module_name))
#
# m[0].click()
# wait_for_page(page)
#
# if item:
# elem = find('[data-label="{0}"]'.format(item))[0]
# elem.click()
# page = elem.get_attribute("data-route")
# wait_for_page(page)
#
# def new_doc(module, doctype):
# go_to_module(module, doctype)
# primary_action()
# wait_for_page("Form/" + doctype)
#
# def add_child(fieldname):
# find('[data-fieldname="{0}"] .grid-add-row'.format(fieldname))[0].click()
# wait('[data-fieldname="{0}"] .form-grid'.format(fieldname))
#
# def done_add_child(fieldname):
# selector = '[data-fieldname="{0}"] .grid-row-open .btn-success'.format(fieldname)
# scroll_to(selector)
# wait_till_clickable(selector).click()
#
# def set_field(fieldname, value, fieldtype="input"):
# _driver.switch_to.window(_driver.current_window_handle)
# selector = '{0}[data-fieldname="{1}"]'.format(fieldtype, fieldname)
# set_input(selector, value, key=Keys.TAB)
# wait_for_ajax()
#
# def set_select(fieldname, value):
# select = Select(find('select[data-fieldname="{0}"]'.format(fieldname))[0])
# select.select_by_value(value)
# wait_for_ajax()
#
#
# 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_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_state(state):
# return wait(cur_route + '[data-state="{0}"]'.format(state), True)
#
#

View file

@ -14,7 +14,6 @@ semantic_version
rauth>=0.6.2
requests
redis==2.10.6
selenium
babel==2.6.0
ipython
html2text==2016.9.19