* test: Add UI test for Link control - Add API cy.call - Add API cy.create_records - Add ui_test_helpers.py * style: Missing semicolon * style: Missing semicolon * style: Missing semicolon * style: Remove unused imports * test: Robust test for setting invalid value * style: Remove unused importversion-14
@@ -0,0 +1,75 @@ | |||
context('Control Link', () => { | |||
beforeEach(() => { | |||
cy.login('Administrator', 'qwe'); | |||
cy.visit('/desk'); | |||
cy.create_records({ | |||
doctype: 'ToDo', | |||
description: 'this is a test todo for link' | |||
}).as('todos'); | |||
}); | |||
function get_dialog_with_link() { | |||
return cy.dialog({ | |||
title: 'Link', | |||
fields: [ | |||
{ | |||
'label': 'Select ToDo', | |||
'fieldname': 'link', | |||
'fieldtype': 'Link', | |||
'options': 'ToDo' | |||
} | |||
] | |||
}); | |||
} | |||
it('should set the valid value', () => { | |||
get_dialog_with_link().as('dialog'); | |||
cy.server(); | |||
cy.route('POST', '/api/method/frappe.desk.search.search_link').as('search_link'); | |||
cy.get('.frappe-control[data-fieldname=link] input') | |||
.focus() | |||
.type('todo for li') | |||
.type('n', { delay: 600 }) | |||
.type('k', { delay: 700 }); | |||
cy.wait('@search_link'); | |||
cy.get('.frappe-control[data-fieldname=link] ul').should('be.visible'); | |||
cy.get('.frappe-control[data-fieldname=link] input').type('{downarrow}{enter}', { delay: 100 }); | |||
cy.get('.frappe-control[data-fieldname=link] input').blur(); | |||
cy.get('@dialog').then(dialog => { | |||
cy.get('@todos').then(todos => { | |||
let value = dialog.get_value('link'); | |||
expect(value).to.eq(todos[0]); | |||
}); | |||
}); | |||
}); | |||
it.only('should unset invalid value', () => { | |||
get_dialog_with_link().as('dialog'); | |||
cy.server(); | |||
cy.route('GET', '/api/method/frappe.desk.form.utils.validate_link*').as('validate_link'); | |||
cy.get('.frappe-control[data-fieldname=link] input') | |||
.type('invalid value', { delay: 100 }) | |||
.blur(); | |||
cy.wait('@validate_link'); | |||
cy.get('.frappe-control[data-fieldname=link] input').should('have.value', ''); | |||
}); | |||
it('should route to form on arrow click', () => { | |||
get_dialog_with_link().as('dialog'); | |||
cy.server(); | |||
cy.route('GET', '/api/method/frappe.desk.form.utils.validate_link*').as('validate_link'); | |||
cy.get('@todos').then(todos => { | |||
cy.get('.frappe-control[data-fieldname=link] input').type(todos[0]).blur(); | |||
cy.wait('@validate_link'); | |||
cy.get('.frappe-control[data-fieldname=link] input').focus(); | |||
cy.get('.frappe-control[data-fieldname=link] .link-btn').click(); | |||
cy.location('hash').should('eq', `#Form/ToDo/${todos[0]}`); | |||
}); | |||
}); | |||
}); |
@@ -1,14 +1,21 @@ | |||
context('Rating Control', () => { | |||
beforeEach(() => { | |||
context('Control Rating', () => { | |||
before(() => { | |||
cy.login('Administrator', 'qwe'); | |||
cy.visit('/desk'); | |||
}); | |||
function get_dialog_with_rating() { | |||
return cy.dialog({ | |||
title: 'Rating', | |||
fields: [{ | |||
'fieldname': 'rate', | |||
'fieldtype': 'Rating', | |||
}] | |||
}); | |||
} | |||
it('click on the star rating to record value', () => { | |||
cy.visit('/desk'); | |||
cy.dialog('Rating', [{ | |||
'fieldname': 'rate', | |||
'fieldtype': 'Rating', | |||
}]).as('dialog'); | |||
get_dialog_with_rating().as('dialog'); | |||
cy.get('div.rating') | |||
.children('i.fa') | |||
@@ -18,15 +25,13 @@ context('Rating Control', () => { | |||
cy.get('@dialog').then(dialog => { | |||
var value = dialog.get_value('rate'); | |||
expect(value).to.equal(1); | |||
dialog.hide(); | |||
}); | |||
}); | |||
it('hover on the star', () => { | |||
cy.visit('/desk'); | |||
cy.dialog('Rating', [{ | |||
'fieldname': 'rate', | |||
'fieldtype': 'Rating', | |||
}]); | |||
get_dialog_with_rating(); | |||
cy.get('div.rating') | |||
.children('i.fa') | |||
.first() | |||
@@ -3,7 +3,7 @@ context('List View', () => { | |||
cy.login('Administrator', 'qwe'); | |||
cy.visit('/desk'); | |||
cy.window().its('frappe').then(frappe => { | |||
frappe.call("frappe.tests.test_utils.setup_workflow"); | |||
frappe.call("frappe.tests.ui_test_helpers.setup_workflow"); | |||
}); | |||
cy.clear_cache(); | |||
}); | |||
@@ -7,7 +7,7 @@ context('Relative Timeframe', () => { | |||
cy.login('Administrator', 'qwe'); | |||
cy.visit('/desk'); | |||
cy.window().its('frappe').then(frappe => { | |||
frappe.call("frappe.tests.test_utils.create_todo_records"); | |||
frappe.call("frappe.tests.ui_test_helpers.create_todo_records"); | |||
}); | |||
}); | |||
it('set relative filter for Previous and check list', () => { | |||
@@ -35,6 +35,29 @@ Cypress.Commands.add('login', (email, password) => { | |||
}); | |||
}); | |||
Cypress.Commands.add('call', (method, args) => { | |||
return cy.window().its('frappe.csrf_token').then(csrf_token => { | |||
return cy.request({ | |||
url: `/api/method/${method}`, | |||
method: 'POST', | |||
body: args, | |||
headers: { | |||
'Accept': 'application/json', | |||
'Content-Type': 'application/json', | |||
'X-Frappe-CSRF-Token': csrf_token | |||
} | |||
}).then(res => { | |||
expect(res.status).eq(200); | |||
return res.body; | |||
}); | |||
}); | |||
}); | |||
Cypress.Commands.add('create_records', (doc) => { | |||
return cy.call('frappe.tests.ui_test_helpers.create_if_not_exists', { doc }) | |||
.then(r => r.message); | |||
}); | |||
Cypress.Commands.add('fill_field', (fieldname, value, fieldtype='Data') => { | |||
let selector = `.form-control[data-fieldname="${fieldname}"]`; | |||
@@ -72,15 +95,9 @@ Cypress.Commands.add('clear_cache', () => { | |||
}); | |||
}); | |||
Cypress.Commands.add('dialog', (title, fields) => { | |||
cy.window().then(win => { | |||
var d = new win.frappe.ui.Dialog({ | |||
title: title, | |||
fields: fields, | |||
primary_action: function(){ | |||
d.hide(); | |||
} | |||
}); | |||
Cypress.Commands.add('dialog', (opts) => { | |||
return cy.window().then(win => { | |||
var d = new win.frappe.ui.Dialog(opts); | |||
d.show(); | |||
return d; | |||
}); | |||
@@ -234,7 +234,7 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({ | |||
me.awesomplete.list = me.$input.cache[doctype][term]; | |||
} | |||
}); | |||
}, 618)); | |||
}, 500)); | |||
this.$input.on("blur", function() { | |||
if(me.selected) { | |||
@@ -3,10 +3,9 @@ | |||
from __future__ import unicode_literals | |||
import unittest | |||
import frappe | |||
from frappe.utils import evaluate_filters, money_in_words, scrub_urls, get_url | |||
from frappe.utils import ceil, floor, now, add_to_date | |||
from frappe.utils import ceil, floor | |||
class TestFilters(unittest.TestCase): | |||
def test_simple_dict(self): | |||
@@ -123,36 +122,3 @@ class TestHTMLUtils(unittest.TestCase): | |||
clean = clean_email_html(sample) | |||
self.assertTrue('<h1>Hello</h1>' in clean) | |||
self.assertTrue('<a href="http://test.com">text</a>' in clean) | |||
@frappe.whitelist() | |||
def create_todo_records(): | |||
if frappe.db.get_all('ToDo', {'description': 'this is first todo'}): | |||
return | |||
frappe.get_doc({ | |||
"doctype": "ToDo", | |||
"date": add_to_date(now(), days=3), | |||
"description": "this is first todo" | |||
}).insert() | |||
frappe.get_doc({ | |||
"doctype": "ToDo", | |||
"date": add_to_date(now(), days=-3), | |||
"description": "this is second todo" | |||
}).insert() | |||
frappe.get_doc({ | |||
"doctype": "ToDo", | |||
"date": add_to_date(now(), months=2), | |||
"description": "this is third todo" | |||
}).insert() | |||
frappe.get_doc({ | |||
"doctype": "ToDo", | |||
"date": add_to_date(now(), months=-2), | |||
"description": "this is fourth todo" | |||
}).insert() | |||
@frappe.whitelist() | |||
def setup_workflow(): | |||
from frappe.workflow.doctype.workflow.test_workflow import create_todo_workflow | |||
create_todo_workflow() | |||
create_todo_records() | |||
frappe.clear_cache() |
@@ -0,0 +1,64 @@ | |||
import frappe | |||
from frappe.utils import add_to_date, now | |||
@frappe.whitelist() | |||
def create_if_not_exists(doc): | |||
'''Create records if they dont exist. | |||
Will check for uniqueness by checking if a record exists with these field value pairs | |||
:param doc: dict of field value pairs. can be a list of dict for multiple records. | |||
''' | |||
doc = frappe.parse_json(doc) | |||
if not isinstance(doc, list): | |||
docs = [doc] | |||
else: | |||
docs = doc | |||
names = [] | |||
for doc in docs: | |||
filters = doc.copy() | |||
filters.pop('doctype') | |||
name = frappe.db.exists(doc.doctype, filters) | |||
if not name: | |||
d = frappe.get_doc(doc) | |||
d.insert(ignore_permissions=True) | |||
name = d.name | |||
names.append(name) | |||
return names | |||
@frappe.whitelist() | |||
def create_todo_records(): | |||
if frappe.db.get_all('ToDo', {'description': 'this is first todo'}): | |||
return | |||
frappe.get_doc({ | |||
"doctype": "ToDo", | |||
"date": add_to_date(now(), days=3), | |||
"description": "this is first todo" | |||
}).insert() | |||
frappe.get_doc({ | |||
"doctype": "ToDo", | |||
"date": add_to_date(now(), days=-3), | |||
"description": "this is second todo" | |||
}).insert() | |||
frappe.get_doc({ | |||
"doctype": "ToDo", | |||
"date": add_to_date(now(), months=2), | |||
"description": "this is third todo" | |||
}).insert() | |||
frappe.get_doc({ | |||
"doctype": "ToDo", | |||
"date": add_to_date(now(), months=-2), | |||
"description": "this is fourth todo" | |||
}).insert() | |||
@frappe.whitelist() | |||
def setup_workflow(): | |||
from frappe.workflow.doctype.workflow.test_workflow import create_todo_workflow | |||
create_todo_workflow() | |||
create_todo_records() | |||
frappe.clear_cache() |