Bläddra i källkod

test: Add UI test for Link control (#7809)

* 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 import
version-14
Faris Ansari 6 år sedan
committed by Suraj Shetty
förälder
incheckning
8fb2a538ec
8 ändrade filer med 186 tillägg och 59 borttagningar
  1. +75
    -0
      cypress/integration/control_link.js
  2. +17
    -12
      cypress/integration/control_rating.js
  3. +1
    -1
      cypress/integration/list_view.js
  4. +1
    -1
      cypress/integration/relative_filters.js
  5. +26
    -9
      cypress/support/commands.js
  6. +1
    -1
      frappe/public/js/frappe/form/controls/link.js
  7. +1
    -35
      frappe/tests/test_utils.py
  8. +64
    -0
      frappe/tests/ui_test_helpers.py

+ 75
- 0
cypress/integration/control_link.js Visa fil

@@ -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]}`);
});
});
});

+ 17
- 12
cypress/integration/control_rating.js Visa fil

@@ -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()


+ 1
- 1
cypress/integration/list_view.js Visa fil

@@ -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();
});


+ 1
- 1
cypress/integration/relative_filters.js Visa fil

@@ -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', () => {


+ 26
- 9
cypress/support/commands.js Visa fil

@@ -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;
});


+ 1
- 1
frappe/public/js/frappe/form/controls/link.js Visa fil

@@ -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) {


+ 1
- 35
frappe/tests/test_utils.py Visa fil

@@ -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()

+ 64
- 0
frappe/tests/ui_test_helpers.py Visa fil

@@ -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()

Laddar…
Avbryt
Spara