style: format JS files with prettier

This commit is contained in:
Ankush Menat 2022-08-04 14:51:01 +05:30
parent 015937a03a
commit 40f27f908a
560 changed files with 26258 additions and 23373 deletions

View File

@ -1,24 +1,24 @@
module.exports = {
parserPreset: 'conventional-changelog-conventionalcommits',
parserPreset: "conventional-changelog-conventionalcommits",
rules: {
'subject-empty': [2, 'never'],
'type-case': [2, 'always', 'lower-case'],
'type-empty': [2, 'never'],
'type-enum': [
"subject-empty": [2, "never"],
"type-case": [2, "always", "lower-case"],
"type-empty": [2, "never"],
"type-enum": [
2,
'always',
"always",
[
'build',
'chore',
'ci',
'docs',
'feat',
'fix',
'perf',
'refactor',
'revert',
'style',
'test',
"build",
"chore",
"ci",
"docs",
"feat",
"fix",
"perf",
"refactor",
"revert",
"style",
"test",
],
],
},

View File

@ -13,8 +13,8 @@ export default {
fieldtype: "Data",
in_list_view: 1,
label: "Title",
unique: 1
}
unique: 1,
},
],
links: [],
istable: 1,
@ -24,7 +24,7 @@ export default {
naming_rule: "By fieldname",
owner: "Administrator",
permissions: [],
sort_field: 'modified',
sort_order: 'ASC',
track_changes: 1
};
sort_field: "modified",
sort_order: "ASC",
track_changes: 1,
};

View File

@ -12,38 +12,38 @@ export default {
fieldname: "data",
fieldtype: "Data",
in_list_view: 1,
label: "Data"
label: "Data",
},
{
fieldname: "barcode",
fieldtype: "Barcode",
in_list_view: 1,
label: "Barcode"
label: "Barcode",
},
{
fieldname: "check",
fieldtype: "Check",
in_list_view: 1,
label: "Check"
label: "Check",
},
{
fieldname: "rating",
fieldtype: "Rating",
in_list_view: 1,
label: "Rating"
label: "Rating",
},
{
fieldname: "duration",
fieldtype: "Duration",
in_list_view: 1,
label: "Duration"
label: "Duration",
},
{
fieldname: "date",
fieldtype: "Date",
in_list_view: 1,
label: "Date"
}
label: "Date",
},
],
links: [],
istable: 1,
@ -53,7 +53,7 @@ export default {
naming_rule: "By fieldname",
owner: "Administrator",
permissions: [],
sort_field: 'modified',
sort_order: 'ASC',
track_changes: 1
};
sort_field: "modified",
sort_order: "ASC",
track_changes: 1,
};

View File

@ -1,37 +1,37 @@
export default {
name: 'Custom Submittable DocType',
name: "Custom Submittable DocType",
custom: 1,
actions: [],
is_submittable: 1,
creation: '2019-12-10 06:29:07.215072',
doctype: 'DocType',
creation: "2019-12-10 06:29:07.215072",
doctype: "DocType",
editable_grid: 1,
engine: 'InnoDB',
engine: "InnoDB",
fields: [
{
fieldname: 'enabled',
fieldtype: 'Check',
label: 'Enabled',
fieldname: "enabled",
fieldtype: "Check",
label: "Enabled",
allow_on_submit: 1,
reqd: 1
reqd: 1,
},
{
fieldname: 'title',
fieldtype: 'Data',
label: 'title',
reqd: 1
fieldname: "title",
fieldtype: "Data",
label: "title",
reqd: 1,
},
{
fieldname: 'description',
fieldtype: 'Text Editor',
label: 'Description'
}
fieldname: "description",
fieldtype: "Text Editor",
label: "Description",
},
],
links: [],
modified: '2019-12-10 14:40:53.127615',
modified_by: 'Administrator',
module: 'Custom',
owner: 'Administrator',
modified: "2019-12-10 14:40:53.127615",
modified_by: "Administrator",
module: "Custom",
owner: "Administrator",
permissions: [
{
create: 1,
@ -39,15 +39,15 @@ export default {
email: 1,
print: 1,
read: 1,
role: 'System Manager',
role: "System Manager",
share: 1,
write: 1,
submit: 1,
cancel: 1
}
cancel: 1,
},
],
quick_entry: 1,
sort_field: 'modified',
sort_order: 'ASC',
track_changes: 1
};
sort_field: "modified",
sort_order: "ASC",
track_changes: 1,
};

View File

@ -1,51 +1,51 @@
export default {
name: 'Validation Test',
name: "Validation Test",
custom: 1,
actions: [],
creation: '2019-03-15 06:29:07.215072',
doctype: 'DocType',
creation: "2019-03-15 06:29:07.215072",
doctype: "DocType",
editable_grid: 1,
engine: 'InnoDB',
engine: "InnoDB",
fields: [
{
fieldname: 'email',
fieldtype: 'Data',
label: 'Email',
options: 'Email'
fieldname: "email",
fieldtype: "Data",
label: "Email",
options: "Email",
},
{
fieldname: 'URL',
fieldtype: 'Data',
label: 'URL',
options: 'URL'
fieldname: "URL",
fieldtype: "Data",
label: "URL",
options: "URL",
},
{
fieldname: 'Phone',
fieldtype: 'Data',
label: 'Phone',
options: 'Phone'
fieldname: "Phone",
fieldtype: "Data",
label: "Phone",
options: "Phone",
},
{
fieldname: 'person_name',
fieldtype: 'Data',
label: 'Person Name',
options: 'Name'
fieldname: "person_name",
fieldtype: "Data",
label: "Person Name",
options: "Name",
},
{
fieldname: 'read_only_url',
fieldtype: 'Data',
label: 'Read Only URL',
options: 'URL',
read_only: '1',
default: 'https://frappe.io'
}
fieldname: "read_only_url",
fieldtype: "Data",
label: "Read Only URL",
options: "URL",
read_only: "1",
default: "https://frappe.io",
},
],
issingle: 1,
links: [],
modified: '2021-04-19 14:40:53.127615',
modified_by: 'Administrator',
module: 'Custom',
owner: 'Administrator',
modified: "2021-04-19 14:40:53.127615",
modified_by: "Administrator",
module: "Custom",
owner: "Administrator",
permissions: [
{
create: 1,
@ -53,13 +53,13 @@ export default {
email: 1,
print: 1,
read: 1,
role: 'System Manager',
role: "System Manager",
share: 1,
write: 1
}
write: 1,
},
],
quick_entry: 1,
sort_field: 'modified',
sort_order: 'ASC',
track_changes: 1
sort_field: "modified",
sort_order: "ASC",
track_changes: 1,
};

View File

@ -1,34 +1,34 @@
export default {
name: 'DateTime Test',
name: "DateTime Test",
custom: 1,
actions: [],
creation: '2019-03-15 06:29:07.215072',
doctype: 'DocType',
creation: "2019-03-15 06:29:07.215072",
doctype: "DocType",
editable_grid: 1,
engine: 'InnoDB',
engine: "InnoDB",
fields: [
{
fieldname: 'date',
fieldtype: 'Date',
label: 'Date'
fieldname: "date",
fieldtype: "Date",
label: "Date",
},
{
fieldname: 'time',
fieldtype: 'Time',
label: 'Time'
fieldname: "time",
fieldtype: "Time",
label: "Time",
},
{
fieldname: 'datetime',
fieldtype: 'Datetime',
label: 'Datetime'
}
fieldname: "datetime",
fieldtype: "Datetime",
label: "Datetime",
},
],
issingle: 1,
links: [],
modified: '2019-12-09 14:40:53.127615',
modified_by: 'Administrator',
module: 'Custom',
owner: 'Administrator',
modified: "2019-12-09 14:40:53.127615",
modified_by: "Administrator",
module: "Custom",
owner: "Administrator",
permissions: [
{
create: 1,
@ -36,13 +36,13 @@ export default {
email: 1,
print: 1,
read: 1,
role: 'System Manager',
role: "System Manager",
share: 1,
write: 1
}
write: 1,
},
],
quick_entry: 1,
sort_field: 'modified',
sort_order: 'ASC',
track_changes: 1
sort_field: "modified",
sort_order: "ASC",
track_changes: 1,
};

View File

@ -10,18 +10,18 @@ export default {
engine: "InnoDB",
fields: [
{
"fieldname": "title",
"fieldtype": "Data",
"label": "Title",
"unique": 1
}
fieldname: "title",
fieldtype: "Data",
label: "Title",
unique: 1,
},
],
links: [
{
"group": "Child Doctype",
"link_doctype": "Doctype With Child Table",
"link_fieldname": "title"
}
group: "Child Doctype",
link_doctype: "Doctype With Child Table",
link_fieldname: "title",
},
],
modified: "2022-02-10 12:03:12.603763",
modified_by: "Administrator",
@ -34,12 +34,12 @@ export default {
email: 1,
print: 1,
read: 1,
role: 'System Manager',
role: "System Manager",
share: 1,
write: 1
}
write: 1,
},
],
sort_field: 'modified',
sort_order: 'ASC',
track_changes: 1
};
sort_field: "modified",
sort_order: "ASC",
track_changes: 1,
};

View File

@ -12,21 +12,21 @@ export default {
fieldname: "title",
fieldtype: "Data",
label: "Title",
unique: 1
unique: 1,
},
{
fieldname: "child_table",
fieldtype: "Table",
label: "Child Table",
options: "Child Table Doctype",
reqd: 1
reqd: 1,
},
{
fieldname: "child_table_1",
fieldtype: "Table",
label: "Child Table 1",
options: "Child Table Doctype 1"
}
options: "Child Table Doctype 1",
},
],
links: [],
modified: "2022-02-10 12:03:12.603763",
@ -41,12 +41,12 @@ export default {
email: 1,
print: 1,
read: 1,
role: 'System Manager',
role: "System Manager",
share: 1,
write: 1
}
write: 1,
},
],
sort_field: 'modified',
sort_order: 'ASC',
track_changes: 1
sort_field: "modified",
sort_order: "ASC",
track_changes: 1,
};

View File

@ -4,29 +4,28 @@ export default {
custom: 1,
is_submittable: 1,
autoname: "field:title",
creation: '2022-03-30 06:29:07.215072',
doctype: 'DocType',
engine: 'InnoDB',
creation: "2022-03-30 06:29:07.215072",
doctype: "DocType",
engine: "InnoDB",
fields: [
{
fieldname: 'title',
fieldtype: 'Data',
label: 'title',
fieldname: "title",
fieldtype: "Data",
label: "title",
unique: 1,
},
{
fieldname: 'phone',
fieldtype: 'Phone',
label: 'Phone'
}
fieldname: "phone",
fieldtype: "Phone",
label: "Phone",
},
],
links: [],
modified: '2019-03-30 14:40:53.127615',
modified_by: 'Administrator',
modified: "2019-03-30 14:40:53.127615",
modified_by: "Administrator",
naming_rule: "By fieldname",
module: 'Custom',
owner: 'Administrator',
module: "Custom",
owner: "Administrator",
permissions: [
{
create: 1,
@ -34,14 +33,14 @@ export default {
email: 1,
print: 1,
read: 1,
role: 'System Manager',
role: "System Manager",
share: 1,
write: 1,
submit: 1,
cancel: 1
}
cancel: 1,
},
],
sort_field: 'modified',
sort_order: 'ASC',
track_changes: 1
sort_field: "modified",
sort_order: "ASC",
track_changes: 1,
};

View File

@ -1,39 +1,39 @@
export default {
name: 'Form With Tab Break',
name: "Form With Tab Break",
custom: 1,
actions: [],
doctype: 'DocType',
engine: 'InnoDB',
doctype: "DocType",
engine: "InnoDB",
fields: [
{
fieldname: 'username',
fieldtype: 'Data',
label: 'Name',
options: 'Name'
fieldname: "username",
fieldtype: "Data",
label: "Name",
options: "Name",
},
{
fieldname: 'tab',
fieldtype: 'Tab Break',
label: 'Tab 2',
fieldname: "tab",
fieldtype: "Tab Break",
label: "Tab 2",
},
{
fieldname: 'Phone',
fieldtype: 'Data',
label: 'Phone',
options: 'Phone',
reqd: 1
fieldname: "Phone",
fieldtype: "Data",
label: "Phone",
options: "Phone",
reqd: 1,
},
],
links: [
{
"group": "Profile",
"link_doctype": "Contact",
"link_fieldname": "user"
group: "Profile",
link_doctype: "Contact",
link_fieldname: "user",
},
],
modified_by: 'Administrator',
module: 'Custom',
owner: 'Administrator',
modified_by: "Administrator",
module: "Custom",
owner: "Administrator",
permissions: [
{
create: 1,
@ -41,14 +41,14 @@ export default {
email: 1,
print: 1,
read: 1,
role: 'System Manager',
role: "System Manager",
share: 1,
write: 1
}
write: 1,
},
],
quick_entry: 1,
autoname: "format: Test-{####}",
sort_field: 'modified',
sort_order: 'ASC',
track_changes: 1
sort_field: "modified",
sort_order: "ASC",
track_changes: 1,
};

View File

@ -1,42 +1,43 @@
context('API Resources', () => {
context("API Resources", () => {
before(() => {
cy.visit('/login');
cy.visit("/login");
cy.login();
cy.visit('/app/website');
cy.visit("/app/website");
});
it('Creates two Comments', () => {
cy.insert_doc('Comment', { comment_type: 'Comment', content: "hello" });
cy.insert_doc('Comment', { comment_type: 'Comment', content: "world" });
it("Creates two Comments", () => {
cy.insert_doc("Comment", { comment_type: "Comment", content: "hello" });
cy.insert_doc("Comment", { comment_type: "Comment", content: "world" });
});
it('Lists the Comments', () => {
cy.get_list('Comment')
.its('data')
.then(data => expect(data.length).to.be.at.least(2));
it("Lists the Comments", () => {
cy.get_list("Comment")
.its("data")
.then((data) => expect(data.length).to.be.at.least(2));
cy.get_list('Comment', ['name', 'content'], [['content', '=', 'hello']])
.then(body => {
expect(body).to.have.property('data');
expect(body.data).to.have.lengthOf(1);
expect(body.data[0]).to.have.property('content');
expect(body.data[0]).to.have.property('name');
});
cy.get_list("Comment", ["name", "content"], [["content", "=", "hello"]]).then((body) => {
expect(body).to.have.property("data");
expect(body.data).to.have.lengthOf(1);
expect(body.data[0]).to.have.property("content");
expect(body.data[0]).to.have.property("name");
});
});
it('Gets each Comment', () => {
cy.get_list('Comment').then(body => body.data.forEach(comment => {
cy.get_doc('Comment', comment.name);
}));
it("Gets each Comment", () => {
cy.get_list("Comment").then((body) =>
body.data.forEach((comment) => {
cy.get_doc("Comment", comment.name);
})
);
});
it('Removes the Comments', () => {
cy.get_list('Comment').then(body => {
it("Removes the Comments", () => {
cy.get_list("Comment").then((body) => {
let comment_names = [];
body.data.map(comment => comment_names.push(comment.name));
body.data.map((comment) => comment_names.push(comment.name));
comment_names = [...new Set(comment_names)]; // remove duplicates
comment_names.forEach((comment_name) => {
cy.remove_doc('Comment', comment_name);
cy.remove_doc("Comment", comment_name);
});
});
});

View File

@ -1,48 +1,57 @@
context('Awesome Bar', () => {
context("Awesome Bar", () => {
before(() => {
cy.visit('/login');
cy.visit("/login");
cy.login();
cy.visit('/app/website');
cy.visit("/app/website");
});
beforeEach(() => {
cy.get('.navbar .navbar-home').click();
cy.findByPlaceholderText('Search or type a command (Ctrl + G)').clear();
cy.get(".navbar .navbar-home").click();
cy.findByPlaceholderText("Search or type a command (Ctrl + G)").clear();
});
it('navigates to doctype list', () => {
cy.findByPlaceholderText('Search or type a command (Ctrl + G)').type('todo', { delay: 700 });
cy.get('.awesomplete').findByRole('listbox').should('be.visible');
cy.findByPlaceholderText('Search or type a command (Ctrl + G)').type('{enter}', { delay: 700 });
it("navigates to doctype list", () => {
cy.findByPlaceholderText("Search or type a command (Ctrl + G)").type("todo", {
delay: 700,
});
cy.get(".awesomplete").findByRole("listbox").should("be.visible");
cy.findByPlaceholderText("Search or type a command (Ctrl + G)").type("{enter}", {
delay: 700,
});
cy.get('.title-text').should('contain', 'To Do');
cy.get(".title-text").should("contain", "To Do");
cy.location('pathname').should('eq', '/app/todo');
cy.location("pathname").should("eq", "/app/todo");
});
it('find text in doctype list', () => {
cy.findByPlaceholderText('Search or type a command (Ctrl + G)')
.type('test in todo{enter}', { delay: 700 });
it("find text in doctype list", () => {
cy.findByPlaceholderText("Search or type a command (Ctrl + G)").type(
"test in todo{enter}",
{ delay: 700 }
);
cy.get('.title-text').should('contain', 'To Do');
cy.get(".title-text").should("contain", "To Do");
cy.findByPlaceholderText('ID')
.should('have.value', '%test%');
cy.findByPlaceholderText("ID").should("have.value", "%test%");
cy.clear_filters();
});
it('navigates to new form', () => {
cy.findByPlaceholderText('Search or type a command (Ctrl + G)')
.type('new blog post{enter}', { delay: 700 });
it("navigates to new form", () => {
cy.findByPlaceholderText("Search or type a command (Ctrl + G)").type(
"new blog post{enter}",
{ delay: 700 }
);
cy.get('.title-text:visible').should('have.text', 'New Blog Post');
cy.get(".title-text:visible").should("have.text", "New Blog Post");
});
it('calculates math expressions', () => {
cy.findByPlaceholderText('Search or type a command (Ctrl + G)')
.type('55 + 32{downarrow}{enter}', { delay: 700 });
it("calculates math expressions", () => {
cy.findByPlaceholderText("Search or type a command (Ctrl + G)").type(
"55 + 32{downarrow}{enter}",
{ delay: 700 }
);
cy.get('.modal-title').should('contain', 'Result');
cy.get('.msgprint').should('contain', '55 + 32 = 87');
cy.get(".modal-title").should("contain", "Result");
cy.get(".msgprint").should("contain", "55 + 32 = 87");
});
});

View File

@ -1,90 +1,95 @@
context('Attach Control', () => {
context("Attach Control", () => {
before(() => {
cy.login();
cy.visit('/app/doctype');
return cy.window().its('frappe').then(frappe => {
return frappe.xcall('frappe.tests.ui_test_helpers.create_doctype', {
name: 'Test Attach Control',
fields: [
{
"label": "Attach File or Image",
"fieldname": "attach",
"fieldtype": "Attach",
"in_list_view": 1,
},
]
cy.visit("/app/doctype");
return cy
.window()
.its("frappe")
.then((frappe) => {
return frappe.xcall("frappe.tests.ui_test_helpers.create_doctype", {
name: "Test Attach Control",
fields: [
{
label: "Attach File or Image",
fieldname: "attach",
fieldtype: "Attach",
in_list_view: 1,
},
],
});
});
});
});
it('Checking functionality for "Link" button in the "Attach" fieldtype', () => {
//Navigating to the new form for the newly created doctype
cy.new_form('Test Attach Control');
cy.new_form("Test Attach Control");
//Clicking on the attach button which is displayed as part of creating a doctype with "Attach" fieldtype
cy.findByRole('button', {name: 'Attach'}).click();
cy.findByRole("button", { name: "Attach" }).click();
//Clicking on "Link" button to attach a file using the "Link" button
cy.findByRole('button', {name: 'Link'}).click();
cy.findByPlaceholderText('Attach a web link').type('https://wallpaperplay.com/walls/full/8/2/b/72402.jpg');
cy.findByRole("button", { name: "Link" }).click();
cy.findByPlaceholderText("Attach a web link").type(
"https://wallpaperplay.com/walls/full/8/2/b/72402.jpg"
);
//Clicking on the Upload button to upload the file
cy.intercept("POST", "/api/method/upload_file").as("upload_image");
cy.get('.modal-footer').findByRole("button", {name: "Upload"}).click({delay: 500});
cy.get(".modal-footer").findByRole("button", { name: "Upload" }).click({ delay: 500 });
cy.wait("@upload_image");
cy.findByRole('button', {name: 'Save'}).click();
cy.findByRole("button", { name: "Save" }).click();
//Checking if the URL of the attached image is getting displayed in the field of the newly created doctype
cy.get('.attached-file > .ellipsis > .attached-file-link')
.should('have.attr', 'href')
.and('equal', 'https://wallpaperplay.com/walls/full/8/2/b/72402.jpg');
cy.get(".attached-file > .ellipsis > .attached-file-link")
.should("have.attr", "href")
.and("equal", "https://wallpaperplay.com/walls/full/8/2/b/72402.jpg");
//Clicking on the "Clear" button
cy.get('[data-action="clear_attachment"]').click();
//Checking if clicking on the clear button clears the field of the doctype form and again displays the attach button
cy.get('.control-input > .btn-sm').should('contain', 'Attach');
cy.get(".control-input > .btn-sm").should("contain", "Attach");
//Deleting the doc
cy.go_to_list('Test Attach Control');
cy.get('.list-row-checkbox').eq(0).click();
cy.get('.actions-btn-group > .btn').contains('Actions').click();
cy.go_to_list("Test Attach Control");
cy.get(".list-row-checkbox").eq(0).click();
cy.get(".actions-btn-group > .btn").contains("Actions").click();
cy.get('.actions-btn-group > .dropdown-menu [data-label="Delete"]').click();
cy.click_modal_primary_button('Yes');
cy.click_modal_primary_button("Yes");
});
it('Checking functionality for "Library" button in the "Attach" fieldtype', () => {
//Navigating to the new form for the newly created doctype
cy.new_form('Test Attach Control');
cy.new_form("Test Attach Control");
//Clicking on the attach button which is displayed as part of creating a doctype with "Attach" fieldtype
cy.findByRole('button', {name: 'Attach'}).click();
cy.findByRole("button", { name: "Attach" }).click();
//Clicking on "Library" button to attach a file using the "Library" button
cy.findByRole('button', {name: 'Library'}).click();
cy.contains('72402.jpg').click();
cy.findByRole("button", { name: "Library" }).click();
cy.contains("72402.jpg").click();
//Clicking on the Upload button to upload the file
cy.intercept("POST", "/api/method/upload_file").as("upload_image");
cy.get('.modal-footer').findByRole("button", {name: "Upload"}).click({delay: 500});
cy.get(".modal-footer").findByRole("button", { name: "Upload" }).click({ delay: 500 });
cy.wait("@upload_image");
cy.findByRole('button', {name: 'Save'}).click();
cy.findByRole("button", { name: "Save" }).click();
//Checking if the URL of the attached image is getting displayed in the field of the newly created doctype
cy.get('.attached-file > .ellipsis > .attached-file-link')
.should('have.attr', 'href')
.and('equal', 'https://wallpaperplay.com/walls/full/8/2/b/72402.jpg');
cy.get(".attached-file > .ellipsis > .attached-file-link")
.should("have.attr", "href")
.and("equal", "https://wallpaperplay.com/walls/full/8/2/b/72402.jpg");
//Clicking on the "Clear" button
cy.get('[data-action="clear_attachment"]').click();
//Checking if clicking on the clear button clears the field of the doctype form and again displays the attach button
cy.get('.control-input > .btn-sm').should('contain', 'Attach');
cy.get(".control-input > .btn-sm").should("contain", "Attach");
//Deleting the doc
cy.go_to_list('Test Attach Control');
cy.get('.list-row-checkbox').eq(0).click();
cy.get('.actions-btn-group > .btn').contains('Actions').click();
cy.go_to_list("Test Attach Control");
cy.get(".list-row-checkbox").eq(0).click();
cy.get(".actions-btn-group > .btn").contains("Actions").click();
cy.get('.actions-btn-group > .dropdown-menu [data-label="Delete"]').click();
cy.click_modal_primary_button('Yes');
cy.click_modal_primary_button("Yes");
});
});
});

View File

@ -1,57 +1,64 @@
context('Control Autocomplete', () => {
context("Control Autocomplete", () => {
before(() => {
cy.login();
cy.visit('/app/website');
cy.visit("/app/website");
});
function get_dialog_with_autocomplete(options) {
cy.visit('/app/website');
cy.visit("/app/website");
return cy.dialog({
title: 'Autocomplete',
title: "Autocomplete",
fields: [
{
'label': 'Select an option',
'fieldname': 'autocomplete',
'fieldtype': 'Autocomplete',
'options': options || ['Option 1', 'Option 2', 'Option 3'],
}
]
label: "Select an option",
fieldname: "autocomplete",
fieldtype: "Autocomplete",
options: options || ["Option 1", "Option 2", "Option 3"],
},
],
});
}
it('should set the valid value', () => {
get_dialog_with_autocomplete().as('dialog');
it("should set the valid value", () => {
get_dialog_with_autocomplete().as("dialog");
cy.get('.frappe-control[data-fieldname=autocomplete] input').focus().as('input');
cy.get(".frappe-control[data-fieldname=autocomplete] input").focus().as("input");
cy.wait(1000);
cy.get('@input').type('2', { delay: 300 });
cy.get('.frappe-control[data-fieldname=autocomplete]').findByRole('listbox').should('be.visible');
cy.get('.frappe-control[data-fieldname=autocomplete] input').type('{enter}', { delay: 300 });
cy.get('.frappe-control[data-fieldname=autocomplete] input').blur();
cy.get('@dialog').then(dialog => {
let value = dialog.get_value('autocomplete');
expect(value).to.eq('Option 2');
cy.get("@input").type("2", { delay: 300 });
cy.get(".frappe-control[data-fieldname=autocomplete]")
.findByRole("listbox")
.should("be.visible");
cy.get(".frappe-control[data-fieldname=autocomplete] input").type("{enter}", {
delay: 300,
});
cy.get(".frappe-control[data-fieldname=autocomplete] input").blur();
cy.get("@dialog").then((dialog) => {
let value = dialog.get_value("autocomplete");
expect(value).to.eq("Option 2");
dialog.clear();
});
});
it('should set the valid value with different label', () => {
it("should set the valid value with different label", () => {
const options_with_label = [
{ label: "Option 1", value: "option_1" },
{ label: "Option 2", value: "option_2" }
{ label: "Option 2", value: "option_2" },
];
get_dialog_with_autocomplete(options_with_label).as('dialog');
get_dialog_with_autocomplete(options_with_label).as("dialog");
cy.get('.frappe-control[data-fieldname=autocomplete] input').focus().as('input');
cy.get('.frappe-control[data-fieldname=autocomplete]').findByRole('listbox').should('be.visible');
cy.get('@input').type('2', { delay: 300 });
cy.get('.frappe-control[data-fieldname=autocomplete] input').type('{enter}', { delay: 300 });
cy.get('.frappe-control[data-fieldname=autocomplete] input').blur();
cy.get('@dialog').then(dialog => {
let value = dialog.get_value('autocomplete');
expect(value).to.eq('option_2');
cy.get(".frappe-control[data-fieldname=autocomplete] input").focus().as("input");
cy.get(".frappe-control[data-fieldname=autocomplete]")
.findByRole("listbox")
.should("be.visible");
cy.get("@input").type("2", { delay: 300 });
cy.get(".frappe-control[data-fieldname=autocomplete] input").type("{enter}", {
delay: 300,
});
cy.get(".frappe-control[data-fieldname=autocomplete] input").blur();
cy.get("@dialog").then((dialog) => {
let value = dialog.get_value("autocomplete");
expect(value).to.eq("option_2");
dialog.clear();
});
});
});

View File

@ -1,55 +1,57 @@
context('Control Barcode', () => {
context("Control Barcode", () => {
beforeEach(() => {
cy.login();
cy.visit('/app/website');
cy.visit("/app/website");
});
function get_dialog_with_barcode() {
return cy.dialog({
title: 'Barcode',
title: "Barcode",
fields: [
{
label: 'Barcode',
fieldname: 'barcode',
fieldtype: 'Barcode'
}
]
label: "Barcode",
fieldname: "barcode",
fieldtype: "Barcode",
},
],
});
}
it('should generate barcode on setting a value', () => {
get_dialog_with_barcode().as('dialog');
it("should generate barcode on setting a value", () => {
get_dialog_with_barcode().as("dialog");
cy.focused().blur();
cy.get('.frappe-control[data-fieldname=barcode]').findByRole('textbox')
.type('123456789')
cy.get(".frappe-control[data-fieldname=barcode]")
.findByRole("textbox")
.type("123456789")
.blur();
cy.get('.frappe-control[data-fieldname=barcode] svg[data-barcode-value="123456789"]')
.should('exist');
cy.get(
'.frappe-control[data-fieldname=barcode] svg[data-barcode-value="123456789"]'
).should("exist");
cy.get('@dialog').then(dialog => {
let value = dialog.get_value('barcode');
expect(value).to.contain('<svg');
cy.get("@dialog").then((dialog) => {
let value = dialog.get_value("barcode");
expect(value).to.contain("<svg");
expect(value).to.contain('data-barcode-value="123456789"');
});
});
it('should reset when input is cleared', () => {
get_dialog_with_barcode().as('dialog');
it("should reset when input is cleared", () => {
get_dialog_with_barcode().as("dialog");
cy.focused().blur();
cy.get('.frappe-control[data-fieldname=barcode]').findByRole('textbox')
.type('123456789')
cy.get(".frappe-control[data-fieldname=barcode]")
.findByRole("textbox")
.type("123456789")
.blur();
cy.get('.frappe-control[data-fieldname=barcode]').findByRole('textbox')
.clear()
.blur();
cy.get('.frappe-control[data-fieldname=barcode] svg[data-barcode-value="123456789"]')
.should('not.exist');
cy.get(".frappe-control[data-fieldname=barcode]").findByRole("textbox").clear().blur();
cy.get(
'.frappe-control[data-fieldname=barcode] svg[data-barcode-value="123456789"]'
).should("not.exist");
cy.get('@dialog').then(dialog => {
let value = dialog.get_value('barcode');
expect(value).to.equal('');
cy.get("@dialog").then((dialog) => {
let value = dialog.get_value("barcode");
expect(value).to.equal("");
});
});
});

View File

@ -1,77 +1,80 @@
context('Control Color', () => {
context("Control Color", () => {
before(() => {
cy.login();
cy.visit('/app/website');
cy.visit("/app/website");
});
function get_dialog_with_color() {
return cy.dialog({
title: 'Color',
fields: [{
label: 'Color',
fieldname: 'color',
fieldtype: 'Color'
}]
title: "Color",
fields: [
{
label: "Color",
fieldname: "color",
fieldtype: "Color",
},
],
});
}
it('Verifying if the color control is selecting correct', () => {
get_dialog_with_color().as('dialog');
cy.findByPlaceholderText('Choose a color').click();
it("Verifying if the color control is selecting correct", () => {
get_dialog_with_color().as("dialog");
cy.findByPlaceholderText("Choose a color").click();
///Selecting a color from the color palette
cy.get('[style="background-color: rgb(79, 157, 217);"]').click();
//Checking if the css attribute is correct
cy.get('.color-map').should('have.css', 'color', 'rgb(79, 157, 217)');
cy.get('.hue-map').should('have.css', 'color', 'rgb(0, 145, 255)');
cy.get(".color-map").should("have.css", "color", "rgb(79, 157, 217)");
cy.get(".hue-map").should("have.css", "color", "rgb(0, 145, 255)");
//Checking if the correct color is being selected
cy.get('@dialog').then(dialog => {
let value = dialog.get_value('color');
expect(value).to.equal('#4F9DD9');
cy.get("@dialog").then((dialog) => {
let value = dialog.get_value("color");
expect(value).to.equal("#4F9DD9");
});
//Selecting a color
cy.get('[style="background-color: rgb(203, 41, 41);"]').click();
//Checking if the correct css is being selected
cy.get('.color-map').should('have.css', 'color', 'rgb(203, 41, 41)');
cy.get('.hue-map').should('have.css', 'color', 'rgb(255, 0, 0)');
cy.get(".color-map").should("have.css", "color", "rgb(203, 41, 41)");
cy.get(".hue-map").should("have.css", "color", "rgb(255, 0, 0)");
//Checking if the correct color is being selected
cy.get('@dialog').then(dialog => {
let value = dialog.get_value('color');
expect(value).to.equal('#CB2929');
cy.get("@dialog").then((dialog) => {
let value = dialog.get_value("color");
expect(value).to.equal("#CB2929");
});
//Selecting color from the palette
cy.get('.color-map > .color-selector').click(65, 87, {force: true});
cy.get('.color-map').should('have.css', 'color', 'rgb(56, 0, 0)');
cy.get(".color-map > .color-selector").click(65, 87, { force: true });
cy.get(".color-map").should("have.css", "color", "rgb(56, 0, 0)");
//Checking if the expected color is selected and getting displayed
cy.get('@dialog').then(dialog => {
let value = dialog.get_value('color');
expect(value).to.equal('#380000');
cy.get("@dialog").then((dialog) => {
let value = dialog.get_value("color");
expect(value).to.equal("#380000");
});
//Selecting the color from the hue map
cy.get('.hue-map > .hue-selector').click(35, -1, {force: true});
cy.get('.color-map').should('have.css', 'color', 'rgb(56, 45, 0)');
cy.get('.hue-map').should('have.css', 'color', 'rgb(255, 204, 0)');
cy.get('.color-map > .color-selector').click(55, 12, {force: true});
cy.get('.color-map').should('have.css', 'color', 'rgb(46, 37, 0)');
cy.get(".hue-map > .hue-selector").click(35, -1, { force: true });
cy.get(".color-map").should("have.css", "color", "rgb(56, 45, 0)");
cy.get(".hue-map").should("have.css", "color", "rgb(255, 204, 0)");
cy.get(".color-map > .color-selector").click(55, 12, { force: true });
cy.get(".color-map").should("have.css", "color", "rgb(46, 37, 0)");
//Checking if the correct color is being displayed
cy.get('@dialog').then(dialog => {
let value = dialog.get_value('color');
expect(value).to.equal('#2e2500');
cy.get("@dialog").then((dialog) => {
let value = dialog.get_value("color");
expect(value).to.equal("#2e2500");
});
//Clearing the field and checking if the field contains the placeholder "Choose a color"
cy.get('.input-with-feedback').click({force: true});
cy.get_field('color', 'Color').type('{selectall}').clear();
cy.get_field('color', 'Color').invoke('attr', 'placeholder').should('contain', 'Choose a color');
cy.get(".input-with-feedback").click({ force: true });
cy.get_field("color", "Color").type("{selectall}").clear();
cy.get_field("color", "Color")
.invoke("attr", "placeholder")
.should("contain", "Choose a color");
});
});
});

View File

@ -1,134 +1,145 @@
context('Data Control', () => {
context("Data Control", () => {
before(() => {
cy.login();
cy.visit('/app/doctype');
return cy.window().its('frappe').then(frappe => {
return frappe.xcall('frappe.tests.ui_test_helpers.create_doctype', {
name: 'Test Data Control',
fields: [
{
"label": "Name",
"fieldname": "name1",
"fieldtype": "Data",
"options": "Name",
"in_list_view": 1,
"reqd": 1,
},
{
"label": "Email-ID",
"fieldname": "email",
"fieldtype": "Data",
"options": "Email",
"in_list_view": 1,
"reqd": 1,
},
{
"label": "Phone No.",
"fieldname": "phone",
"fieldtype": "Data",
"options": "Phone",
"in_list_view": 1,
"reqd": 1,
},
]
cy.visit("/app/doctype");
return cy
.window()
.its("frappe")
.then((frappe) => {
return frappe.xcall("frappe.tests.ui_test_helpers.create_doctype", {
name: "Test Data Control",
fields: [
{
label: "Name",
fieldname: "name1",
fieldtype: "Data",
options: "Name",
in_list_view: 1,
reqd: 1,
},
{
label: "Email-ID",
fieldname: "email",
fieldtype: "Data",
options: "Email",
in_list_view: 1,
reqd: 1,
},
{
label: "Phone No.",
fieldname: "phone",
fieldtype: "Data",
options: "Phone",
in_list_view: 1,
reqd: 1,
},
],
});
});
});
});
it('check custom formatters', () => {
it("check custom formatters", () => {
cy.visit(`/app/doctype/User`);
cy.get('[data-fieldname="fields"] .grid-row[data-idx="2"] [data-fieldname="fieldtype"] .static-area').should('have.text', '🔵 Section Break');
cy.get(
'[data-fieldname="fields"] .grid-row[data-idx="2"] [data-fieldname="fieldtype"] .static-area'
).should("have.text", "🔵 Section Break");
});
it('Verifying data control by inputting different patterns for "Name" field', () => {
cy.new_form('Test Data Control');
cy.new_form("Test Data Control");
//Checking the URL for the new form of the doctype
cy.location("pathname").should('eq', '/app/test-data-control/new-test-data-control-1');
cy.get('.title-text').should('have.text', 'New Test Data Control');
cy.get('.frappe-control[data-fieldname="name1"]').find('label').should('have.class', 'reqd');
cy.get('.frappe-control[data-fieldname="email"]').find('label').should('have.class', 'reqd');
cy.get('.frappe-control[data-fieldname="phone"]').find('label').should('have.class', 'reqd');
cy.location("pathname").should("eq", "/app/test-data-control/new-test-data-control-1");
cy.get(".title-text").should("have.text", "New Test Data Control");
cy.get('.frappe-control[data-fieldname="name1"]')
.find("label")
.should("have.class", "reqd");
cy.get('.frappe-control[data-fieldname="email"]')
.find("label")
.should("have.class", "reqd");
cy.get('.frappe-control[data-fieldname="phone"]')
.find("label")
.should("have.class", "reqd");
//Checking if the status is "Not Saved" initially
cy.get('.indicator-pill').should('have.text', 'Not Saved');
cy.get(".indicator-pill").should("have.text", "Not Saved");
//Inputting data in the field
cy.fill_field('name1', '@@###', 'Data');
cy.fill_field('email', 'test@example.com', 'Data');
cy.fill_field('phone', '9834280031', 'Data');
cy.fill_field("name1", "@@###", "Data");
cy.fill_field("email", "test@example.com", "Data");
cy.fill_field("phone", "9834280031", "Data");
//Checking if the border color of the field changes to red
cy.get('.frappe-control[data-fieldname="name1"]').should('have.class', 'has-error');
cy.get('.frappe-control[data-fieldname="name1"]').should("have.class", "has-error");
cy.save();
//Checking for the error message
cy.get('.modal-title').should('have.text', 'Message');
cy.get('.msgprint').should('have.text', '@@### is not a valid Name');
cy.get(".modal-title").should("have.text", "Message");
cy.get(".msgprint").should("have.text", "@@### is not a valid Name");
cy.hide_dialog();
cy.get_field('name1', 'Data').clear({force: true});
cy.fill_field('name1', 'Komal{}/!', 'Data');
cy.get('.frappe-control[data-fieldname="name1"]').should('have.class', 'has-error');
cy.get_field("name1", "Data").clear({ force: true });
cy.fill_field("name1", "Komal{}/!", "Data");
cy.get('.frappe-control[data-fieldname="name1"]').should("have.class", "has-error");
cy.save();
cy.get('.modal-title').should('have.text', 'Message');
cy.get('.msgprint').should('have.text', 'Komal{}/! is not a valid Name');
cy.get(".modal-title").should("have.text", "Message");
cy.get(".msgprint").should("have.text", "Komal{}/! is not a valid Name");
cy.hide_dialog();
});
it('Verifying data control by inputting different patterns for "Email" field', () => {
cy.get_field('name1', 'Data').clear({force: true});
cy.fill_field('name1', 'Komal', 'Data');
cy.get_field('email', 'Data').clear({force: true});
cy.fill_field('email', 'komal', 'Data');
cy.get('.frappe-control[data-fieldname="email"]').should('have.class', 'has-error');
cy.get_field("name1", "Data").clear({ force: true });
cy.fill_field("name1", "Komal", "Data");
cy.get_field("email", "Data").clear({ force: true });
cy.fill_field("email", "komal", "Data");
cy.get('.frappe-control[data-fieldname="email"]').should("have.class", "has-error");
cy.save();
cy.get('.modal-title').should('have.text', 'Message');
cy.get('.msgprint').should('have.text', 'komal is not a valid Email Address');
cy.get(".modal-title").should("have.text", "Message");
cy.get(".msgprint").should("have.text", "komal is not a valid Email Address");
cy.hide_dialog();
cy.get_field('email', 'Data').clear({force: true});
cy.fill_field('email', 'komal@test', 'Data');
cy.get('.frappe-control[data-fieldname="email"]').should('have.class', 'has-error');
cy.get_field("email", "Data").clear({ force: true });
cy.fill_field("email", "komal@test", "Data");
cy.get('.frappe-control[data-fieldname="email"]').should("have.class", "has-error");
cy.save();
cy.get('.modal-title').should('have.text', 'Message');
cy.get('.msgprint').should('have.text', 'komal@test is not a valid Email Address');
cy.get(".modal-title").should("have.text", "Message");
cy.get(".msgprint").should("have.text", "komal@test is not a valid Email Address");
cy.hide_dialog();
});
it('Verifying data control by inputting different patterns for "Phone" field', () => {
cy.get_field('email', 'Data').clear({force: true});
cy.fill_field('email', 'komal@test.com', 'Data');
cy.get_field('phone', 'Data').clear({force: true});
cy.fill_field('phone', 'komal', 'Data');
cy.get('.frappe-control[data-fieldname="phone"]').should('have.class', 'has-error');
cy.findByRole('button', {name: 'Save'}).click({force: true});
cy.get('.modal-title').should('have.text', 'Message');
cy.get('.msgprint').should('have.text', 'komal is not a valid Phone Number');
cy.get_field("email", "Data").clear({ force: true });
cy.fill_field("email", "komal@test.com", "Data");
cy.get_field("phone", "Data").clear({ force: true });
cy.fill_field("phone", "komal", "Data");
cy.get('.frappe-control[data-fieldname="phone"]').should("have.class", "has-error");
cy.findByRole("button", { name: "Save" }).click({ force: true });
cy.get(".modal-title").should("have.text", "Message");
cy.get(".msgprint").should("have.text", "komal is not a valid Phone Number");
cy.hide_dialog();
});
it('Inputting correct data and saving the doc', () => {
it("Inputting correct data and saving the doc", () => {
//Inputting the data as expected and saving the document
cy.get_field('name1', 'Data').clear({force: true});
cy.get_field('email', 'Data').clear({force: true});
cy.get_field('phone', 'Data').clear({force: true});
cy.fill_field('name1', 'Komal', 'Data');
cy.fill_field('email', 'komal@test.com', 'Data');
cy.fill_field('phone', '9432380001', 'Data');
cy.findByRole('button', {name: 'Save'}).click({force: true});
cy.get_field("name1", "Data").clear({ force: true });
cy.get_field("email", "Data").clear({ force: true });
cy.get_field("phone", "Data").clear({ force: true });
cy.fill_field("name1", "Komal", "Data");
cy.fill_field("email", "komal@test.com", "Data");
cy.fill_field("phone", "9432380001", "Data");
cy.findByRole("button", { name: "Save" }).click({ force: true });
//Checking if the fields contains the data which has been filled in
cy.location("pathname").should('not.be', '/app/test-data-control/new-test-data-control-1');
cy.get_field('name1').should('have.value', 'Komal');
cy.get_field('email').should('have.value', 'komal@test.com');
cy.get_field('phone').should('have.value', '9432380001');
cy.location("pathname").should("not.be", "/app/test-data-control/new-test-data-control-1");
cy.get_field("name1").should("have.value", "Komal");
cy.get_field("email").should("have.value", "komal@test.com");
cy.get_field("phone").should("have.value", "9432380001");
});
it('Deleting the doc', () => {
it("Deleting the doc", () => {
//Deleting the inserted document
cy.go_to_list('Test Data Control');
cy.get('.list-row-checkbox').eq(0).click({force: true});
cy.get('.actions-btn-group > .btn').contains('Actions').click();
cy.go_to_list("Test Data Control");
cy.get(".list-row-checkbox").eq(0).click({ force: true });
cy.get(".actions-btn-group > .btn").contains("Actions").click();
cy.get('.actions-btn-group > .dropdown-menu [data-label="Delete"]').click();
cy.click_modal_primary_button('Yes');
cy.click_modal_primary_button("Yes");
});
});

View File

@ -1,82 +1,89 @@
context('Date Control', () => {
context("Date Control", () => {
before(() => {
cy.login();
cy.visit('/app');
cy.visit("/app");
});
function get_dialog(date_field_options) {
return cy.dialog({
title: 'Date',
fields: [{
"label": "Date",
"fieldname": "date",
"fieldtype": "Date",
"in_list_view": 1,
...date_field_options
}]
title: "Date",
fields: [
{
label: "Date",
fieldname: "date",
fieldtype: "Date",
in_list_view: 1,
...date_field_options,
},
],
});
}
it('Selecting a date from the datepicker', () => {
it("Selecting a date from the datepicker", () => {
cy.clear_dialogs();
cy.clear_datepickers();
get_dialog().as('dialog');
cy.get_field('date', 'Date').click();
cy.get('.datepicker--nav-title').click();
cy.get('.datepicker--nav-title').click({force: true});
get_dialog().as("dialog");
cy.get_field("date", "Date").click();
cy.get(".datepicker--nav-title").click();
cy.get(".datepicker--nav-title").click({ force: true });
//Inputing values in the date field
cy.get('.datepicker--years > .datepicker--cells > .datepicker--cell[data-year=2020]').click();
cy.get('.datepicker--months > .datepicker--cells > .datepicker--cell[data-month=0]').click();
cy.get('.datepicker--days > .datepicker--cells > .datepicker--cell[data-date=15]').click();
cy.get(
".datepicker--years > .datepicker--cells > .datepicker--cell[data-year=2020]"
).click();
cy.get(
".datepicker--months > .datepicker--cells > .datepicker--cell[data-month=0]"
).click();
cy.get(".datepicker--days > .datepicker--cells > .datepicker--cell[data-date=15]").click();
// Verify if the selected date is set the date field
cy.window().its('cur_dialog.fields_dict.date.value').should('be.equal', '2020-01-15');
cy.window().its("cur_dialog.fields_dict.date.value").should("be.equal", "2020-01-15");
});
it('Checking next and previous button', () => {
it("Checking next and previous button", () => {
cy.clear_dialogs();
cy.clear_datepickers();
get_dialog({ default: '2020-01-15' }).as('dialog');
cy.get_field('date', 'Date').click();
get_dialog({ default: "2020-01-15" }).as("dialog");
cy.get_field("date", "Date").click();
//Clicking on the next button in the datepicker
cy.get('.datepicker--nav-action[data-action=next]').click();
cy.get(".datepicker--nav-action[data-action=next]").click();
//Selecting a date from the datepicker
cy.get('.datepicker--cell[data-date=15]').click({force: true});
cy.get(".datepicker--cell[data-date=15]").click({ force: true });
//Verifying if the selected date has been displayed in the date field
cy.window().its('cur_dialog.fields_dict.date.value').should('be.equal', '2020-02-15');
cy.window().its("cur_dialog.fields_dict.date.value").should("be.equal", "2020-02-15");
cy.wait(500);
cy.get_field('date', 'Date').click();
cy.get_field("date", "Date").click();
//Clicking on the previous button in the datepicker
cy.get('.datepicker--nav-action[data-action=prev]').click();
cy.get(".datepicker--nav-action[data-action=prev]").click();
//Selecting a date from the datepicker
cy.get('.datepicker--cell[data-date=15]').click({force: true});
cy.get(".datepicker--cell[data-date=15]").click({ force: true });
//Verifying if the selected date has been displayed in the date field
cy.window().its('cur_dialog.fields_dict.date.value').should('be.equal', '2020-01-15');
cy.window().its("cur_dialog.fields_dict.date.value").should("be.equal", "2020-01-15");
});
it('Clicking on "Today" button gives todays date', () => {
cy.clear_dialogs();
cy.clear_datepickers();
get_dialog().as('dialog');
cy.get_field('date', 'Date').click();
get_dialog().as("dialog");
cy.get_field("date", "Date").click();
//Clicking on "Today" button
cy.get('.datepicker--button').click();
cy.get(".datepicker--button").click();
//Verifying if clicking on "Today" button matches today's date
cy.window().then(win => {
expect(win.cur_dialog.fields_dict.date.value).to.be.equal(win.frappe.datetime.get_today());
cy.window().then((win) => {
expect(win.cur_dialog.fields_dict.date.value).to.be.equal(
win.frappe.datetime.get_today()
);
});
});
});
});

View File

@ -1,42 +1,48 @@
context('Date Range Control', () => {
context("Date Range Control", () => {
before(() => {
cy.login();
cy.visit('/app');
cy.visit("/app");
});
function get_dialog() {
return cy.dialog({
title: 'Date Range',
fields: [{
"label": "Date Range",
"fieldname": "date_range",
"fieldtype": "Date Range",
}]
title: "Date Range",
fields: [
{
label: "Date Range",
fieldname: "date_range",
fieldtype: "Date Range",
},
],
});
}
it('Selecting a date range from the datepicker', () => {
it("Selecting a date range from the datepicker", () => {
cy.clear_dialogs();
cy.clear_datepickers();
get_dialog().as('dialog');
cy.get_field('date_range', 'Date Range').click();
cy.get('.datepicker--nav-title').click();
cy.get('.datepicker--nav-title').click({force: true});
get_dialog().as("dialog");
cy.get_field("date_range", "Date Range").click();
cy.get(".datepicker--nav-title").click();
cy.get(".datepicker--nav-title").click({ force: true });
//Inputing date range values in the date range field
cy.get('.datepicker--years > .datepicker--cells > .datepicker--cell[data-year=2020]').click();
cy.get('.datepicker--months > .datepicker--cells > .datepicker--cell[data-month=0]').click();
cy.get('.datepicker--cell[data-date=1]:first').click({force: true});
cy.get('.datepicker--cell[data-date=15]:first').click({force: true});
cy.get(
".datepicker--years > .datepicker--cells > .datepicker--cell[data-year=2020]"
).click();
cy.get(
".datepicker--months > .datepicker--cells > .datepicker--cell[data-month=0]"
).click();
cy.get(".datepicker--cell[data-date=1]:first").click({ force: true });
cy.get(".datepicker--cell[data-date=15]:first").click({ force: true });
// Verify if the selected date range values is set in the date range field
cy.window()
.its('cur_dialog')
.then(dialog => {
.its("cur_dialog")
.then((dialog) => {
let date_range = dialog.get_value("date_range");
expect(date_range[0]).to.equal('2020-01-01');
expect(date_range[1]).to.equal('2020-01-15');
expect(date_range[0]).to.equal("2020-01-01");
expect(date_range[1]).to.equal("2020-01-15");
});
});
});
});

View File

@ -1,46 +1,46 @@
context('Control Duration', () => {
context("Control Duration", () => {
before(() => {
cy.login();
cy.visit('/app/website');
cy.visit("/app/website");
});
function get_dialog_with_duration(hide_days = 0, hide_seconds = 0) {
return cy.dialog({
title: 'Duration',
fields: [{
'fieldname': 'duration',
'fieldtype': 'Duration',
'hide_days': hide_days,
'hide_seconds': hide_seconds
}]
title: "Duration",
fields: [
{
fieldname: "duration",
fieldtype: "Duration",
hide_days: hide_days,
hide_seconds: hide_seconds,
},
],
});
}
it('should set duration', () => {
get_dialog_with_duration().as('dialog');
cy.get('.frappe-control[data-fieldname=duration] input')
.first()
.click();
cy.get('.duration-input[data-duration=days]')
it("should set duration", () => {
get_dialog_with_duration().as("dialog");
cy.get(".frappe-control[data-fieldname=duration] input").first().click();
cy.get(".duration-input[data-duration=days]")
.type(45, { force: true })
.blur({ force: true });
cy.get('.duration-input[data-duration=minutes]')
.type(30)
.blur({ force: true });
cy.get('.frappe-control[data-fieldname=duration] input').first().should('have.value', '45d 30m');
cy.get('.frappe-control[data-fieldname=duration] input').first().blur();
cy.get('.duration-picker').should('not.be.visible');
cy.get('@dialog').then(dialog => {
let value = dialog.get_value('duration');
cy.get(".duration-input[data-duration=minutes]").type(30).blur({ force: true });
cy.get(".frappe-control[data-fieldname=duration] input")
.first()
.should("have.value", "45d 30m");
cy.get(".frappe-control[data-fieldname=duration] input").first().blur();
cy.get(".duration-picker").should("not.be.visible");
cy.get("@dialog").then((dialog) => {
let value = dialog.get_value("duration");
expect(value).to.equal(3889800);
cy.hide_dialog();
});
});
it('should hide days or seconds according to duration options', () => {
get_dialog_with_duration(1, 1).as('dialog');
cy.get('.frappe-control[data-fieldname=duration] input').first();
cy.get('.duration-input[data-duration=days]').should('not.be.visible');
cy.get('.duration-input[data-duration=seconds]').should('not.be.visible');
it("should hide days or seconds according to duration options", () => {
get_dialog_with_duration(1, 1).as("dialog");
cy.get(".frappe-control[data-fieldname=duration] input").first();
cy.get(".duration-input[data-duration=days]").should("not.be.visible");
cy.get(".duration-input[data-duration=seconds]").should("not.be.visible");
});
});
});

View File

@ -1,133 +1,159 @@
context('Dynamic Link', () => {
context("Dynamic Link", () => {
before(() => {
cy.login();
cy.visit('/app/doctype');
return cy.window().its('frappe').then(frappe => {
return frappe.xcall('frappe.tests.ui_test_helpers.create_doctype', {
name: 'Test Dynamic Link',
fields: [
{
"label": "Document Type",
"fieldname": "doc_type",
"fieldtype": "Link",
"options": "DocType",
"in_list_view": 1,
"in_standard_filter": 1,
},
{
"label": "Document ID",
"fieldname": "doc_id",
"fieldtype": "Dynamic Link",
"options": "doc_type",
"in_list_view": 1,
"in_standard_filter": 1,
},
]
cy.visit("/app/doctype");
return cy
.window()
.its("frappe")
.then((frappe) => {
return frappe.xcall("frappe.tests.ui_test_helpers.create_doctype", {
name: "Test Dynamic Link",
fields: [
{
label: "Document Type",
fieldname: "doc_type",
fieldtype: "Link",
options: "DocType",
in_list_view: 1,
in_standard_filter: 1,
},
{
label: "Document ID",
fieldname: "doc_id",
fieldtype: "Dynamic Link",
options: "doc_type",
in_list_view: 1,
in_standard_filter: 1,
},
],
});
});
});
});
function get_dialog_with_dynamic_link() {
return cy.dialog({
title: 'Dynamic Link',
fields: [{
"label": "Document Type",
"fieldname": "doc_type",
"fieldtype": "Link",
"options": "DocType",
"in_list_view": 1,
},
{
"label": "Document ID",
"fieldname": "doc_id",
"fieldtype": "Dynamic Link",
"options": "doc_type",
"in_list_view": 1,
}]
title: "Dynamic Link",
fields: [
{
label: "Document Type",
fieldname: "doc_type",
fieldtype: "Link",
options: "DocType",
in_list_view: 1,
},
{
label: "Document ID",
fieldname: "doc_id",
fieldtype: "Dynamic Link",
options: "doc_type",
in_list_view: 1,
},
],
});
}
function get_dialog_with_dynamic_link_option() {
return cy.dialog({
title: 'Dynamic Link',
fields: [{
"label": "Document Type",
"fieldname": "doc_type",
"fieldtype": "Link",
"options": "DocType",
"in_list_view": 1,
},
{
"label": "Document ID",
"fieldname": "doc_id",
"fieldtype": "Dynamic Link",
"get_options": () => {
return "User";
title: "Dynamic Link",
fields: [
{
label: "Document Type",
fieldname: "doc_type",
fieldtype: "Link",
options: "DocType",
in_list_view: 1,
},
"in_list_view": 1,
}]
{
label: "Document ID",
fieldname: "doc_id",
fieldtype: "Dynamic Link",
get_options: () => {
return "User";
},
in_list_view: 1,
},
],
});
}
it('Creating a dynamic link by passing option as function and verifying it in a dialog', () => {
get_dialog_with_dynamic_link_option().as('dialog');
cy.get_field('doc_type').clear();
cy.fill_field('doc_type', 'User', 'Link');
cy.get_field('doc_id').click();
it("Creating a dynamic link by passing option as function and verifying it in a dialog", () => {
get_dialog_with_dynamic_link_option().as("dialog");
cy.get_field("doc_type").clear();
cy.fill_field("doc_type", "User", "Link");
cy.get_field("doc_id").click();
//Checking if the listbox have length greater than 0
cy.get('[data-fieldname="doc_id"]').find('.awesomplete').find("li").its('length').should('be.gte', 0);
cy.get('.btn-modal-close').click({force: true});
cy.get('[data-fieldname="doc_id"]')
.find(".awesomplete")
.find("li")
.its("length")
.should("be.gte", 0);
cy.get(".btn-modal-close").click({ force: true });
});
it('Creating a dynamic link and verifying it in a dialog', () => {
get_dialog_with_dynamic_link().as('dialog');
cy.get_field('doc_type').clear();
cy.fill_field('doc_type', 'User', 'Link');
cy.get_field('doc_id').click();
it("Creating a dynamic link and verifying it in a dialog", () => {
get_dialog_with_dynamic_link().as("dialog");
cy.get_field("doc_type").clear();
cy.fill_field("doc_type", "User", "Link");
cy.get_field("doc_id").click();
//Checking if the listbox have length greater than 0
cy.get('[data-fieldname="doc_id"]').find('.awesomplete').find("li").its('length').should('be.gte', 0);
cy.get('.btn-modal-close').click({force: true, multiple: true});
cy.get('[data-fieldname="doc_id"]')
.find(".awesomplete")
.find("li")
.its("length")
.should("be.gte", 0);
cy.get(".btn-modal-close").click({ force: true, multiple: true });
});
it('Creating a dynamic link and verifying it', () => {
cy.visit('/app/test-dynamic-link');
it("Creating a dynamic link and verifying it", () => {
cy.visit("/app/test-dynamic-link");
//Clicking on the Document ID field
cy.get_field('doc_type').clear();
cy.get_field("doc_type").clear();
//Entering User in the Doctype field
cy.fill_field('doc_type', 'User', 'Link', {delay: 500});
cy.get_field('doc_id').click();
cy.fill_field("doc_type", "User", "Link", { delay: 500 });
cy.get_field("doc_id").click();
//Checking if the listbox have length greater than 0
cy.get('[data-fieldname="doc_id"]').find('.awesomplete').find("li").its('length').should('be.gte', 0);
cy.get('[data-fieldname="doc_id"]')
.find(".awesomplete")
.find("li")
.its("length")
.should("be.gte", 0);
//Opening a new form for dynamic link doctype
cy.new_form('Test Dynamic Link');
cy.get_field('doc_type').clear();
cy.new_form("Test Dynamic Link");
cy.get_field("doc_type").clear();
//Entering User in the Doctype field
cy.fill_field('doc_type', 'User', 'Link', {delay: 500});
cy.get_field('doc_id').click();
cy.fill_field("doc_type", "User", "Link", { delay: 500 });
cy.get_field("doc_id").click();
//Checking if the listbox have length greater than 0
cy.get('[data-fieldname="doc_id"]').find('.awesomplete').find("li").its('length').should('be.gte', 0);
cy.get_field('doc_type').clear();
cy.get('[data-fieldname="doc_id"]')
.find(".awesomplete")
.find("li")
.its("length")
.should("be.gte", 0);
cy.get_field("doc_type").clear();
//Entering System Settings in the Doctype field
cy.intercept('/api/method/frappe.desk.search.search_link').as('search_query');
cy.fill_field('doc_type', 'System Settings', 'Link', {delay: 500});
cy.wait('@search_query');
cy.get(`[data-fieldname="doc_type"] ul:visible li:first-child`)
.click({scrollBehavior: false});
cy.intercept("/api/method/frappe.desk.search.search_link").as("search_query");
cy.fill_field("doc_type", "System Settings", "Link", { delay: 500 });
cy.wait("@search_query");
cy.get(`[data-fieldname="doc_type"] ul:visible li:first-child`).click({
scrollBehavior: false,
});
cy.get_field('doc_id').click();
cy.get_field("doc_id").click();
//Checking if the system throws error
cy.get('.modal-title').should('have.text', 'Error');
cy.get('.msgprint').should('have.text', 'System Settings is not a valid DocType for Dynamic Link');
cy.get(".modal-title").should("have.text", "Error");
cy.get(".msgprint").should(
"have.text",
"System Settings is not a valid DocType for Dynamic Link"
);
});
});

View File

@ -11,9 +11,9 @@ context("Control Float", () => {
{
fieldname: "float_number",
fieldtype: "Float",
Label: "Float"
}
]
Label: "Float",
},
],
});
}
@ -21,27 +21,21 @@ context("Control Float", () => {
get_dialog_with_float().as("dialog");
let data = get_data();
data.forEach(x => {
data.forEach((x) => {
cy.window()
.its("frappe")
.then(frappe => {
.then((frappe) => {
frappe.boot.sysdefaults.number_format = x.number_format;
});
x.values.forEach(d => {
x.values.forEach((d) => {
cy.get_field("float_number", "Float").clear();
cy.fill_field("float_number", d.input, "Float").blur();
cy.get_field("float_number", "Float").should(
"have.value",
d.blur_expected
);
cy.get_field("float_number", "Float").should("have.value", d.blur_expected);
cy.get_field("float_number", "Float").focus();
cy.get_field("float_number", "Float").blur();
cy.get_field("float_number", "Float").focus();
cy.get_field("float_number", "Float").should(
"have.value",
d.focus_expected
);
cy.get_field("float_number", "Float").should("have.value", d.focus_expected);
});
});
});
@ -54,19 +48,19 @@ context("Control Float", () => {
{
input: "364.87,334",
blur_expected: "36.487,334",
focus_expected: "36487.334"
focus_expected: "36487.334",
},
{
input: "36487,334",
blur_expected: "36.487,334",
focus_expected: "36487.334"
focus_expected: "36487.334",
},
{
input: "100",
blur_expected: "100,000",
focus_expected: "100"
}
]
focus_expected: "100",
},
],
},
{
number_format: "#,###.##",
@ -74,20 +68,20 @@ context("Control Float", () => {
{
input: "364,87.334",
blur_expected: "36,487.334",
focus_expected: "36487.334"
focus_expected: "36487.334",
},
{
input: "36487.334",
blur_expected: "36,487.334",
focus_expected: "36487.334"
focus_expected: "36487.334",
},
{
input: "100",
blur_expected: "100.000",
focus_expected: "100"
}
]
}
focus_expected: "100",
},
],
},
];
}
});

View File

@ -1,50 +1,55 @@
context('Control Icon', () => {
context("Control Icon", () => {
before(() => {
cy.login();
cy.visit('/app/website');
cy.visit("/app/website");
});
function get_dialog_with_icon() {
return cy.dialog({
title: 'Icon',
fields: [{
label: 'Icon',
fieldname: 'icon',
fieldtype: 'Icon'
}]
title: "Icon",
fields: [
{
label: "Icon",
fieldname: "icon",
fieldtype: "Icon",
},
],
});
}
it('should set icon', () => {
get_dialog_with_icon().as('dialog');
cy.get('.frappe-control[data-fieldname=icon]').findByRole('textbox').click();
it("should set icon", () => {
get_dialog_with_icon().as("dialog");
cy.get(".frappe-control[data-fieldname=icon]").findByRole("textbox").click();
cy.get('.icon-picker .icon-wrapper[id=heart-active]').first().click();
cy.get('.frappe-control[data-fieldname=icon]').findByRole('textbox').should('have.value', 'heart-active');
cy.get('@dialog').then(dialog => {
let value = dialog.get_value('icon');
expect(value).to.equal('heart-active');
cy.get(".icon-picker .icon-wrapper[id=heart-active]").first().click();
cy.get(".frappe-control[data-fieldname=icon]")
.findByRole("textbox")
.should("have.value", "heart-active");
cy.get("@dialog").then((dialog) => {
let value = dialog.get_value("icon");
expect(value).to.equal("heart-active");
});
cy.get('.icon-picker .icon-wrapper[id=heart]').first().click();
cy.get('.frappe-control[data-fieldname=icon]').findByRole('textbox').should('have.value', 'heart');
cy.get('@dialog').then(dialog => {
let value = dialog.get_value('icon');
expect(value).to.equal('heart');
cy.get(".icon-picker .icon-wrapper[id=heart]").first().click();
cy.get(".frappe-control[data-fieldname=icon]")
.findByRole("textbox")
.should("have.value", "heart");
cy.get("@dialog").then((dialog) => {
let value = dialog.get_value("icon");
expect(value).to.equal("heart");
});
});
it('search for icon and clear search input', () => {
let search_text = 'ed';
cy.get('.icon-picker').findByRole('searchbox').click().type(search_text);
cy.get('.icon-section .icon-wrapper:not(.hidden)').then(i => {
cy.get(`.icon-section .icon-wrapper[id*='${search_text}']`).then(icons => {
it("search for icon and clear search input", () => {
let search_text = "ed";
cy.get(".icon-picker").findByRole("searchbox").click().type(search_text);
cy.get(".icon-section .icon-wrapper:not(.hidden)").then((i) => {
cy.get(`.icon-section .icon-wrapper[id*='${search_text}']`).then((icons) => {
expect(i.length).to.equal(icons.length);
});
});
cy.get('.icon-picker').findByRole('searchbox').clear().blur();
cy.get('.icon-section .icon-wrapper').should('not.have.class', 'hidden');
cy.get(".icon-picker").findByRole("searchbox").clear().blur();
cy.get(".icon-section .icon-wrapper").should("not.have.class", "hidden");
});
});
});

View File

@ -1,93 +1,101 @@
context('Control Link', () => {
context("Control Link", () => {
before(() => {
cy.login();
cy.visit('/app/website');
cy.visit("/app/website");
});
beforeEach(() => {
cy.visit('/app/website');
cy.visit("/app/website");
cy.create_records({
doctype: 'ToDo',
description: 'this is a test todo for link'
}).as('todos');
doctype: "ToDo",
description: "this is a test todo for link",
}).as("todos");
});
function get_dialog_with_link() {
return cy.dialog({
title: 'Link',
title: "Link",
fields: [
{
'label': 'Select ToDo',
'fieldname': 'link',
'fieldtype': 'Link',
'options': 'ToDo',
}
]
label: "Select ToDo",
fieldname: "link",
fieldtype: "Link",
options: "ToDo",
},
],
});
}
function get_dialog_with_user_link() {
return cy.dialog({
title: 'Link',
title: "Link",
fields: [
{
'label': 'Select User',
'fieldname': 'link',
'fieldtype': 'Link',
'options': 'User',
}
]
label: "Select User",
fieldname: "link",
fieldtype: "Link",
options: "User",
},
],
});
}
it('should set the valid value', () => {
get_dialog_with_link().as('dialog');
it("should set the valid value", () => {
get_dialog_with_link().as("dialog");
cy.insert_doc("Property Setter", {
"doctype": "Property Setter",
"doc_type": "User",
"property": "translate_link_fields",
"property_type": "Check",
"doctype_or_field": "DocType",
"value": "0"
}, true);
cy.insert_doc(
"Property Setter",
{
doctype: "Property Setter",
doc_type: "User",
property: "translate_link_fields",
property_type: "Check",
doctype_or_field: "DocType",
value: "0",
},
true
);
cy.insert_doc("Property Setter", {
"doctype": "Property Setter",
"doc_type": "ToDo",
"property": "show_title_field_in_link",
"property_type": "Check",
"doctype_or_field": "DocType",
"value": "0"
}, true);
cy.insert_doc(
"Property Setter",
{
doctype: "Property Setter",
doc_type: "ToDo",
property: "show_title_field_in_link",
property_type: "Check",
doctype_or_field: "DocType",
value: "0",
},
true
);
cy.intercept('POST', '/api/method/frappe.desk.search.search_link').as('search_link');
cy.intercept("POST", "/api/method/frappe.desk.search.search_link").as("search_link");
cy.get('.frappe-control[data-fieldname=link] input').focus().as('input');
cy.wait('@search_link');
cy.get('@input').type('todo for link', { delay: 200 });
cy.wait('@search_link');
cy.get('.frappe-control[data-fieldname=link]').findByRole('listbox').should('be.visible');
cy.get('.frappe-control[data-fieldname=link] input').type('{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');
cy.get(".frappe-control[data-fieldname=link] input").focus().as("input");
cy.wait("@search_link");
cy.get("@input").type("todo for link", { delay: 200 });
cy.wait("@search_link");
cy.get(".frappe-control[data-fieldname=link]").findByRole("listbox").should("be.visible");
cy.get(".frappe-control[data-fieldname=link] input").type("{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('should unset invalid value', () => {
get_dialog_with_link().as('dialog');
it("should unset invalid value", () => {
get_dialog_with_link().as("dialog");
cy.intercept('POST', '/api/method/frappe.client.validate_link').as('validate_link');
cy.intercept("POST", "/api/method/frappe.client.validate_link").as("validate_link");
cy.get('.frappe-control[data-fieldname=link] input')
.type('invalid value', { delay: 100 })
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', '');
cy.wait("@validate_link");
cy.get(".frappe-control[data-fieldname=link] input").should("have.value", "");
});
it("should be possible set empty value explicitly", () => {
@ -95,295 +103,325 @@ context('Control Link', () => {
cy.intercept("POST", "/api/method/frappe.client.validate_link").as("validate_link");
cy.get(".frappe-control[data-fieldname=link] input")
.type(" ", { delay: 100 })
.blur();
cy.get(".frappe-control[data-fieldname=link] input").type(" ", { delay: 100 }).blur();
cy.wait("@validate_link");
cy.get(".frappe-control[data-fieldname=link] input").should("have.value", "");
cy.window()
.its("cur_dialog")
.then((dialog) => {
expect(dialog.get_value("link")).to.equal('');
expect(dialog.get_value("link")).to.equal("");
});
});
it('should route to form on arrow click', () => {
get_dialog_with_link().as('dialog');
it("should route to form on arrow click", () => {
get_dialog_with_link().as("dialog");
cy.intercept('POST', '/api/method/frappe.client.validate_link').as('validate_link');
cy.intercept('POST', '/api/method/frappe.desk.search.search_link').as('search_link');
cy.intercept("POST", "/api/method/frappe.client.validate_link").as("validate_link");
cy.intercept("POST", "/api/method/frappe.desk.search.search_link").as("search_link");
cy.get('@todos').then(todos => {
cy.get('.frappe-control[data-fieldname=link] input').as('input');
cy.get('@input').focus();
cy.wait('@search_link');
cy.get('@input').type(todos[0]).blur();
cy.wait('@validate_link');
cy.get('@input').focus();
cy.get("@todos").then((todos) => {
cy.get(".frappe-control[data-fieldname=link] input").as("input");
cy.get("@input").focus();
cy.wait("@search_link");
cy.get("@input").type(todos[0]).blur();
cy.wait("@validate_link");
cy.get("@input").focus();
cy.wait(500); // wait for arrow to show
cy.get('.frappe-control[data-fieldname=link] .btn-open')
.should('be.visible')
.click();
cy.location('pathname').should('eq', `/app/todo/${todos[0]}`);
cy.get(".frappe-control[data-fieldname=link] .btn-open").should("be.visible").click();
cy.location("pathname").should("eq", `/app/todo/${todos[0]}`);
});
});
it('show title field in link', () => {
it("show title field in link", () => {
cy.insert_doc(
"Property Setter",
{
doctype: "Property Setter",
doc_type: "User",
property: "translate_link_fields",
property_type: "Check",
doctype_or_field: "DocType",
value: "0",
},
true
);
cy.insert_doc("Property Setter", {
"doctype": "Property Setter",
"doc_type": "User",
"property": "translate_link_fields",
"property_type": "Check",
"doctype_or_field": "DocType",
"value": "0"
}, true);
cy.insert_doc("Property Setter", {
"doctype": "Property Setter",
"doc_type": "ToDo",
"property": "show_title_field_in_link",
"property_type": "Check",
"doctype_or_field": "DocType",
"value": "1"
}, true);
cy.insert_doc(
"Property Setter",
{
doctype: "Property Setter",
doc_type: "ToDo",
property: "show_title_field_in_link",
property_type: "Check",
doctype_or_field: "DocType",
value: "1",
},
true
);
cy.clear_cache();
cy.wait(500);
get_dialog_with_link().as('dialog');
cy.window().its('frappe').then(frappe => {
if (!frappe.boot) {
frappe.boot = {
link_title_doctypes: ['ToDo']
};
} else {
frappe.boot.link_title_doctypes = ['ToDo'];
}
});
get_dialog_with_link().as("dialog");
cy.window()
.its("frappe")
.then((frappe) => {
if (!frappe.boot) {
frappe.boot = {
link_title_doctypes: ["ToDo"],
};
} else {
frappe.boot.link_title_doctypes = ["ToDo"];
}
});
cy.intercept('POST', '/api/method/frappe.desk.search.search_link').as('search_link');
cy.intercept("POST", "/api/method/frappe.desk.search.search_link").as("search_link");
cy.get('.frappe-control[data-fieldname=link] input').focus().as('input');
cy.wait('@search_link');
cy.get('@input').type('todo for link');
cy.wait('@search_link');
cy.get('.frappe-control[data-fieldname=link] ul').should('be.visible');
cy.get('.frappe-control[data-fieldname=link] input').type('{enter}', { delay: 100 });
cy.get('.frappe-control[data-fieldname=link] input').blur();
cy.get('@dialog').then(dialog => {
cy.get('@todos').then(todos => {
let field = dialog.get_field('link');
cy.get(".frappe-control[data-fieldname=link] input").focus().as("input");
cy.wait("@search_link");
cy.get("@input").type("todo for link");
cy.wait("@search_link");
cy.get(".frappe-control[data-fieldname=link] ul").should("be.visible");
cy.get(".frappe-control[data-fieldname=link] input").type("{enter}", { delay: 100 });
cy.get(".frappe-control[data-fieldname=link] input").blur();
cy.get("@dialog").then((dialog) => {
cy.get("@todos").then((todos) => {
let field = dialog.get_field("link");
let value = field.get_value();
let label = field.get_label_value();
expect(value).to.eq(todos[0]);
expect(label).to.eq('this is a test todo for link');
expect(label).to.eq("this is a test todo for link");
});
});
});
it('should update dependant fields (via fetch_from)', () => {
cy.get('@todos').then(todos => {
it("should update dependant fields (via fetch_from)", () => {
cy.get("@todos").then((todos) => {
cy.visit(`/app/todo/${todos[0]}`);
cy.intercept('POST', '/api/method/frappe.desk.search.search_link').as('search_link');
cy.intercept('POST', '/api/method/frappe.client.validate_link').as('validate_link');
cy.intercept("POST", "/api/method/frappe.desk.search.search_link").as("search_link");
cy.intercept("POST", "/api/method/frappe.client.validate_link").as("validate_link");
cy.get('.frappe-control[data-fieldname=assigned_by] input').focus().as('input');
cy.get('@input').type('Administrator', {delay: 100}).blur();
cy.wait('@validate_link');
cy.get('.frappe-control[data-fieldname=assigned_by_full_name] .control-value').should(
'contain', 'Administrator'
cy.get(".frappe-control[data-fieldname=assigned_by] input").focus().as("input");
cy.get("@input").type("Administrator", { delay: 100 }).blur();
cy.wait("@validate_link");
cy.get(".frappe-control[data-fieldname=assigned_by_full_name] .control-value").should(
"contain",
"Administrator"
);
cy.window()
.its("cur_frm.doc.assigned_by")
.should("eq", "Administrator");
cy.window().its("cur_frm.doc.assigned_by").should("eq", "Administrator");
// invalid input
cy.get('@input').clear().type('invalid input', {delay: 100}).blur();
cy.get('.frappe-control[data-fieldname=assigned_by_full_name] .control-value').should(
'contain', ''
cy.get("@input").clear().type("invalid input", { delay: 100 }).blur();
cy.get(".frappe-control[data-fieldname=assigned_by_full_name] .control-value").should(
"contain",
""
);
cy.window()
.its("cur_frm.doc.assigned_by")
.should("eq", null);
cy.window().its("cur_frm.doc.assigned_by").should("eq", null);
// set valid value again
cy.get('@input').clear().focus();
cy.wait('@search_link');
cy.get('@input').type('Administrator', {delay: 100}).blur();
cy.wait('@validate_link');
cy.get("@input").clear().focus();
cy.wait("@search_link");
cy.get("@input").type("Administrator", { delay: 100 }).blur();
cy.wait("@validate_link");
cy.window()
.its("cur_frm.doc.assigned_by")
.should("eq", "Administrator");
cy.window().its("cur_frm.doc.assigned_by").should("eq", "Administrator");
// clear input
cy.get('@input').clear().blur();
cy.get('.frappe-control[data-fieldname=assigned_by_full_name] .control-value').should(
'contain', ''
cy.get("@input").clear().blur();
cy.get(".frappe-control[data-fieldname=assigned_by_full_name] .control-value").should(
"contain",
""
);
cy.window()
.its("cur_frm.doc.assigned_by")
.should("eq", "");
cy.window().its("cur_frm.doc.assigned_by").should("eq", "");
});
});
it("should set default values", () => {
cy.insert_doc("Property Setter", {
"doctype_or_field": "DocField",
"doc_type": "ToDo",
"field_name": "assigned_by",
"property": "default",
"property_type": "Text",
"value": "Administrator"
}, true);
cy.insert_doc(
"Property Setter",
{
doctype_or_field: "DocField",
doc_type: "ToDo",
field_name: "assigned_by",
property: "default",
property_type: "Text",
value: "Administrator",
},
true
);
cy.reload();
cy.new_form("ToDo");
cy.fill_field("description", "new", "Text Editor");
cy.intercept("POST", "/api/method/frappe.desk.form.save.savedocs").as("save_form");
cy.findByRole("button", {name: "Save"}).click();
cy.findByRole("button", { name: "Save" }).click();
cy.wait("@save_form");
cy.get(".frappe-control[data-fieldname=assigned_by_full_name] .control-value").should(
"contain", "Administrator"
"contain",
"Administrator"
);
// if user clears default value explicitly, system should not reset default again
cy.get_field("assigned_by").clear().blur();
cy.intercept("POST", "/api/method/frappe.desk.form.save.savedocs").as("save_form");
cy.findByRole("button", {name: "Save"}).click();
cy.findByRole("button", { name: "Save" }).click();
cy.wait("@save_form");
cy.get_field("assigned_by").should("have.value", "");
cy.get(".frappe-control[data-fieldname=assigned_by_full_name] .control-value").should(
"contain", ""
"contain",
""
);
});
it('show translated text for link with show_title_field_in_link enabled', () => {
cy.insert_doc("Property Setter", {
"doctype": "Property Setter",
"doc_type": "ToDo",
"property": "translate_link_fields",
"property_type": "Check",
"doctype_or_field": "DocType",
"value": "1"
}, true);
it("show translated text for link with show_title_field_in_link enabled", () => {
cy.insert_doc(
"Property Setter",
{
doctype: "Property Setter",
doc_type: "ToDo",
property: "translate_link_fields",
property_type: "Check",
doctype_or_field: "DocType",
value: "1",
},
true
);
cy.insert_doc("Property Setter", {
"doctype": "Property Setter",
"doc_type": "ToDo",
"property": "show_title_field_in_link",
"property_type": "Check",
"doctype_or_field": "DocType",
"value": "1"
}, true);
cy.insert_doc(
"Property Setter",
{
doctype: "Property Setter",
doc_type: "ToDo",
property: "show_title_field_in_link",
property_type: "Check",
doctype_or_field: "DocType",
value: "1",
},
true
);
cy.window().its('frappe').then(frappe => {
cy.insert_doc("Translation", {
doctype: "Translation",
language: frappe.boot.lang,
source_text: "this is a test todo for link",
translated_text: "this is a translated test todo for link",
cy.window()
.its("frappe")
.then((frappe) => {
cy.insert_doc("Translation", {
doctype: "Translation",
language: frappe.boot.lang,
source_text: "this is a test todo for link",
translated_text: "this is a translated test todo for link",
});
});
});
cy.clear_cache();
cy.wait(500);
cy.window().its('frappe').then(frappe => {
if (!frappe.boot) {
frappe.boot = {
link_title_doctypes: ['ToDo'],
translatable_doctypes: ['ToDo']
};
} else {
frappe.boot.link_title_doctypes = ['ToDo'];
frappe.boot.translatable_doctypes = ['ToDo'];
}
});
cy.window()
.its("frappe")
.then((frappe) => {
if (!frappe.boot) {
frappe.boot = {
link_title_doctypes: ["ToDo"],
translatable_doctypes: ["ToDo"],
};
} else {
frappe.boot.link_title_doctypes = ["ToDo"];
frappe.boot.translatable_doctypes = ["ToDo"];
}
});
get_dialog_with_link().as('dialog');
cy.intercept('POST', '/api/method/frappe.desk.search.search_link').as('search_link');
get_dialog_with_link().as("dialog");
cy.intercept("POST", "/api/method/frappe.desk.search.search_link").as("search_link");
cy.get('.frappe-control[data-fieldname=link] input').focus().as('input');
cy.wait('@search_link');
cy.get('@input').type('todo for link', { delay: 100 });
cy.wait('@search_link');
cy.get('.frappe-control[data-fieldname=link] ul').should('be.visible');
cy.get('.frappe-control[data-fieldname=link] input').type('{enter}', { delay: 100 });
cy.get('.frappe-control[data-fieldname=link] input').blur();
cy.get('@dialog').then(dialog => {
cy.get('@todos').then(todos => {
let field = dialog.get_field('link');
cy.get(".frappe-control[data-fieldname=link] input").focus().as("input");
cy.wait("@search_link");
cy.get("@input").type("todo for link", { delay: 100 });
cy.wait("@search_link");
cy.get(".frappe-control[data-fieldname=link] ul").should("be.visible");
cy.get(".frappe-control[data-fieldname=link] input").type("{enter}", { delay: 100 });
cy.get(".frappe-control[data-fieldname=link] input").blur();
cy.get("@dialog").then((dialog) => {
cy.get("@todos").then((todos) => {
let field = dialog.get_field("link");
let value = field.get_value();
let label = field.get_label_value();
expect(value).to.eq(todos[0]);
expect(label).to.eq('this is a translated test todo for link');
expect(label).to.eq("this is a translated test todo for link");
});
});
});
it('show translated text for link with show_title_field_in_link disabled', () => {
cy.insert_doc("Property Setter", {
"doctype": "Property Setter",
"doc_type": "User",
"property": "translate_link_fields",
"property_type": "Check",
"doctype_or_field": "DocType",
"value": "1"
}, true);
it("show translated text for link with show_title_field_in_link disabled", () => {
cy.insert_doc(
"Property Setter",
{
doctype: "Property Setter",
doc_type: "User",
property: "translate_link_fields",
property_type: "Check",
doctype_or_field: "DocType",
value: "1",
},
true
);
cy.insert_doc("Property Setter", {
"doctype": "Property Setter",
"doc_type": "ToDo",
"property": "show_title_field_in_link",
"property_type": "Check",
"doctype_or_field": "DocType",
"value": "0"
}, true);
cy.insert_doc(
"Property Setter",
{
doctype: "Property Setter",
doc_type: "ToDo",
property: "show_title_field_in_link",
property_type: "Check",
doctype_or_field: "DocType",
value: "0",
},
true
);
cy.window().its('frappe').then(frappe => {
cy.insert_doc("Translation", {
doctype: "Translation",
language: frappe.boot.lang,
source_text: "test@erpnext.com",
translated_text: "translatedtest@erpnext.com",
cy.window()
.its("frappe")
.then((frappe) => {
cy.insert_doc("Translation", {
doctype: "Translation",
language: frappe.boot.lang,
source_text: "test@erpnext.com",
translated_text: "translatedtest@erpnext.com",
});
});
});
cy.clear_cache();
cy.wait(500);
cy.window().its('frappe').then(frappe => {
if (!frappe.boot) {
frappe.boot = {
translatable_doctypes: ['User']
};
} else {
frappe.boot.translatable_doctypes = ['User'];
}
});
cy.window()
.its("frappe")
.then((frappe) => {
if (!frappe.boot) {
frappe.boot = {
translatable_doctypes: ["User"],
};
} else {
frappe.boot.translatable_doctypes = ["User"];
}
});
get_dialog_with_user_link().as('dialog');
cy.intercept('POST', '/api/method/frappe.desk.search.search_link').as('search_link');
get_dialog_with_user_link().as("dialog");
cy.intercept("POST", "/api/method/frappe.desk.search.search_link").as("search_link");
cy.get('.frappe-control[data-fieldname=link] input').focus().as('input');
cy.wait('@search_link');
cy.get('@input').type('test@erpnext.com', { delay: 100 });
cy.wait('@search_link');
cy.get('.frappe-control[data-fieldname=link] ul').should('be.visible');
cy.get('.frappe-control[data-fieldname=link] input').type('{enter}', { delay: 100 });
cy.get('.frappe-control[data-fieldname=link] input').blur();
cy.get('@dialog').then(dialog => {
let field = dialog.get_field('link');
cy.get(".frappe-control[data-fieldname=link] input").focus().as("input");
cy.wait("@search_link");
cy.get("@input").type("test@erpnext.com", { delay: 100 });
cy.wait("@search_link");
cy.get(".frappe-control[data-fieldname=link] ul").should("be.visible");
cy.get(".frappe-control[data-fieldname=link] input").type("{enter}", { delay: 100 });
cy.get(".frappe-control[data-fieldname=link] input").blur();
cy.get("@dialog").then((dialog) => {
let field = dialog.get_field("link");
let value = field.get_value();
let label = field.get_label_value();
expect(value).to.eq('test@erpnext.com');
expect(label).to.eq('translatedtest@erpnext.com');
expect(value).to.eq("test@erpnext.com");
expect(label).to.eq("translatedtest@erpnext.com");
});
});
});

View File

@ -7,12 +7,9 @@ context("Control Markdown Editor", () => {
it("should allow inserting images by drag and drop", () => {
cy.visit("/app/web-page/new");
cy.fill_field("content_type", "Markdown", "Select");
cy.get_field("main_section_md", "Markdown Editor").attachFile(
"sample_image.jpg",
{
subjectType: "drag-n-drop"
}
);
cy.get_field("main_section_md", "Markdown Editor").attachFile("sample_image.jpg", {
subjectType: "drag-n-drop",
});
cy.click_modal_primary_button("Upload");
cy.get_field("main_section_md", "Markdown Editor").should(
"contain",

View File

@ -1,4 +1,4 @@
import doctype_with_phone from '../fixtures/doctype_with_phone';
import doctype_with_phone from "../fixtures/doctype_with_phone";
context("Control Phone", () => {
before(() => {
@ -9,10 +9,12 @@ context("Control Phone", () => {
function get_dialog_with_phone() {
return cy.dialog({
title: "Phone",
fields: [{
"fieldname": "phone",
"fieldtype": "Phone",
}]
fields: [
{
fieldname: "phone",
fieldtype: "Phone",
},
],
});
}
@ -27,18 +29,16 @@ context("Control Phone", () => {
let phone_number = "9312672712";
cy.get(".selected-phone > img").click().first();
cy.get_field("phone")
.first()
.click({multiple: true});
cy.get_field("phone").first().click({ multiple: true });
cy.get(".frappe-control[data-fieldname=phone]")
.findByRole("textbox")
.first()
.type(phone_number, {force: true});
.type(phone_number, { force: true });
cy.get_field("phone").first().should("have.value", phone_number);
cy.get_field("phone").first().blur({force: true});
cy.get_field("phone").first().blur({ force: true });
cy.wait(100);
cy.get("@dialog").then(dialog => {
cy.get("@dialog").then((dialog) => {
let value = dialog.get_value("phone");
expect(value).to.equal("+91-" + phone_number);
});
@ -48,10 +48,12 @@ context("Control Phone", () => {
let search_text = "india";
cy.get(".selected-phone").click().first();
cy.get(".phone-picker").findByRole("searchbox").click().type(search_text);
cy.get(".phone-section .phone-wrapper:not(.hidden)").then(i => {
cy.get(`.phone-section .phone-wrapper[id*="${search_text.toLowerCase()}"]`).then(countries => {
expect(i.length).to.equal(countries.length);
});
cy.get(".phone-section .phone-wrapper:not(.hidden)").then((i) => {
cy.get(`.phone-section .phone-wrapper[id*="${search_text.toLowerCase()}"]`).then(
(countries) => {
expect(i.length).to.equal(countries.length);
}
);
});
cy.get(".phone-picker").findByRole("searchbox").clear().blur();

View File

@ -1,56 +1,54 @@
context('Control Rating', () => {
context("Control Rating", () => {
before(() => {
cy.login();
cy.visit('/app/website');
cy.visit("/app/website");
});
function get_dialog_with_rating() {
return cy.dialog({
title: 'Rating',
fields: [{
'fieldname': 'rate',
'fieldtype': 'Rating',
'options': 7
}]
title: "Rating",
fields: [
{
fieldname: "rate",
fieldtype: "Rating",
options: 7,
},
],
});
}
it('click on the star rating to record value', () => {
get_dialog_with_rating().as('dialog');
it("click on the star rating to record value", () => {
get_dialog_with_rating().as("dialog");
cy.get('div.rating')
.children('svg')
.find('.right-half')
cy.get("div.rating")
.children("svg")
.find(".right-half")
.first()
.click()
.should('have.class', 'star-click');
cy.get('@dialog').then(dialog => {
var value = dialog.get_value('rate');
expect(value).to.equal(1/7);
.should("have.class", "star-click");
cy.get("@dialog").then((dialog) => {
var value = dialog.get_value("rate");
expect(value).to.equal(1 / 7);
dialog.hide();
});
});
it('hover on the star', () => {
it("hover on the star", () => {
get_dialog_with_rating();
cy.get('div.rating')
.children('svg')
.find('.right-half')
cy.get("div.rating")
.children("svg")
.find(".right-half")
.first()
.invoke('trigger', 'mouseenter')
.should('have.class', 'star-hover')
.invoke('trigger', 'mouseleave')
.should('not.have.class', 'star-hover');
.invoke("trigger", "mouseenter")
.should("have.class", "star-hover")
.invoke("trigger", "mouseleave")
.should("not.have.class", "star-hover");
});
it('check number of stars in rating', () => {
it("check number of stars in rating", () => {
get_dialog_with_rating();
cy.get('div.rating')
.first()
.children('svg')
.should('have.length', 7);
cy.get("div.rating").first().children("svg").should("have.length", 7);
});
});

View File

@ -1,37 +1,40 @@
context('Control Select', () => {
context("Control Select", () => {
before(() => {
cy.login();
cy.visit('/app/website');
cy.visit("/app/website");
});
function get_dialog_with_select() {
return cy.dialog({
title: 'Select',
fields: [{
'fieldname': 'select_control',
'fieldtype': 'Select',
'placeholder': 'Select an Option',
'options': ['', 'Option 1', 'Option 2', 'Option 2'],
}]
title: "Select",
fields: [
{
fieldname: "select_control",
fieldtype: "Select",
placeholder: "Select an Option",
options: ["", "Option 1", "Option 2", "Option 2"],
},
],
});
}
it('toggles placholder on clicking an option', () => {
get_dialog_with_select().as('dialog');
it("toggles placholder on clicking an option", () => {
get_dialog_with_select().as("dialog");
cy.get('.frappe-control[data-fieldname=select_control] .control-input').as('control');
cy.get('.frappe-control[data-fieldname=select_control] .control-input select').as('select');
cy.get('@control').get('.select-icon').should('exist');
cy.get('@control').get('.placeholder').should('have.css', 'display', 'block');
cy.get('@select').select('Option 1');
cy.findByDisplayValue('Option 1').should('exist');
cy.get('@control').get('.placeholder').should('have.css', 'display', 'none');
cy.get('@select').invoke('val', '');
cy.findByDisplayValue('Option 1').should('not.exist');
cy.get('@control').get('.placeholder').should('have.css', 'display', 'block');
cy.get(".frappe-control[data-fieldname=select_control] .control-input").as("control");
cy.get(".frappe-control[data-fieldname=select_control] .control-input select").as(
"select"
);
cy.get("@control").get(".select-icon").should("exist");
cy.get("@control").get(".placeholder").should("have.css", "display", "block");
cy.get("@select").select("Option 1");
cy.findByDisplayValue("Option 1").should("exist");
cy.get("@control").get(".placeholder").should("have.css", "display", "none");
cy.get("@select").invoke("val", "");
cy.findByDisplayValue("Option 1").should("not.exist");
cy.get("@control").get(".placeholder").should("have.css", "display", "block");
cy.get('@dialog').then(dialog => {
cy.get("@dialog").then((dialog) => {
dialog.hide();
});
});

View File

@ -31,10 +31,7 @@ const check_button_count = (label, group = "TestGroup") => {
.should("be.visible");
//reset viewport
cy.viewport(
Cypress.config("viewportWidth"),
Cypress.config("viewportHeight")
);
cy.viewport(Cypress.config("viewportWidth"), Cypress.config("viewportHeight"));
};
describe(

View File

@ -1,19 +1,19 @@
context('Customize Form', () => {
context("Customize Form", () => {
before(() => {
cy.login();
cy.visit('/app/customize-form');
cy.visit("/app/customize-form");
});
it('Changing to naming rule should update autoname', () => {
it("Changing to naming rule should update autoname", () => {
cy.fill_field("doc_type", "ToDo", "Link").blur();
cy.click_form_section("Naming");
const naming_rule_default_autoname_map = {
"Set by user": "prompt",
"By fieldname": "field:",
'By "Naming Series" field': "naming_series:",
"Expression": "format:",
Expression: "format:",
"Expression (old style)": "",
"Random": "hash",
"By script": ""
Random: "hash",
"By script": "",
};
Cypress._.forOwn(naming_rule_default_autoname_map, (value, naming_rule) => {
cy.fill_field("naming_rule", naming_rule, "Select");

View File

@ -1,22 +1,22 @@
context('Dashboard Chart', () => {
context("Dashboard Chart", () => {
before(() => {
cy.login();
cy.visit('/app/website');
cy.visit("/app/website");
});
it('Check filter populate for child table doctype', () => {
cy.visit('/app/dashboard-chart/new-dashboard-chart-1');
cy.get('[data-fieldname="parent_document_type"]').should('have.css', 'display', 'none');
it("Check filter populate for child table doctype", () => {
cy.visit("/app/dashboard-chart/new-dashboard-chart-1");
cy.get('[data-fieldname="parent_document_type"]').should("have.css", "display", "none");
cy.get_field('document_type', 'Link');
cy.fill_field('document_type', 'Workspace Link', 'Link').focus().blur();
cy.get_field('document_type', 'Link').should('have.value', 'Workspace Link');
cy.get_field("document_type", "Link");
cy.fill_field("document_type", "Workspace Link", "Link").focus().blur();
cy.get_field("document_type", "Link").should("have.value", "Workspace Link");
cy.fill_field('chart_name', 'Test Chart', 'Data');
cy.fill_field("chart_name", "Test Chart", "Data");
cy.get('[data-fieldname="filters_json"]').click().wait(200);
cy.get('.modal-body .filter-action-buttons .add-filter').click();
cy.get('.modal-body .fieldname-select-area').click();
cy.get('.modal-actions .btn-modal-close').click();
cy.get(".modal-body .filter-action-buttons .add-filter").click();
cy.get(".modal-body .fieldname-select-area").click();
cy.get(".modal-actions .btn-modal-close").click();
});
});
});

View File

@ -1,91 +1,94 @@
import doctype_with_child_table from '../fixtures/doctype_with_child_table';
import child_table_doctype from '../fixtures/child_table_doctype';
import child_table_doctype_1 from '../fixtures/child_table_doctype_1';
import doctype_to_link from '../fixtures/doctype_to_link';
import doctype_with_child_table from "../fixtures/doctype_with_child_table";
import child_table_doctype from "../fixtures/child_table_doctype";
import child_table_doctype_1 from "../fixtures/child_table_doctype_1";
import doctype_to_link from "../fixtures/doctype_to_link";
const doctype_to_link_name = doctype_to_link.name;
const child_table_doctype_name = child_table_doctype.name;
context('Dashboard links', () => {
context("Dashboard links", () => {
before(() => {
cy.visit('/login');
cy.visit("/login");
cy.login();
cy.insert_doc('DocType', child_table_doctype, true);
cy.insert_doc('DocType', child_table_doctype_1, true);
cy.insert_doc('DocType', doctype_with_child_table, true);
cy.insert_doc('DocType', doctype_to_link, true);
return cy.window().its('frappe').then(frappe => {
return frappe.xcall("frappe.tests.ui_test_helpers.update_child_table", {
name: child_table_doctype_name
cy.insert_doc("DocType", child_table_doctype, true);
cy.insert_doc("DocType", child_table_doctype_1, true);
cy.insert_doc("DocType", doctype_with_child_table, true);
cy.insert_doc("DocType", doctype_to_link, true);
return cy
.window()
.its("frappe")
.then((frappe) => {
return frappe.xcall("frappe.tests.ui_test_helpers.update_child_table", {
name: child_table_doctype_name,
});
});
});
});
it('Adding a new contact, checking for the counter on the dashboard and deleting the created contact', () => {
cy.visit('/app/contact');
it("Adding a new contact, checking for the counter on the dashboard and deleting the created contact", () => {
cy.visit("/app/contact");
cy.clear_filters();
cy.visit('/app/user');
cy.get('.list-row-col > .level-item > .ellipsis').eq(0).click({ force: true });
cy.visit("/app/user");
cy.get(".list-row-col > .level-item > .ellipsis").eq(0).click({ force: true });
//To check if initially the dashboard contains only the "Contact" link and there is no counter
cy.get('[data-doctype="Contact"]').should('contain', 'Contact');
cy.get('[data-doctype="Contact"]').should("contain", "Contact");
//Adding a new contact
cy.get('.document-link-badge[data-doctype="Contact"]').click();
cy.wait(300);
cy.findByRole('button', {name: 'Add Contact'}).should('be.visible');
cy.findByRole('button', {name: 'Add Contact'}).click();
cy.get('[data-doctype="Contact"][data-fieldname="first_name"]').type('Admin');
cy.findByRole('button', {name: 'Save'}).click();
cy.visit('/app/user');
cy.get('.list-row-col > .level-item > .ellipsis').eq(0).click({ force: true });
cy.findByRole("button", { name: "Add Contact" }).should("be.visible");
cy.findByRole("button", { name: "Add Contact" }).click();
cy.get('[data-doctype="Contact"][data-fieldname="first_name"]').type("Admin");
cy.findByRole("button", { name: "Save" }).click();
cy.visit("/app/user");
cy.get(".list-row-col > .level-item > .ellipsis").eq(0).click({ force: true });
//To check if the counter for contact doc is "1" after adding the contact
cy.get('[data-doctype="Contact"] > .count').should('contain', '1');
cy.get('[data-doctype="Contact"]').contains('Contact').click();
cy.get('[data-doctype="Contact"] > .count').should("contain", "1");
cy.get('[data-doctype="Contact"]').contains("Contact").click();
//Deleting the newly created contact
cy.visit('/app/contact');
cy.get('.list-subject > .select-like > .list-row-checkbox').eq(0).click({ force: true });
cy.findByRole('button', {name: 'Actions'}).click();
cy.visit("/app/contact");
cy.get(".list-subject > .select-like > .list-row-checkbox").eq(0).click({ force: true });
cy.findByRole("button", { name: "Actions" }).click();
cy.get('.actions-btn-group [data-label="Delete"]').click();
cy.findByRole('button', {name: 'Yes'}).click({delay: 700});
cy.findByRole("button", { name: "Yes" }).click({ delay: 700 });
//To check if the counter from the "Contact" doc link is removed
cy.wait(700);
cy.visit('/app/user');
cy.get('.list-row-col > .level-item > .ellipsis').eq(0).click({ force: true });
cy.get('[data-doctype="Contact"]').should('contain', 'Contact');
cy.visit("/app/user");
cy.get(".list-row-col > .level-item > .ellipsis").eq(0).click({ force: true });
cy.get('[data-doctype="Contact"]').should("contain", "Contact");
});
it('Report link in dashboard', () => {
cy.visit('/app/user');
cy.visit('/app/user/Administrator');
cy.get('[data-doctype="Contact"]').should('contain', 'Contact');
cy.findByText('Connections');
it("Report link in dashboard", () => {
cy.visit("/app/user");
cy.visit("/app/user/Administrator");
cy.get('[data-doctype="Contact"]').should("contain", "Contact");
cy.findByText("Connections");
cy.window()
.its('cur_frm')
.then(cur_frm => {
.its("cur_frm")
.then((cur_frm) => {
cur_frm.dashboard.data.reports = [
{
'label': 'Reports',
'items': ['Website Analytics']
}
label: "Reports",
items: ["Website Analytics"],
},
];
cur_frm.dashboard.render_report_links();
cy.get('[data-report="Website Analytics"]').contains('Website Analytics').click();
cy.findByText('Website Analytics');
cy.get('[data-report="Website Analytics"]').contains("Website Analytics").click();
cy.findByText("Website Analytics");
});
});
it('check if child table is populated with linked field on creation from dashboard link', () => {
it("check if child table is populated with linked field on creation from dashboard link", () => {
cy.new_form(doctype_to_link_name);
cy.fill_field("title", "Test Linking");
cy.findByRole("button", {name: "Save"}).click();
cy.findByRole("button", { name: "Save" }).click();
cy.get('.document-link .btn-new').click();
cy.get('.frappe-control[data-fieldname="child_table"] .rows .data-row .col[data-fieldname="doctype_to_link"]')
.should('contain.text', 'Test Linking');
cy.get(".document-link .btn-new").click();
cy.get(
'.frappe-control[data-fieldname="child_table"] .rows .data-row .col[data-fieldname="doctype_to_link"]'
).should("contain.text", "Test Linking");
});
});

View File

@ -1,43 +1,45 @@
import data_field_validation_doctype from '../fixtures/data_field_validation_doctype';
import data_field_validation_doctype from "../fixtures/data_field_validation_doctype";
const doctype_name = data_field_validation_doctype.name;
context('Data Field Input Validation in New Form', () => {
context("Data Field Input Validation in New Form", () => {
before(() => {
cy.login();
cy.visit('/app/website');
return cy.insert_doc('DocType', data_field_validation_doctype, true);
cy.visit("/app/website");
return cy.insert_doc("DocType", data_field_validation_doctype, true);
});
function validateField(fieldname, invalid_value, valid_value) {
// Invalid, should have has-error class
cy.get_field(fieldname).clear().type(invalid_value).blur();
cy.get(`.frappe-control[data-fieldname="${fieldname}"]`).should('have.class', 'has-error');
cy.get(`.frappe-control[data-fieldname="${fieldname}"]`).should("have.class", "has-error");
// Valid value, should not have has-error class
cy.get_field(fieldname).clear().type(valid_value);
cy.get(`.frappe-control[data-fieldname="${fieldname}"]`).should('not.have.class', 'has-error');
cy.get(`.frappe-control[data-fieldname="${fieldname}"]`).should(
"not.have.class",
"has-error"
);
}
describe('Data Field Options', () => {
it('should validate email address', () => {
describe("Data Field Options", () => {
it("should validate email address", () => {
cy.new_form(doctype_name);
validateField('email', 'captian', 'hello@test.com');
validateField("email", "captian", "hello@test.com");
});
it('should validate URL', () => {
validateField('url', 'jkl', 'https://frappe.io');
validateField('url', 'abcd.com', 'http://google.com/home');
validateField('url', '&&http://google.uae', 'gopher://frappe.io');
validateField('url', 'ftt2:://google.in?q=news', 'ftps2://frappe.io/__/#home');
validateField('url', 'ftt2://', 'ntps://localhost'); // For intranet URLs
it("should validate URL", () => {
validateField("url", "jkl", "https://frappe.io");
validateField("url", "abcd.com", "http://google.com/home");
validateField("url", "&&http://google.uae", "gopher://frappe.io");
validateField("url", "ftt2:://google.in?q=news", "ftps2://frappe.io/__/#home");
validateField("url", "ftt2://", "ntps://localhost"); // For intranet URLs
});
it('should validate phone number', () => {
validateField('phone', 'america', '89787878');
it("should validate phone number", () => {
validateField("phone", "america", "89787878");
});
it('should validate name', () => {
validateField('person_name', ' 777Hello', 'James Bond');
it("should validate name", () => {
validateField("person_name", " 777Hello", "James Bond");
});
});
});
});

View File

@ -1,53 +1,52 @@
import datetime_doctype from '../fixtures/datetime_doctype';
import datetime_doctype from "../fixtures/datetime_doctype";
const doctype_name = datetime_doctype.name;
context('Control Date, Time and DateTime', () => {
context("Control Date, Time and DateTime", () => {
before(() => {
cy.login();
cy.visit('/app/website');
return cy.insert_doc('DocType', datetime_doctype, true);
cy.visit("/app/website");
return cy.insert_doc("DocType", datetime_doctype, true);
});
describe('Date formats', () => {
describe("Date formats", () => {
let date_formats = [
{
date_format: 'dd-mm-yyyy',
date_format: "dd-mm-yyyy",
part: 2,
length: 4,
separator: '-'
separator: "-",
},
{
date_format: 'mm/dd/yyyy',
date_format: "mm/dd/yyyy",
part: 0,
length: 2,
separator: '/'
}
separator: "/",
},
];
date_formats.forEach(d => {
it('test date format ' + d.date_format, () => {
cy.set_value('System Settings', 'System Settings', {
date_format: d.date_format
date_formats.forEach((d) => {
it("test date format " + d.date_format, () => {
cy.set_value("System Settings", "System Settings", {
date_format: d.date_format,
});
cy.window()
.its('frappe')
.then(frappe => {
.its("frappe")
.then((frappe) => {
// update sys_defaults value to avoid a reload
frappe.sys_defaults.date_format = d.date_format;
});
cy.new_form(doctype_name);
cy.get('.form-control[data-fieldname=date]').focus();
cy.get('.datepickers-container .datepicker.active')
.should('be.visible');
cy.get(".form-control[data-fieldname=date]").focus();
cy.get(".datepickers-container .datepicker.active").should("be.visible");
cy.get(
'.datepickers-container .datepicker.active .datepicker--cell-day.-current-'
".datepickers-container .datepicker.active .datepicker--cell-day.-current-"
).click({ force: true });
cy.window()
.its('cur_frm')
.then(cur_frm => {
let formatted_value = cur_frm.get_field('date').input.value;
.its("cur_frm")
.then((cur_frm) => {
let formatted_value = cur_frm.get_field("date").input.value;
let parts = formatted_value.split(d.separator);
expect(parts[d.part].length).to.equal(d.length);
});
@ -55,74 +54,72 @@ context('Control Date, Time and DateTime', () => {
});
});
describe('Time formats', () => {
describe("Time formats", () => {
let time_formats = [
{
time_format: 'HH:mm:ss',
value: ' 11:00:12',
match_value: '11:00:12'
time_format: "HH:mm:ss",
value: " 11:00:12",
match_value: "11:00:12",
},
{
time_format: 'HH:mm',
value: ' 11:00:12',
match_value: '11:00'
}
time_format: "HH:mm",
value: " 11:00:12",
match_value: "11:00",
},
];
time_formats.forEach(d => {
it('test time format ' + d.time_format, () => {
cy.set_value('System Settings', 'System Settings', {
time_format: d.time_format
time_formats.forEach((d) => {
it("test time format " + d.time_format, () => {
cy.set_value("System Settings", "System Settings", {
time_format: d.time_format,
});
cy.window()
.its('frappe')
.then(frappe => {
.its("frappe")
.then((frappe) => {
frappe.sys_defaults.time_format = d.time_format;
});
cy.new_form(doctype_name);
cy.fill_field('time', d.value, 'Time').blur();
cy.get_field('time').should('have.value', d.match_value);
cy.fill_field("time", d.value, "Time").blur();
cy.get_field("time").should("have.value", d.match_value);
});
});
});
describe('DateTime formats', () => {
describe("DateTime formats", () => {
let datetime_formats = [
{
date_format: 'dd.mm.yyyy',
time_format: 'HH:mm:ss',
value: ' 02.12.2019 11:00:12',
doc_value: '2019-12-02 00:30:12', // system timezone (America/New_York)
input_value: '02.12.2019 11:00:12' // admin timezone (Asia/Kolkata)
date_format: "dd.mm.yyyy",
time_format: "HH:mm:ss",
value: " 02.12.2019 11:00:12",
doc_value: "2019-12-02 00:30:12", // system timezone (America/New_York)
input_value: "02.12.2019 11:00:12", // admin timezone (Asia/Kolkata)
},
{
date_format: 'mm-dd-yyyy',
time_format: 'HH:mm',
value: ' 12-02-2019 11:00:00',
doc_value: '2019-12-02 00:30:00', // system timezone (America/New_York)
input_value: '12-02-2019 11:00' // admin timezone (Asia/Kolkata)
}
date_format: "mm-dd-yyyy",
time_format: "HH:mm",
value: " 12-02-2019 11:00:00",
doc_value: "2019-12-02 00:30:00", // system timezone (America/New_York)
input_value: "12-02-2019 11:00", // admin timezone (Asia/Kolkata)
},
];
datetime_formats.forEach(d => {
datetime_formats.forEach((d) => {
it(`test datetime format ${d.date_format} ${d.time_format}`, () => {
cy.set_value('System Settings', 'System Settings', {
cy.set_value("System Settings", "System Settings", {
date_format: d.date_format,
time_format: d.time_format
time_format: d.time_format,
});
cy.window()
.its('frappe')
.then(frappe => {
.its("frappe")
.then((frappe) => {
frappe.sys_defaults.date_format = d.date_format;
frappe.sys_defaults.time_format = d.time_format;
});
cy.new_form(doctype_name);
cy.fill_field('datetime', d.value, 'Datetime').blur();
cy.get_field('datetime').should('have.value', d.input_value);
cy.fill_field("datetime", d.value, "Datetime").blur();
cy.get_field("datetime").should("have.value", d.input_value);
cy.window()
.its('cur_frm.doc.datetime')
.should('eq', d.doc_value);
cy.window().its("cur_frm.doc.datetime").should("eq", d.doc_value);
});
});
});

View File

@ -16,4 +16,4 @@
// cy.get('.indicator-pill').should('contain', 'Open').should('have.class', 'red');
// });
// });
// });
// });

View File

@ -1,135 +1,152 @@
context('Depends On', () => {
context("Depends On", () => {
before(() => {
cy.login();
cy.visit('/app/website');
return cy.window().its('frappe').then(frappe => {
return frappe.xcall('frappe.tests.ui_test_helpers.create_child_doctype', {
name: 'Child Test Depends On',
fields: [
{
"label": "Child Test Field",
"fieldname": "child_test_field",
"fieldtype": "Data",
"in_list_view": 1,
},
{
"label": "Child Dependant Field",
"fieldname": "child_dependant_field",
"fieldtype": "Data",
"in_list_view": 1,
},
{
"label": "Child Display Dependant Field",
"fieldname": "child_display_dependant_field",
"fieldtype": "Data",
"in_list_view": 1,
},
]
cy.visit("/app/website");
return cy
.window()
.its("frappe")
.then((frappe) => {
return frappe.xcall("frappe.tests.ui_test_helpers.create_child_doctype", {
name: "Child Test Depends On",
fields: [
{
label: "Child Test Field",
fieldname: "child_test_field",
fieldtype: "Data",
in_list_view: 1,
},
{
label: "Child Dependant Field",
fieldname: "child_dependant_field",
fieldtype: "Data",
in_list_view: 1,
},
{
label: "Child Display Dependant Field",
fieldname: "child_display_dependant_field",
fieldtype: "Data",
in_list_view: 1,
},
],
});
})
.then((frappe) => {
return frappe.xcall("frappe.tests.ui_test_helpers.create_doctype", {
name: "Test Depends On",
fields: [
{
label: "Test Field",
fieldname: "test_field",
fieldtype: "Data",
},
{
label: "Dependant Field",
fieldname: "dependant_field",
fieldtype: "Data",
mandatory_depends_on: "eval:doc.test_field=='Some Value'",
read_only_depends_on: "eval:doc.test_field=='Some Other Value'",
},
{
label: "Display Dependant Field",
fieldname: "display_dependant_field",
fieldtype: "Data",
depends_on: "eval:doc.test_field=='Value'",
},
{
label: "Child Test Depends On Field",
fieldname: "child_test_depends_on_field",
fieldtype: "Table",
read_only_depends_on: "eval:doc.test_field=='Some Other Value'",
options: "Child Test Depends On",
},
{
label: "Dependent Tab",
fieldname: "dependent_tab",
fieldtype: "Tab Break",
depends_on: "eval:doc.test_field=='Show Tab'",
},
{
fieldname: "tab_section",
fieldtype: "Section Break",
},
{
label: "Field in Tab",
fieldname: "field_in_tab",
fieldtype: "Data",
},
],
});
});
}).then(frappe => {
return frappe.xcall('frappe.tests.ui_test_helpers.create_doctype', {
name: 'Test Depends On',
fields: [
{
"label": "Test Field",
"fieldname": "test_field",
"fieldtype": "Data",
},
{
"label": "Dependant Field",
"fieldname": "dependant_field",
"fieldtype": "Data",
"mandatory_depends_on": "eval:doc.test_field=='Some Value'",
"read_only_depends_on": "eval:doc.test_field=='Some Other Value'",
},
{
"label": "Display Dependant Field",
"fieldname": "display_dependant_field",
"fieldtype": "Data",
'depends_on': "eval:doc.test_field=='Value'"
},
{
"label": "Child Test Depends On Field",
"fieldname": "child_test_depends_on_field",
"fieldtype": "Table",
'read_only_depends_on': "eval:doc.test_field=='Some Other Value'",
'options': "Child Test Depends On"
},
{
"label": "Dependent Tab",
"fieldname": "dependent_tab",
"fieldtype": "Tab Break",
"depends_on": "eval:doc.test_field=='Show Tab'"
},
{
"fieldname": "tab_section",
"fieldtype": "Section Break",
},
{
"label": "Field in Tab",
"fieldname": "field_in_tab",
"fieldtype": "Data",
}
]
});
});
});
it('should show the tab on other setting field value', () => {
cy.new_form('Test Depends On');
cy.fill_field('test_field', 'Show Tab');
cy.get('body').click();
cy.findByRole("tab", {name: "Dependent Tab"}).should('be.visible');
it("should show the tab on other setting field value", () => {
cy.new_form("Test Depends On");
cy.fill_field("test_field", "Show Tab");
cy.get("body").click();
cy.findByRole("tab", { name: "Dependent Tab" }).should("be.visible");
});
it('should set the field as mandatory depending on other fields value', () => {
cy.new_form('Test Depends On');
cy.fill_field('test_field', 'Some Value');
cy.findByRole('button', {name: 'Save'}).click();
cy.get('.msgprint-dialog .modal-title').contains('Missing Fields').should('be.visible');
it("should set the field as mandatory depending on other fields value", () => {
cy.new_form("Test Depends On");
cy.fill_field("test_field", "Some Value");
cy.findByRole("button", { name: "Save" }).click();
cy.get(".msgprint-dialog .modal-title").contains("Missing Fields").should("be.visible");
cy.hide_dialog();
cy.fill_field('test_field', 'Random value');
cy.findByRole('button', {name: 'Save'}).click();
cy.get('.msgprint-dialog .modal-title').contains('Missing Fields').should('not.be.visible');
cy.fill_field("test_field", "Random value");
cy.findByRole("button", { name: "Save" }).click();
cy.get(".msgprint-dialog .modal-title")
.contains("Missing Fields")
.should("not.be.visible");
});
it('should set the field as read only depending on other fields value', () => {
cy.new_form('Test Depends On');
cy.fill_field('dependant_field', 'Some Value');
cy.fill_field('test_field', 'Some Other Value');
cy.get('body').click();
cy.get('.control-input [data-fieldname="dependant_field"]').should('be.disabled');
cy.fill_field('test_field', 'Random Value');
cy.get('body').click();
cy.get('.control-input [data-fieldname="dependant_field"]').should('not.be.disabled');
it("should set the field as read only depending on other fields value", () => {
cy.new_form("Test Depends On");
cy.fill_field("dependant_field", "Some Value");
cy.fill_field("test_field", "Some Other Value");
cy.get("body").click();
cy.get('.control-input [data-fieldname="dependant_field"]').should("be.disabled");
cy.fill_field("test_field", "Random Value");
cy.get("body").click();
cy.get('.control-input [data-fieldname="dependant_field"]').should("not.be.disabled");
});
it('should set the table and its fields as read only depending on other fields value', () => {
cy.new_form('Test Depends On');
cy.fill_field('dependant_field', 'Some Value');
it("should set the table and its fields as read only depending on other fields value", () => {
cy.new_form("Test Depends On");
cy.fill_field("dependant_field", "Some Value");
//cy.fill_field('test_field', 'Some Other Value');
cy.get('.frappe-control[data-fieldname="child_test_depends_on_field"]').as('table');
cy.get('@table').findByRole('button', {name: 'Add Row'}).click();
cy.get('@table').find('[data-idx="1"]').as('row1');
cy.get('@row1').find('.btn-open-row').click();
cy.get('@row1').find('.form-in-grid').as('row1-form_in_grid');
cy.get('.frappe-control[data-fieldname="child_test_depends_on_field"]').as("table");
cy.get("@table").findByRole("button", { name: "Add Row" }).click();
cy.get("@table").find('[data-idx="1"]').as("row1");
cy.get("@row1").find(".btn-open-row").click();
cy.get("@row1").find(".form-in-grid").as("row1-form_in_grid");
//cy.get('@row1-form_in_grid').find('')
cy.fill_table_field('child_test_depends_on_field', '1', 'child_test_field', 'Some Value');
cy.fill_table_field('child_test_depends_on_field', '1', 'child_dependant_field', 'Some Other Value');
cy.fill_table_field("child_test_depends_on_field", "1", "child_test_field", "Some Value");
cy.fill_table_field(
"child_test_depends_on_field",
"1",
"child_dependant_field",
"Some Other Value"
);
cy.get('@row1-form_in_grid').find('.grid-collapse-row').click();
cy.get("@row1-form_in_grid").find(".grid-collapse-row").click();
// set the table to read-only
cy.fill_field('test_field', 'Some Other Value');
cy.fill_field("test_field", "Some Other Value");
// grid row form fields should be read-only
cy.get('@row1').find('.btn-open-row').click();
cy.get("@row1").find(".btn-open-row").click();
cy.get('@row1-form_in_grid').find('.control-input [data-fieldname="child_test_field"]').should('be.disabled');
cy.get('@row1-form_in_grid').find('.control-input [data-fieldname="child_dependant_field"]').should('be.disabled');
cy.get("@row1-form_in_grid")
.find('.control-input [data-fieldname="child_test_field"]')
.should("be.disabled");
cy.get("@row1-form_in_grid")
.find('.control-input [data-fieldname="child_dependant_field"]')
.should("be.disabled");
});
it('should display the field depending on other fields value', () => {
cy.new_form('Test Depends On');
cy.get('.control-input [data-fieldname="display_dependant_field"]').should('not.be.visible');
it("should display the field depending on other fields value", () => {
cy.new_form("Test Depends On");
cy.get('.control-input [data-fieldname="display_dependant_field"]').should(
"not.be.visible"
);
cy.get('.control-input [data-fieldname="test_field"]').clear();
cy.fill_field('test_field', 'Value');
cy.get('body').click();
cy.get('.control-input [data-fieldname="display_dependant_field"]').should('be.visible');
cy.fill_field("test_field", "Value");
cy.get("body").click();
cy.get('.control-input [data-fieldname="display_dependant_field"]').should("be.visible");
});
});

View File

@ -1,79 +1,101 @@
context('Discussions', () => {
context("Discussions", () => {
before(() => {
cy.login();
cy.visit('/app');
return cy.window().its('frappe').then(frappe => {
return frappe.call('frappe.tests.ui_test_helpers.create_data_for_discussions');
});
cy.visit("/app");
return cy
.window()
.its("frappe")
.then((frappe) => {
return frappe.call("frappe.tests.ui_test_helpers.create_data_for_discussions");
});
});
const reply_through_modal = () => {
cy.visit('/test-page-discussions');
cy.visit("/test-page-discussions");
// Open the modal
cy.get('.reply').click();
cy.get(".reply").click();
cy.wait(500);
cy.get('.discussion-modal').should('be.visible');
cy.get(".discussion-modal").should("be.visible");
// Enter title
cy.get('.modal .topic-title').type('Discussion from tests')
.should('have.value', 'Discussion from tests');
cy.get(".modal .topic-title")
.type("Discussion from tests")
.should("have.value", "Discussion from tests");
// Enter comment
cy.get('.modal .comment-field')
.type('This is a discussion from the cypress ui tests.')
.should('have.value', 'This is a discussion from the cypress ui tests.');
cy.get(".modal .comment-field")
.type("This is a discussion from the cypress ui tests.")
.should("have.value", "This is a discussion from the cypress ui tests.");
// Submit
cy.get('.modal .submit-discussion').click();
cy.get(".modal .submit-discussion").click();
cy.wait(2000);
// Check if discussion is added to page and content is visible
cy.get('.sidebar-parent:first .discussion-topic-title').should('have.text', 'Discussion from tests');
cy.get('.discussion-on-page:visible').should('have.class', 'show');
cy.get('.discussion-on-page:visible .reply-card .reply-text')
.should('have.text', 'This is a discussion from the cypress ui tests.\n');
cy.get(".sidebar-parent:first .discussion-topic-title").should(
"have.text",
"Discussion from tests"
);
cy.get(".discussion-on-page:visible").should("have.class", "show");
cy.get(".discussion-on-page:visible .reply-card .reply-text").should(
"have.text",
"This is a discussion from the cypress ui tests.\n"
);
};
const reply_through_comment_box = () => {
cy.get('.discussion-form:visible .comment-field')
.type('This is a discussion from the cypress ui tests. \n\nThis comment was entered through the commentbox on the page.')
.should('have.value', 'This is a discussion from the cypress ui tests. \n\nThis comment was entered through the commentbox on the page.');
cy.get(".discussion-form:visible .comment-field")
.type(
"This is a discussion from the cypress ui tests. \n\nThis comment was entered through the commentbox on the page."
)
.should(
"have.value",
"This is a discussion from the cypress ui tests. \n\nThis comment was entered through the commentbox on the page."
);
cy.get('.discussion-form:visible .submit-discussion').click();
cy.get(".discussion-form:visible .submit-discussion").click();
cy.wait(3000);
cy.get('.discussion-on-page:visible').should('have.class', 'show');
cy.get('.discussion-on-page:visible').children(".reply-card").eq(1).find(".reply-text")
.should('have.text', 'This is a discussion from the cypress ui tests. \n\nThis comment was entered through the commentbox on the page.\n');
cy.get(".discussion-on-page:visible").should("have.class", "show");
cy.get(".discussion-on-page:visible")
.children(".reply-card")
.eq(1)
.find(".reply-text")
.should(
"have.text",
"This is a discussion from the cypress ui tests. \n\nThis comment was entered through the commentbox on the page.\n"
);
};
const cancel_and_clear_comment_box = () => {
cy.get('.discussion-form:visible .comment-field')
.type('This is a discussion from the cypress ui tests.')
.should('have.value', 'This is a discussion from the cypress ui tests.');
cy.get(".discussion-form:visible .comment-field")
.type("This is a discussion from the cypress ui tests.")
.should("have.value", "This is a discussion from the cypress ui tests.");
cy.get('.discussion-form:visible .cancel-comment').click();
cy.get('.discussion-form:visible .comment-field').should('have.value', '');
cy.get(".discussion-form:visible .cancel-comment").click();
cy.get(".discussion-form:visible .comment-field").should("have.value", "");
};
const single_thread_discussion = () => {
cy.visit('/test-single-thread');
cy.get('.discussions-sidebar').should('have.length', 0);
cy.get('.reply').should('have.length', 0);
cy.visit("/test-single-thread");
cy.get(".discussions-sidebar").should("have.length", 0);
cy.get(".reply").should("have.length", 0);
cy.get('.discussion-form:visible .comment-field')
.type('This comment is being made on a single thread discussion.')
.should('have.value', 'This comment is being made on a single thread discussion.');
cy.get(".discussion-form:visible .comment-field")
.type("This comment is being made on a single thread discussion.")
.should("have.value", "This comment is being made on a single thread discussion.");
cy.get('.discussion-form:visible .submit-discussion').click();
cy.get(".discussion-form:visible .submit-discussion").click();
cy.wait(3000);
cy.get('.discussion-on-page').children(".reply-card").eq(-1).find(".reply-text")
.should('have.text', 'This comment is being made on a single thread discussion.\n');
cy.get(".discussion-on-page")
.children(".reply-card")
.eq(-1)
.find(".reply-text")
.should("have.text", "This comment is being made on a single thread discussion.\n");
};
it('reply through modal', reply_through_modal);
it('reply through comment box', reply_through_comment_box);
it('cancel and clear comment box', cancel_and_clear_comment_box);
it('single thread discussion', single_thread_discussion);
it("reply through modal", reply_through_modal);
it("reply through comment box", reply_through_comment_box);
it("cancel and clear comment box", cancel_and_clear_comment_box);
it("single thread discussion", single_thread_discussion);
});

View File

@ -1,78 +1,82 @@
context('FileUploader', () => {
context("FileUploader", () => {
before(() => {
cy.login();
cy.visit('/app');
cy.visit("/app");
});
function open_upload_dialog() {
cy.window().its('frappe').then(frappe => {
new frappe.ui.FileUploader();
});
cy.window()
.its("frappe")
.then((frappe) => {
new frappe.ui.FileUploader();
});
}
it('upload dialog api works', () => {
it("upload dialog api works", () => {
open_upload_dialog();
cy.get_open_dialog().should('contain', 'Drag and drop files');
cy.get_open_dialog().should("contain", "Drag and drop files");
cy.hide_dialog();
});
it('should accept dropped files', () => {
it("should accept dropped files", () => {
open_upload_dialog();
cy.get_open_dialog().find('.file-upload-area').attachFile('example.json', {
subjectType: 'drag-n-drop',
cy.get_open_dialog().find(".file-upload-area").attachFile("example.json", {
subjectType: "drag-n-drop",
});
cy.get_open_dialog().find('.file-name').should('contain', 'example.json');
cy.intercept('POST', '/api/method/upload_file').as('upload_file');
cy.get_open_dialog().findByRole('button', {name: 'Upload'}).click();
cy.wait('@upload_file').its('response.statusCode').should('eq', 200);
cy.get('.modal:visible').should('not.exist');
cy.get_open_dialog().find(".file-name").should("contain", "example.json");
cy.intercept("POST", "/api/method/upload_file").as("upload_file");
cy.get_open_dialog().findByRole("button", { name: "Upload" }).click();
cy.wait("@upload_file").its("response.statusCode").should("eq", 200);
cy.get(".modal:visible").should("not.exist");
});
it('should accept uploaded files', () => {
it("should accept uploaded files", () => {
open_upload_dialog();
cy.get_open_dialog().findByRole('button', {name: 'Library'}).click();
cy.findByPlaceholderText('Search by filename or extension').type('example.json');
cy.get_open_dialog().findAllByText('example.json').first().click();
cy.intercept('POST', '/api/method/upload_file').as('upload_file');
cy.get_open_dialog().findByRole('button', {name: 'Upload'}).click();
cy.wait('@upload_file').its('response.body.message')
.should('have.property', 'file_name', 'example.json');
cy.get('.modal:visible').should('not.exist');
cy.get_open_dialog().findByRole("button", { name: "Library" }).click();
cy.findByPlaceholderText("Search by filename or extension").type("example.json");
cy.get_open_dialog().findAllByText("example.json").first().click();
cy.intercept("POST", "/api/method/upload_file").as("upload_file");
cy.get_open_dialog().findByRole("button", { name: "Upload" }).click();
cy.wait("@upload_file")
.its("response.body.message")
.should("have.property", "file_name", "example.json");
cy.get(".modal:visible").should("not.exist");
});
it('should accept web links', () => {
it("should accept web links", () => {
open_upload_dialog();
cy.get_open_dialog().findByRole('button', {name: 'Link'}).click();
cy.get_open_dialog().findByRole("button", { name: "Link" }).click();
cy.get_open_dialog()
.findByPlaceholderText('Attach a web link')
.type('https://github.com', { delay: 100, force: true });
cy.intercept('POST', '/api/method/upload_file').as('upload_file');
cy.get_open_dialog().findByRole('button', {name: 'Upload'}).click();
cy.wait('@upload_file').its('response.body.message')
.should('have.property', 'file_url', 'https://github.com');
cy.get('.modal:visible').should('not.exist');
.findByPlaceholderText("Attach a web link")
.type("https://github.com", { delay: 100, force: true });
cy.intercept("POST", "/api/method/upload_file").as("upload_file");
cy.get_open_dialog().findByRole("button", { name: "Upload" }).click();
cy.wait("@upload_file")
.its("response.body.message")
.should("have.property", "file_url", "https://github.com");
cy.get(".modal:visible").should("not.exist");
});
it('should allow cropping and optimization for valid images', () => {
it("should allow cropping and optimization for valid images", () => {
open_upload_dialog();
cy.get_open_dialog().find('.file-upload-area').attachFile('sample_image.jpg', {
subjectType: 'drag-n-drop',
cy.get_open_dialog().find(".file-upload-area").attachFile("sample_image.jpg", {
subjectType: "drag-n-drop",
});
cy.get_open_dialog().findAllByText('sample_image.jpg').should('exist');
cy.get_open_dialog().find('.btn-crop').first().click();
cy.get_open_dialog().findByRole('button', {name: 'Crop'}).click();
cy.get_open_dialog().findAllByRole('checkbox', {name: 'Optimize'}).should('exist');
cy.get_open_dialog().findAllByLabelText('Optimize').first().click();
cy.get_open_dialog().findAllByText("sample_image.jpg").should("exist");
cy.get_open_dialog().find(".btn-crop").first().click();
cy.get_open_dialog().findByRole("button", { name: "Crop" }).click();
cy.get_open_dialog().findAllByRole("checkbox", { name: "Optimize" }).should("exist");
cy.get_open_dialog().findAllByLabelText("Optimize").first().click();
cy.intercept('POST', '/api/method/upload_file').as('upload_file');
cy.get_open_dialog().findByRole('button', {name: 'Upload'}).click();
cy.wait('@upload_file').its('response.statusCode').should('eq', 200);
cy.get('.modal:visible').should('not.exist');
cy.intercept("POST", "/api/method/upload_file").as("upload_file");
cy.get_open_dialog().findByRole("button", { name: "Upload" }).click();
cy.wait("@upload_file").its("response.statusCode").should("eq", 200);
cy.get(".modal:visible").should("not.exist");
});
});

View File

@ -4,42 +4,48 @@ context("First Day of the Week", () => {
});
beforeEach(() => {
cy.visit('/app/system-settings');
cy.findByText('Date and Number Format').click();
cy.visit("/app/system-settings");
cy.findByText("Date and Number Format").click();
});
it("Date control starts with same day as selected in System Settings", () => {
cy.intercept('POST', '/api/method/frappe.core.doctype.system_settings.system_settings.load').as("load_settings");
cy.fill_field('first_day_of_the_week', 'Tuesday', 'Select');
cy.findByRole('button', {name: 'Save'}).click();
cy.intercept(
"POST",
"/api/method/frappe.core.doctype.system_settings.system_settings.load"
).as("load_settings");
cy.fill_field("first_day_of_the_week", "Tuesday", "Select");
cy.findByRole("button", { name: "Save" }).click();
cy.wait("@load_settings");
cy.dialog({
title: 'Date',
title: "Date",
fields: [
{
label: 'Date',
fieldname: 'date',
fieldtype: 'Date'
}
]
label: "Date",
fieldname: "date",
fieldtype: "Date",
},
],
});
cy.get_field('date').click();
cy.get('.datepicker--day-name').eq(0).should('have.text', 'Tu');
cy.get_field("date").click();
cy.get(".datepicker--day-name").eq(0).should("have.text", "Tu");
});
it("Calendar view starts with same day as selected in System Settings", () => {
cy.intercept('POST', '/api/method/frappe.core.doctype.system_settings.system_settings.load').as("load_settings");
cy.fill_field('first_day_of_the_week', 'Monday', 'Select');
cy.findByRole('button', {name: 'Save'}).click();
cy.intercept(
"POST",
"/api/method/frappe.core.doctype.system_settings.system_settings.load"
).as("load_settings");
cy.fill_field("first_day_of_the_week", "Monday", "Select");
cy.findByRole("button", { name: "Save" }).click();
cy.wait("@load_settings");
cy.visit("app/todo/view/calendar/default");
cy.get('.fc-day-header > span').eq(0).should('have.text', 'Mon');
cy.get(".fc-day-header > span").eq(0).should("have.text", "Mon");
});
after(() => {
cy.visit('/app/system-settings');
cy.findByText('Date and Number Format').click();
cy.fill_field('first_day_of_the_week', 'Sunday', 'Select');
cy.findByRole('button', {name: 'Save'}).click();
cy.visit("/app/system-settings");
cy.findByText("Date and Number Format").click();
cy.fill_field("first_day_of_the_week", "Sunday", "Select");
cy.findByRole("button", { name: "Save" }).click();
});
});
});

View File

@ -1,79 +1,85 @@
context('Folder Navigation', () => {
context("Folder Navigation", () => {
before(() => {
cy.visit('/login');
cy.visit("/login");
cy.login();
cy.visit('/app/file');
cy.visit("/app/file");
});
it('Adding Folders', () => {
it("Adding Folders", () => {
//Adding filter to go into the home folder
cy.get('.filter-selector > .btn').findByText('1 filter').click();
cy.findByRole('button', {name: 'Clear Filters'}).click();
cy.get('.filter-action-buttons > .text-muted').findByText('+ Add a Filter').click();
cy.get('.fieldname-select-area > .awesomplete > .form-control').type('Fol{enter}');
cy.get('.filter-field > .form-group > .link-field > .awesomplete > .input-with-feedback').type('Home{enter}');
cy.get('.filter-action-buttons > div > .btn-primary').findByText('Apply Filters').click();
cy.get(".filter-selector > .btn").findByText("1 filter").click();
cy.findByRole("button", { name: "Clear Filters" }).click();
cy.get(".filter-action-buttons > .text-muted").findByText("+ Add a Filter").click();
cy.get(".fieldname-select-area > .awesomplete > .form-control").type("Fol{enter}");
cy.get(
".filter-field > .form-group > .link-field > .awesomplete > .input-with-feedback"
).type("Home{enter}");
cy.get(".filter-action-buttons > div > .btn-primary").findByText("Apply Filters").click();
//Adding folder (Test Folder)
cy.click_menu_button("New Folder");
cy.fill_field('value', 'Test Folder');
cy.click_modal_primary_button('Create');
cy.fill_field("value", "Test Folder");
cy.click_modal_primary_button("Create");
});
it('Navigating the nested folders, checking if the URL formed is correct, checking if the added content in the child folder is correct', () => {
it("Navigating the nested folders, checking if the URL formed is correct, checking if the added content in the child folder is correct", () => {
//Navigating inside the Attachments folder
cy.get('[title="Attachments"] > span').click();
//To check if the URL formed after visiting the attachments folder is correct
cy.location('pathname').should('eq', '/app/file/view/home/Attachments');
cy.visit('/app/file/view/home/Attachments');
cy.location("pathname").should("eq", "/app/file/view/home/Attachments");
cy.visit("/app/file/view/home/Attachments");
//Adding folder inside the attachments folder
cy.click_menu_button("New Folder");
cy.fill_field('value', 'Test Folder');
cy.click_modal_primary_button('Create');
cy.fill_field("value", "Test Folder");
cy.click_modal_primary_button("Create");
//Navigating inside the added folder in the Attachments folder
cy.get('[title="Test Folder"] > span').click();
//To check if the URL is correct after visiting the Test Folder
cy.location('pathname').should('eq', '/app/file/view/home/Attachments/Test%20Folder');
cy.visit('/app/file/view/home/Attachments/Test%20Folder');
cy.location("pathname").should("eq", "/app/file/view/home/Attachments/Test%20Folder");
cy.visit("/app/file/view/home/Attachments/Test%20Folder");
//Adding a file inside the Test Folder
cy.findByRole('button', {name: 'Add File'}).eq(0).click({force: true});
cy.get('.file-uploader').findByText('Link').click();
cy.get('.input-group > .form-control').type('https://wallpaperplay.com/walls/full/8/2/b/72402.jpg');
cy.click_modal_primary_button('Upload');
cy.findByRole("button", { name: "Add File" }).eq(0).click({ force: true });
cy.get(".file-uploader").findByText("Link").click();
cy.get(".input-group > .form-control").type(
"https://wallpaperplay.com/walls/full/8/2/b/72402.jpg"
);
cy.click_modal_primary_button("Upload");
//To check if the added file is present in the Test Folder
cy.get('span.level-item > span').should('contain', 'Test Folder');
cy.get('.list-row-container').eq(0).should('contain.text', '72402.jpg');
cy.get('.list-row-checkbox').eq(0).click();
cy.get("span.level-item > span").should("contain", "Test Folder");
cy.get(".list-row-container").eq(0).should("contain.text", "72402.jpg");
cy.get(".list-row-checkbox").eq(0).click();
cy.intercept({
method: 'POST',
url: 'api/method/frappe.desk.reportview.delete_items'
}).as('file_deleted');
method: "POST",
url: "api/method/frappe.desk.reportview.delete_items",
}).as("file_deleted");
//Deleting the added file from the Test folder
cy.click_action_button("Delete");
cy.click_modal_primary_button('Yes');
cy.wait('@file_deleted');
cy.click_modal_primary_button("Yes");
cy.wait("@file_deleted");
//Deleting the Test Folder
cy.visit('/app/file/view/home/Attachments');
cy.get('.list-row-checkbox').eq(0).click();
cy.visit("/app/file/view/home/Attachments");
cy.get(".list-row-checkbox").eq(0).click();
cy.click_action_button("Delete");
cy.click_modal_primary_button('Yes');
cy.wait('@file_deleted');
cy.click_modal_primary_button("Yes");
cy.wait("@file_deleted");
});
it('Deleting Test Folder from the home', () => {
//Deleting the Test Folder added in the home directory
cy.visit('/app/file/view/home');
cy.get('.level-left > .list-subject > .file-select >.list-row-checkbox').eq(0).click({force: true, delay: 500});
it("Deleting Test Folder from the home", () => {
//Deleting the Test Folder added in the home directory
cy.visit("/app/file/view/home");
cy.get(".level-left > .list-subject > .file-select >.list-row-checkbox")
.eq(0)
.click({ force: true, delay: 500 });
cy.click_action_button("Delete");
cy.click_modal_primary_button('Yes');
cy.click_modal_primary_button("Yes");
});
});

View File

@ -1,107 +1,114 @@
context('Form', () => {
context("Form", () => {
before(() => {
cy.login();
cy.visit('/app/website');
return cy.window().its('frappe').then(frappe => {
return frappe.call("frappe.tests.ui_test_helpers.create_contact_records");
});
cy.visit("/app/website");
return cy
.window()
.its("frappe")
.then((frappe) => {
return frappe.call("frappe.tests.ui_test_helpers.create_contact_records");
});
});
it('create a new form', () => {
cy.visit('/app/todo/new');
cy.get_field('description', 'Text Editor').type('this is a test todo', {force: true}).wait(200);
cy.get('.page-title').should('contain', 'Not Saved');
it("create a new form", () => {
cy.visit("/app/todo/new");
cy.get_field("description", "Text Editor")
.type("this is a test todo", { force: true })
.wait(200);
cy.get(".page-title").should("contain", "Not Saved");
cy.intercept({
method: 'POST',
url: 'api/method/frappe.desk.form.save.savedocs'
}).as('form_save');
cy.get('.primary-action').click();
cy.wait('@form_save').its('response.statusCode').should('eq', 200);
method: "POST",
url: "api/method/frappe.desk.form.save.savedocs",
}).as("form_save");
cy.get(".primary-action").click();
cy.wait("@form_save").its("response.statusCode").should("eq", 200);
cy.go_to_list('ToDo');
cy.clear_filters()
cy.get('.page-head').findByTitle('To Do').should('exist');
cy.get('.list-row').should('contain', 'this is a test todo');
cy.go_to_list("ToDo");
cy.clear_filters();
cy.get(".page-head").findByTitle("To Do").should("exist");
cy.get(".list-row").should("contain", "this is a test todo");
});
it('navigates between documents with child table list filters applied', () => {
cy.visit('/app/contact');
it("navigates between documents with child table list filters applied", () => {
cy.visit("/app/contact");
cy.clear_filters();
cy.get('.standard-filter-section [data-fieldname="name"] input').type('Test Form Contact 3').blur();
cy.click_listview_row_item_with_text('Test Form Contact 3');
cy.get('.standard-filter-section [data-fieldname="name"] input')
.type("Test Form Contact 3")
.blur();
cy.click_listview_row_item_with_text("Test Form Contact 3");
cy.get('#page-Contact .page-head').findByTitle('Test Form Contact 3').should('exist');
cy.get('.prev-doc').should('be.visible').click();
cy.get('.msgprint-dialog .modal-body').contains('No further records').should('be.visible');
cy.get("#page-Contact .page-head").findByTitle("Test Form Contact 3").should("exist");
cy.get(".prev-doc").should("be.visible").click();
cy.get(".msgprint-dialog .modal-body").contains("No further records").should("be.visible");
cy.hide_dialog();
cy.get('#page-Contact .page-head').findByTitle('Test Form Contact 3').should('exist');
cy.get('.next-doc').should('be.visible').click();
cy.get('.msgprint-dialog .modal-body').contains('No further records').should('be.visible');
cy.get("#page-Contact .page-head").findByTitle("Test Form Contact 3").should("exist");
cy.get(".next-doc").should("be.visible").click();
cy.get(".msgprint-dialog .modal-body").contains("No further records").should("be.visible");
cy.hide_dialog();
cy.get('#page-Contact .page-head').findByTitle('Test Form Contact 3').should('exist');
cy.get("#page-Contact .page-head").findByTitle("Test Form Contact 3").should("exist");
// clear filters
cy.visit('/app/contact');
cy.visit("/app/contact");
cy.clear_filters();
});
it('validates behaviour of Data options validations in child table', () => {
it("validates behaviour of Data options validations in child table", () => {
// test email validations for set_invalid controller
let website_input = 'website.in';
let valid_email = 'user@email.com';
let expectBackgroundColor = 'rgb(255, 245, 245)';
let website_input = "website.in";
let valid_email = "user@email.com";
let expectBackgroundColor = "rgb(255, 245, 245)";
cy.visit('/app/contact/new');
cy.get('.frappe-control[data-fieldname="email_ids"]').as('table');
cy.get('@table').find('button.grid-add-row').click();
cy.get('@table').find('button.grid-add-row').click();
cy.get('@table').find('[data-idx="1"]').as('row1');
cy.get('@table').find('[data-idx="2"]').as('row2');
cy.get('@row1').click();
cy.get('@row1').find('input.input-with-feedback.form-control').as('email_input1');
cy.visit("/app/contact/new");
cy.get('.frappe-control[data-fieldname="email_ids"]').as("table");
cy.get("@table").find("button.grid-add-row").click();
cy.get("@table").find("button.grid-add-row").click();
cy.get("@table").find('[data-idx="1"]').as("row1");
cy.get("@table").find('[data-idx="2"]').as("row2");
cy.get("@row1").click();
cy.get("@row1").find("input.input-with-feedback.form-control").as("email_input1");
cy.get('@email_input1').type(website_input, { waitForAnimations: false });
cy.fill_field('company_name', 'Test Company');
cy.get("@email_input1").type(website_input, { waitForAnimations: false });
cy.fill_field("company_name", "Test Company");
cy.get('@row2').click();
cy.get('@row2').find('input.input-with-feedback.form-control').as('email_input2');
cy.get('@email_input2').type(valid_email, { waitForAnimations: false });
cy.get("@row2").click();
cy.get("@row2").find("input.input-with-feedback.form-control").as("email_input2");
cy.get("@email_input2").type(valid_email, { waitForAnimations: false });
cy.get('@row1').click();
cy.get('@email_input1').should($div => {
cy.get("@row1").click();
cy.get("@email_input1").should(($div) => {
const style = window.getComputedStyle($div[0]);
expect(style.backgroundColor).to.equal(expectBackgroundColor);
});
cy.get('@email_input1').should('have.class', 'invalid');
cy.get("@email_input1").should("have.class", "invalid");
cy.get('@row2').click();
cy.get('@email_input2').should('not.have.class', 'invalid');
cy.get("@row2").click();
cy.get("@email_input2").should("not.have.class", "invalid");
});
it('Shows version conflict warning', { scrollBehavior: false }, () => {
cy.visit('/app/todo');
it("Shows version conflict warning", { scrollBehavior: false }, () => {
cy.visit("/app/todo");
cy.insert_doc("ToDo", {"description": "old"}).then(doc => {
cy.insert_doc("ToDo", { description: "old" }).then((doc) => {
cy.visit(`/app/todo/${doc.name}`);
// make form dirty
cy.fill_field("status", "Cancelled", "Select");
// update doc using api - simulating parallel change by another user
cy.update_doc("ToDo", doc.name, {"status": "Closed"}).then(() => {
cy.findByRole("button", {name: "Refresh"}).click();
cy.update_doc("ToDo", doc.name, { status: "Closed" }).then(() => {
cy.findByRole("button", { name: "Refresh" }).click();
cy.get_field("status", "Select").should("have.value", "Closed");
})
})
});
});
});
it('let user undo/redo field value changes', { scrollBehavior: false }, () => {
it("let user undo/redo field value changes", { scrollBehavior: false }, () => {
const jump_to_field = (field_label) => {
cy.get("body")
.type("{esc}") // lose focus if any
.type("{ctrl+j}") // jump to field
.type("{esc}") // lose focus if any
.type("{ctrl+j}") // jump to field
.type(field_label)
.wait(500)
.type("{enter}")
@ -111,16 +118,13 @@ context('Form', () => {
};
const type_value = (value) => {
cy.focused()
.clear()
.type(value)
.type("{esc}");
cy.focused().clear().type(value).type("{esc}");
};
const undo = () => cy.get("body").type("{esc}").type("{ctrl+z}").wait(500);
const redo = () => cy.get("body").type("{esc}").type("{ctrl+y}").wait(500);
cy.new_form('User');
cy.new_form("User");
jump_to_field("Email");
type_value("admin@example.com");
@ -132,7 +136,7 @@ context('Form', () => {
type_value("12-31-01");
jump_to_field("Send Welcome Email");
cy.focused().uncheck()
cy.focused().uncheck();
// make a mistake
jump_to_field("Username");
@ -140,19 +144,27 @@ context('Form', () => {
// undo behaviour
undo();
cy.get_field("username").should('have.value', 'admin42');
cy.get_field("username").should("have.value", "admin42");
// redo behaviour
redo();
cy.get_field("username").should('have.value', 'admin24');
cy.get_field("username").should("have.value", "admin24");
// undo everything & redo everything, ensure same values at the end
undo(); undo(); undo(); undo(); undo();
redo(); redo(); redo(); redo(); redo();
undo();
undo();
undo();
undo();
undo();
redo();
redo();
redo();
redo();
redo();
cy.get_field("username").should('have.value', 'admin24');
cy.get_field("email").should('have.value', 'admin@example.com');
cy.get_field("birth_date").should('have.value', '12-31-2001'); // parsed value
cy.get_field("send_welcome_email").should('not.be.checked');
cy.get_field("username").should("have.value", "admin24");
cy.get_field("email").should("have.value", "admin@example.com");
cy.get_field("birth_date").should("have.value", "12-31-2001"); // parsed value
cy.get_field("send_welcome_email").should("not.be.checked");
});
});

View File

@ -1,31 +1,30 @@
import doctype_with_tab_break from '../fixtures/doctype_with_tab_break';
import doctype_with_tab_break from "../fixtures/doctype_with_tab_break";
const doctype_name = doctype_with_tab_break.name;
context("Form Tab Break", () => {
before(() => {
cy.login();
cy.visit('/app/website');
return cy.insert_doc('DocType', doctype_with_tab_break, true);
cy.visit("/app/website");
return cy.insert_doc("DocType", doctype_with_tab_break, true);
});
it("Should switch tab and open correct tabs on validation error", () => {
cy.new_form(doctype_name);
// test tab switch
cy.findByRole("tab", {name: "Tab 2"}).click();
cy.findByRole("tab", { name: "Tab 2" }).click();
cy.findByText("Phone");
cy.findByRole("tab", {name: "Details"}).click();
cy.findByRole("tab", { name: "Details" }).click();
cy.findByText("Name");
// form should switch to the tab with un-filled mandatory field
cy.fill_field("username", "Test");
cy.findByRole("button", {name: "Save"}).click();
cy.findByRole("button", { name: "Save" }).click();
cy.findByText("Missing Fields");
cy.hide_dialog();
cy.findByText("Phone");
cy.fill_field("phone", "12345678");
cy.findByRole("button", {name: "Save"}).click();
cy.findByRole("button", { name: "Save" }).click();
// After save, first tab should have dashboard
cy.get(".form-tabs > .nav-item").eq(0).click();
cy.findByText("Connections");
});
});
});

View File

@ -1,88 +1,94 @@
context.skip('Form Tour', () => {
context.skip("Form Tour", () => {
before(() => {
cy.login();
cy.visit('/app');
return cy.window().its('frappe').then(frappe => {
return frappe.call("frappe.tests.ui_test_helpers.create_form_tour");
});
cy.visit("/app");
return cy
.window()
.its("frappe")
.then((frappe) => {
return frappe.call("frappe.tests.ui_test_helpers.create_form_tour");
});
});
const open_test_form_tour = () => {
cy.visit('/app/form-tour/Test Form Tour');
cy.findByRole('button', {name: 'Show Tour'}).should('be.visible').as('show_tour');
cy.get('@show_tour').click();
cy.visit("/app/form-tour/Test Form Tour");
cy.findByRole("button", { name: "Show Tour" }).should("be.visible").as("show_tour");
cy.get("@show_tour").click();
cy.wait(500);
cy.url().should('include', '/app/contact');
cy.url().should("include", "/app/contact");
};
it('jump to a form tour', open_test_form_tour);
it("jump to a form tour", open_test_form_tour);
it('navigates a form tour', () => {
it("navigates a form tour", () => {
open_test_form_tour();
cy.get('.frappe-driver').should('be.visible');
cy.get('.frappe-control[data-fieldname="first_name"]').as('first_name');
cy.get('@first_name').should('have.class', 'driver-highlighted-element');
cy.get('.frappe-driver').findByRole('button', {name: 'Next'}).as('next_btn');
cy.get(".frappe-driver").should("be.visible");
cy.get('.frappe-control[data-fieldname="first_name"]').as("first_name");
cy.get("@first_name").should("have.class", "driver-highlighted-element");
cy.get(".frappe-driver").findByRole("button", { name: "Next" }).as("next_btn");
// next btn shouldn't move to next step, if first name is not entered
cy.get('@next_btn').click();
cy.get("@next_btn").click();
cy.wait(500);
cy.get('@first_name').should('have.class', 'driver-highlighted-element');
cy.get("@first_name").should("have.class", "driver-highlighted-element");
// after filling the field, next step should be highlighted
cy.fill_field('first_name', 'Test Name', 'Data');
cy.fill_field("first_name", "Test Name", "Data");
cy.wait(500);
cy.get('@next_btn').click();
cy.get("@next_btn").click();
cy.wait(500);
// assert field is highlighted
cy.get('.frappe-control[data-fieldname="last_name"]').as('last_name');
cy.get('@last_name').should('have.class', 'driver-highlighted-element');
cy.get('.frappe-control[data-fieldname="last_name"]').as("last_name");
cy.get("@last_name").should("have.class", "driver-highlighted-element");
// after filling the field, next step should be highlighted
cy.fill_field('last_name', 'Test Last Name', 'Data');
cy.fill_field("last_name", "Test Last Name", "Data");
cy.wait(500);
cy.get('@next_btn').click();
cy.get("@next_btn").click();
cy.wait(500);
// assert field is highlighted
cy.get('.frappe-control[data-fieldname="phone_nos"]').as('phone_nos');
cy.get('@phone_nos').should('have.class', 'driver-highlighted-element');
cy.get('.frappe-control[data-fieldname="phone_nos"]').as("phone_nos");
cy.get("@phone_nos").should("have.class", "driver-highlighted-element");
// move to next step
cy.wait(500);
cy.get('@next_btn').click();
cy.get("@next_btn").click();
cy.wait(500);
// assert add row btn is highlighted
cy.get('@phone_nos').find('.grid-add-row').as('add_row');
cy.get('@add_row').should('have.class', 'driver-highlighted-element');
cy.get("@phone_nos").find(".grid-add-row").as("add_row");
cy.get("@add_row").should("have.class", "driver-highlighted-element");
// add a row & move to next step
cy.wait(500);
cy.get('@add_row').click();
cy.get("@add_row").click();
cy.wait(500);
// assert table field is highlighted
cy.get('.grid-row-open .frappe-control[data-fieldname="phone"]').as('phone');
cy.get('@phone').should('have.class', 'driver-highlighted-element');
cy.get('.grid-row-open .frappe-control[data-fieldname="phone"]').as("phone");
cy.get("@phone").should("have.class", "driver-highlighted-element");
// enter value in a table field
let field = cy.fill_table_field('phone_nos', '1', 'phone', '1234567890');
let field = cy.fill_table_field("phone_nos", "1", "phone", "1234567890");
field.blur();
// move to collapse row step
cy.wait(500);
cy.get('.driver-popover-title').contains('Test Title 4').siblings().get('@next_btn').click();
cy.get(".driver-popover-title")
.contains("Test Title 4")
.siblings()
.get("@next_btn")
.click();
cy.wait(500);
// collapse row
cy.get('.grid-row-open .grid-collapse-row').click();
cy.get(".grid-row-open .grid-collapse-row").click();
cy.wait(500);
// assert save btn is highlighted
cy.get('.primary-action').should('have.class', 'driver-highlighted-element');
cy.get(".primary-action").should("have.class", "driver-highlighted-element");
cy.wait(500);
cy.get('.frappe-driver').findByRole('button', {name: 'Save'}).should('be.visible');
cy.get(".frappe-driver").findByRole("button", { name: "Save" }).should("be.visible");
});
});

View File

@ -1,92 +1,114 @@
context('Grid', () => {
context("Grid", () => {
beforeEach(() => {
cy.login();
cy.visit('/app/website');
cy.visit("/app/website");
});
before(() => {
cy.login();
cy.visit('/app/website');
return cy.window().its('frappe').then(frappe => {
return frappe.call("frappe.tests.ui_test_helpers.create_contact_phone_nos_records");
});
cy.visit("/app/website");
return cy
.window()
.its("frappe")
.then((frappe) => {
return frappe.call(
"frappe.tests.ui_test_helpers.create_contact_phone_nos_records"
);
});
});
it('update docfield property using update_docfield_property', () => {
cy.visit('/app/contact/Test Contact');
cy.window().its("cur_frm").then(frm => {
cy.get('.frappe-control[data-fieldname="phone_nos"]').as('table');
let field = frm.get_field("phone_nos");
field.grid.update_docfield_property("is_primary_phone", "hidden", true);
it("update docfield property using update_docfield_property", () => {
cy.visit("/app/contact/Test Contact");
cy.window()
.its("cur_frm")
.then((frm) => {
cy.get('.frappe-control[data-fieldname="phone_nos"]').as("table");
let field = frm.get_field("phone_nos");
field.grid.update_docfield_property("is_primary_phone", "hidden", true);
cy.get('@table').find('[data-idx="1"] .edit-grid-row').click();
cy.get('.grid-row-open').as('table-form');
cy.get('@table-form').find('.frappe-control[data-fieldname="is_primary_phone"]').should("be.hidden");
cy.get('@table-form').find('.grid-footer-toolbar').click();
cy.get("@table").find('[data-idx="1"] .edit-grid-row').click();
cy.get(".grid-row-open").as("table-form");
cy.get("@table-form")
.find('.frappe-control[data-fieldname="is_primary_phone"]')
.should("be.hidden");
cy.get("@table-form").find(".grid-footer-toolbar").click();
cy.get('@table').find('[data-idx="2"] .edit-grid-row').click();
cy.get('.grid-row-open').as('table-form');
cy.get('@table-form').find('.frappe-control[data-fieldname="is_primary_phone"]').should("be.hidden");
cy.get('@table-form').find('.grid-footer-toolbar').click();
});
cy.get("@table").find('[data-idx="2"] .edit-grid-row').click();
cy.get(".grid-row-open").as("table-form");
cy.get("@table-form")
.find('.frappe-control[data-fieldname="is_primary_phone"]')
.should("be.hidden");
cy.get("@table-form").find(".grid-footer-toolbar").click();
});
});
it('update docfield property using toggle_display', () => {
cy.visit('/app/contact/Test Contact');
cy.window().its("cur_frm").then(frm => {
cy.get('.frappe-control[data-fieldname="phone_nos"]').as('table');
let field = frm.get_field("phone_nos");
field.grid.toggle_display("is_primary_mobile_no", false);
it("update docfield property using toggle_display", () => {
cy.visit("/app/contact/Test Contact");
cy.window()
.its("cur_frm")
.then((frm) => {
cy.get('.frappe-control[data-fieldname="phone_nos"]').as("table");
let field = frm.get_field("phone_nos");
field.grid.toggle_display("is_primary_mobile_no", false);
cy.get('@table').find('[data-idx="1"] .edit-grid-row').click();
cy.get('.grid-row-open').as('table-form');
cy.get('@table-form').find('.frappe-control[data-fieldname="is_primary_mobile_no"]').should("be.hidden");
cy.get('@table-form').find('.grid-footer-toolbar').click();
cy.get("@table").find('[data-idx="1"] .edit-grid-row').click();
cy.get(".grid-row-open").as("table-form");
cy.get("@table-form")
.find('.frappe-control[data-fieldname="is_primary_mobile_no"]')
.should("be.hidden");
cy.get("@table-form").find(".grid-footer-toolbar").click();
cy.get('@table').find('[data-idx="2"] .edit-grid-row').click();
cy.get('.grid-row-open').as('table-form');
cy.get('@table-form').find('.frappe-control[data-fieldname="is_primary_mobile_no"]').should("be.hidden");
cy.get('@table-form').find('.grid-footer-toolbar').click();
});
cy.get("@table").find('[data-idx="2"] .edit-grid-row').click();
cy.get(".grid-row-open").as("table-form");
cy.get("@table-form")
.find('.frappe-control[data-fieldname="is_primary_mobile_no"]')
.should("be.hidden");
cy.get("@table-form").find(".grid-footer-toolbar").click();
});
});
it('update docfield property using toggle_enable', () => {
cy.visit('/app/contact/Test Contact');
cy.window().its("cur_frm").then(frm => {
cy.get('.frappe-control[data-fieldname="phone_nos"]').as('table');
let field = frm.get_field("phone_nos");
field.grid.toggle_enable("phone", false);
it("update docfield property using toggle_enable", () => {
cy.visit("/app/contact/Test Contact");
cy.window()
.its("cur_frm")
.then((frm) => {
cy.get('.frappe-control[data-fieldname="phone_nos"]').as("table");
let field = frm.get_field("phone_nos");
field.grid.toggle_enable("phone", false);
cy.get("@table").find('[data-idx="1"] .edit-grid-row').click();
cy.get(".grid-row-open").as("table-form");
cy.get("@table-form")
.find('.frappe-control[data-fieldname="phone"] .control-value')
.should("have.class", "like-disabled-input");
cy.get("@table-form").find(".grid-footer-toolbar").click();
cy.get('@table').find('[data-idx="1"] .edit-grid-row').click();
cy.get('.grid-row-open').as('table-form');
cy.get('@table-form').find('.frappe-control[data-fieldname="phone"] .control-value').should('have.class', 'like-disabled-input');
cy.get('@table-form').find('.grid-footer-toolbar').click();
cy.get('@table').find('[data-idx="2"] .edit-grid-row').click();
cy.get('.grid-row-open').as('table-form');
cy.get('@table-form').find('.frappe-control[data-fieldname="phone"] .control-value').should('have.class', 'like-disabled-input');
cy.get('@table-form').find('.grid-footer-toolbar').click();
});
cy.get("@table").find('[data-idx="2"] .edit-grid-row').click();
cy.get(".grid-row-open").as("table-form");
cy.get("@table-form")
.find('.frappe-control[data-fieldname="phone"] .control-value')
.should("have.class", "like-disabled-input");
cy.get("@table-form").find(".grid-footer-toolbar").click();
});
});
it('update docfield property using toggle_reqd', () => {
cy.visit('/app/contact/Test Contact');
cy.window().its("cur_frm").then(frm => {
cy.get('.frappe-control[data-fieldname="phone_nos"]').as('table');
let field = frm.get_field("phone_nos");
field.grid.toggle_reqd("phone", false);
it("update docfield property using toggle_reqd", () => {
cy.visit("/app/contact/Test Contact");
cy.window()
.its("cur_frm")
.then((frm) => {
cy.get('.frappe-control[data-fieldname="phone_nos"]').as("table");
let field = frm.get_field("phone_nos");
field.grid.toggle_reqd("phone", false);
cy.get('@table').find('[data-idx="1"] .edit-grid-row').click();
cy.get('.grid-row-open').as('table-form');
cy.get_field("phone").as('phone-field');
cy.get('@phone-field').focus().clear().wait(500).blur();
cy.get('@phone-field').should("not.have.class", "has-error");
cy.get('@table-form').find('.grid-footer-toolbar').click();
cy.get("@table").find('[data-idx="1"] .edit-grid-row').click();
cy.get(".grid-row-open").as("table-form");
cy.get_field("phone").as("phone-field");
cy.get("@phone-field").focus().clear().wait(500).blur();
cy.get("@phone-field").should("not.have.class", "has-error");
cy.get("@table-form").find(".grid-footer-toolbar").click();
cy.get('@table').find('[data-idx="2"] .edit-grid-row').click();
cy.get('.grid-row-open').as('table-form');
cy.get_field("phone").as('phone-field');
cy.get('@phone-field').focus().clear().wait(500).blur();
cy.get('@phone-field').should("not.have.class", "has-error");
cy.get('@table-form').find('.grid-footer-toolbar').click();
});
cy.get("@table").find('[data-idx="2"] .edit-grid-row').click();
cy.get(".grid-row-open").as("table-form");
cy.get_field("phone").as("phone-field");
cy.get("@phone-field").focus().clear().wait(500).blur();
cy.get("@phone-field").should("not.have.class", "has-error");
cy.get("@table-form").find(".grid-footer-toolbar").click();
});
});
});

View File

@ -1,23 +1,23 @@
context('Grid Configuration', () => {
context("Grid Configuration", () => {
beforeEach(() => {
cy.login();
cy.visit('/app/doctype/User');
cy.visit("/app/doctype/User");
});
it('Set user wise grid settings', () => {
it("Set user wise grid settings", () => {
cy.wait(100);
cy.get('.frappe-control[data-fieldname="fields"]').as('table');
cy.get('@table').find('.icon-sm').click();
cy.get('.frappe-control[data-fieldname="fields"]').as("table");
cy.get("@table").find(".icon-sm").click();
cy.wait(100);
cy.get('.frappe-control[data-fieldname="fields_html"]').as('modal');
cy.get('@modal').find('.add-new-fields').click();
cy.get('.frappe-control[data-fieldname="fields_html"]').as("modal");
cy.get("@modal").find(".add-new-fields").click();
cy.wait(100);
cy.get('[type="checkbox"][data-unit="read_only"]').check();
cy.findByRole('button', {name: 'Add'}).click();
cy.findByRole("button", { name: "Add" }).click();
cy.wait(100);
cy.get('[data-fieldname="options"]').invoke('attr', 'value', '1');
cy.get('.form-control.column-width[data-fieldname="options"]').trigger('change');
cy.findByRole('button', {name: 'Update'}).click();
cy.get('[data-fieldname="options"]').invoke("attr", "value", "1");
cy.get('.form-control.column-width[data-fieldname="options"]').trigger("change");
cy.findByRole("button", { name: "Update" }).click();
cy.wait(200);
cy.get('[title="Read Only"').should('be.visible');
cy.get('[title="Read Only"').should("be.visible");
});
});
});

View File

@ -1,40 +1,47 @@
context('Grid Keyboard Shortcut', () => {
context("Grid Keyboard Shortcut", () => {
let total_count = 0;
before(() => {
cy.login();
});
beforeEach(() => {
cy.reload();
cy.visit('/app/contact/new-contact-1');
cy.visit("/app/contact/new-contact-1");
cy.get('.frappe-control[data-fieldname="email_ids"]').find(".grid-add-row").click();
});
it('Insert new row at the end', () => {
cy.add_new_row_in_grid('{ctrl}{shift}{downarrow}', (cy, total_count) => {
cy.get('[data-name="new-contact-email-1"]').should('have.attr', 'data-idx', `${total_count+1}`);
}, total_count);
it("Insert new row at the end", () => {
cy.add_new_row_in_grid(
"{ctrl}{shift}{downarrow}",
(cy, total_count) => {
cy.get('[data-name="new-contact-email-1"]').should(
"have.attr",
"data-idx",
`${total_count + 1}`
);
},
total_count
);
});
it('Insert new row at the top', () => {
cy.add_new_row_in_grid('{ctrl}{shift}{uparrow}', (cy) => {
cy.get('[data-name="new-contact-email-1"]').should('have.attr', 'data-idx', '2');
it("Insert new row at the top", () => {
cy.add_new_row_in_grid("{ctrl}{shift}{uparrow}", (cy) => {
cy.get('[data-name="new-contact-email-1"]').should("have.attr", "data-idx", "2");
});
});
it('Insert new row below', () => {
cy.add_new_row_in_grid('{ctrl}{downarrow}', (cy) => {
cy.get('[data-name="new-contact-email-1"]').should('have.attr', 'data-idx', '1');
it("Insert new row below", () => {
cy.add_new_row_in_grid("{ctrl}{downarrow}", (cy) => {
cy.get('[data-name="new-contact-email-1"]').should("have.attr", "data-idx", "1");
});
});
it('Insert new row above', () => {
cy.add_new_row_in_grid('{ctrl}{uparrow}', (cy) => {
cy.get('[data-name="new-contact-email-1"]').should('have.attr', 'data-idx', '2');
it("Insert new row above", () => {
cy.add_new_row_in_grid("{ctrl}{uparrow}", (cy) => {
cy.get('[data-name="new-contact-email-1"]').should("have.attr", "data-idx", "2");
});
});
});
Cypress.Commands.add('add_new_row_in_grid', (shortcut_keys, callbackFn, total_count) => {
cy.get('.frappe-control[data-fieldname="email_ids"]').as('table');
cy.get('@table').find('.grid-body [data-fieldname="email_id"]').first().click();
cy.get('@table').find('.grid-body [data-fieldname="email_id"]')
.first().type(shortcut_keys);
Cypress.Commands.add("add_new_row_in_grid", (shortcut_keys, callbackFn, total_count) => {
cy.get('.frappe-control[data-fieldname="email_ids"]').as("table");
cy.get("@table").find('.grid-body [data-fieldname="email_id"]').first().click();
cy.get("@table").find('.grid-body [data-fieldname="email_id"]').first().type(shortcut_keys);
callbackFn(cy, total_count);
});
});

View File

@ -1,65 +1,73 @@
context('Grid Pagination', () => {
context("Grid Pagination", () => {
beforeEach(() => {
cy.login();
cy.visit('/app/website');
cy.visit("/app/website");
});
before(() => {
cy.login();
cy.visit('/app/website');
return cy.window().its('frappe').then(frappe => {
return frappe.call("frappe.tests.ui_test_helpers.create_contact_phone_nos_records");
});
cy.visit("/app/website");
return cy
.window()
.its("frappe")
.then((frappe) => {
return frappe.call(
"frappe.tests.ui_test_helpers.create_contact_phone_nos_records"
);
});
});
it('creates pages for child table', () => {
cy.visit('/app/contact/Test Contact');
cy.get('.frappe-control[data-fieldname="phone_nos"]').as('table');
cy.get('@table').find('.current-page-number').should('have.value', '1');
cy.get('@table').find('.total-page-number').should('contain', '20');
cy.get('@table').find('.grid-body .grid-row').should('have.length', 50);
it("creates pages for child table", () => {
cy.visit("/app/contact/Test Contact");
cy.get('.frappe-control[data-fieldname="phone_nos"]').as("table");
cy.get("@table").find(".current-page-number").should("have.value", "1");
cy.get("@table").find(".total-page-number").should("contain", "20");
cy.get("@table").find(".grid-body .grid-row").should("have.length", 50);
});
it('goes to the next and previous page', () => {
cy.visit('/app/contact/Test Contact');
cy.get('.frappe-control[data-fieldname="phone_nos"]').as('table');
cy.get('@table').find('.next-page').click();
cy.get('@table').find('.current-page-number').should('have.value', '2');
cy.get('@table').find('.grid-body .grid-row').first().should('have.attr', 'data-idx', '51');
cy.get('@table').find('.prev-page').click();
cy.get('@table').find('.current-page-number').should('have.value', '1');
cy.get('@table').find('.grid-body .grid-row').first().should('have.attr', 'data-idx', '1');
it("goes to the next and previous page", () => {
cy.visit("/app/contact/Test Contact");
cy.get('.frappe-control[data-fieldname="phone_nos"]').as("table");
cy.get("@table").find(".next-page").click();
cy.get("@table").find(".current-page-number").should("have.value", "2");
cy.get("@table")
.find(".grid-body .grid-row")
.first()
.should("have.attr", "data-idx", "51");
cy.get("@table").find(".prev-page").click();
cy.get("@table").find(".current-page-number").should("have.value", "1");
cy.get("@table").find(".grid-body .grid-row").first().should("have.attr", "data-idx", "1");
});
it('adds and deletes rows and changes page', () => {
cy.visit('/app/contact/Test Contact');
cy.get('.frappe-control[data-fieldname="phone_nos"]').as('table');
cy.get('@table').findByRole('button', {name: 'Add Row'}).click();
cy.get('@table').find('.grid-body .row-index').should('contain', 1001);
cy.get('@table').find('.current-page-number').should('have.value', '21');
cy.get('@table').find('.total-page-number').should('contain', '21');
cy.get('@table').find('.grid-body .grid-row .grid-row-check').click({ force: true });
cy.get('@table').findByRole('button', {name: 'Delete'}).click();
cy.get('@table').find('.grid-body .row-index').last().should('contain', 1000);
cy.get('@table').find('.current-page-number').should('have.value', '20');
cy.get('@table').find('.total-page-number').should('contain', '20');
it("adds and deletes rows and changes page", () => {
cy.visit("/app/contact/Test Contact");
cy.get('.frappe-control[data-fieldname="phone_nos"]').as("table");
cy.get("@table").findByRole("button", { name: "Add Row" }).click();
cy.get("@table").find(".grid-body .row-index").should("contain", 1001);
cy.get("@table").find(".current-page-number").should("have.value", "21");
cy.get("@table").find(".total-page-number").should("contain", "21");
cy.get("@table").find(".grid-body .grid-row .grid-row-check").click({ force: true });
cy.get("@table").findByRole("button", { name: "Delete" }).click();
cy.get("@table").find(".grid-body .row-index").last().should("contain", 1000);
cy.get("@table").find(".current-page-number").should("have.value", "20");
cy.get("@table").find(".total-page-number").should("contain", "20");
});
it('go to specific page, use up and down arrow, type characters, 0 page and more than existing page', () => {
cy.visit('/app/contact/Test Contact');
cy.get('.frappe-control[data-fieldname="phone_nos"]').as('table');
cy.get('@table').find('.current-page-number').focus().clear().type('17').blur();
cy.get('@table').find('.grid-body .row-index').should('contain', 801);
it("go to specific page, use up and down arrow, type characters, 0 page and more than existing page", () => {
cy.visit("/app/contact/Test Contact");
cy.get('.frappe-control[data-fieldname="phone_nos"]').as("table");
cy.get("@table").find(".current-page-number").focus().clear().type("17").blur();
cy.get("@table").find(".grid-body .row-index").should("contain", 801);
cy.get('@table').find('.current-page-number').focus().type('{uparrow}{uparrow}');
cy.get('@table').find('.current-page-number').should('have.value', '19');
cy.get("@table").find(".current-page-number").focus().type("{uparrow}{uparrow}");
cy.get("@table").find(".current-page-number").should("have.value", "19");
cy.get('@table').find('.current-page-number').focus().type('{downarrow}{downarrow}');
cy.get('@table').find('.current-page-number').should('have.value', '17');
cy.get("@table").find(".current-page-number").focus().type("{downarrow}{downarrow}");
cy.get("@table").find(".current-page-number").should("have.value", "17");
cy.get('@table').find('.current-page-number').focus().clear().type('700').blur();
cy.get('@table').find('.current-page-number').should('have.value', '20');
cy.get("@table").find(".current-page-number").focus().clear().type("700").blur();
cy.get("@table").find(".current-page-number").should("have.value", "20");
cy.get('@table').find('.current-page-number').focus().clear().type('0').blur();
cy.get('@table').find('.current-page-number').should('have.value', '1');
cy.get("@table").find(".current-page-number").focus().clear().type("0").blur();
cy.get("@table").find(".current-page-number").should("have.value", "1");
cy.get('@table').find('.current-page-number').focus().clear().type('abc').blur();
cy.get('@table').find('.current-page-number').should('have.value', '1');
cy.get("@table").find(".current-page-number").focus().clear().type("abc").blur();
cy.get("@table").find(".current-page-number").should("have.value", "1");
});
// it('deletes all rows', ()=> {
// cy.visit('/app/contact/Test Contact');
@ -69,4 +77,4 @@ context('Grid Pagination', () => {
// cy.get('.modal-dialog .btn-primary').contains('Yes').click();
// cy.get('@table').find('.grid-body .grid-row').should('have.length', 0);
// });
});
});

View File

@ -1,107 +1,133 @@
import doctype_with_child_table from '../fixtures/doctype_with_child_table';
import child_table_doctype from '../fixtures/child_table_doctype';
import child_table_doctype_1 from '../fixtures/child_table_doctype_1';
import doctype_with_child_table from "../fixtures/doctype_with_child_table";
import child_table_doctype from "../fixtures/child_table_doctype";
import child_table_doctype_1 from "../fixtures/child_table_doctype_1";
const doctype_with_child_table_name = doctype_with_child_table.name;
context('Grid Search', () => {
context("Grid Search", () => {
before(() => {
cy.visit('/login');
cy.visit("/login");
cy.login();
cy.visit('/app/website');
cy.insert_doc('DocType', child_table_doctype, true);
cy.insert_doc('DocType', child_table_doctype_1, true);
cy.insert_doc('DocType', doctype_with_child_table, true);
return cy.window().its('frappe').then(frappe => {
return frappe.xcall("frappe.tests.ui_test_helpers.insert_doctype_with_child_table_record", {
name: doctype_with_child_table_name
cy.visit("/app/website");
cy.insert_doc("DocType", child_table_doctype, true);
cy.insert_doc("DocType", child_table_doctype_1, true);
cy.insert_doc("DocType", doctype_with_child_table, true);
return cy
.window()
.its("frappe")
.then((frappe) => {
return frappe.xcall(
"frappe.tests.ui_test_helpers.insert_doctype_with_child_table_record",
{
name: doctype_with_child_table_name,
}
);
});
});
});
it('Test search row visibility', () => {
cy.window().its('frappe').then(frappe => {
frappe.model.user_settings.save('Doctype With Child Table', 'GridView', {
'Child Table Doctype 1': [
{'fieldname': 'data', 'columns': 2},
{'fieldname': 'barcode', 'columns': 1},
{'fieldname': 'check', 'columns': 1},
{'fieldname': 'rating', 'columns': 2},
{'fieldname': 'duration', 'columns': 2},
{'fieldname': 'date', 'columns': 2}
]
it("Test search row visibility", () => {
cy.window()
.its("frappe")
.then((frappe) => {
frappe.model.user_settings.save("Doctype With Child Table", "GridView", {
"Child Table Doctype 1": [
{ fieldname: "data", columns: 2 },
{ fieldname: "barcode", columns: 1 },
{ fieldname: "check", columns: 1 },
{ fieldname: "rating", columns: 2 },
{ fieldname: "duration", columns: 2 },
{ fieldname: "date", columns: 2 },
],
});
});
});
cy.visit(`/app/doctype-with-child-table/Test Grid Search`);
cy.get('.frappe-control[data-fieldname="child_table_1"]').as('table');
cy.get('@table').find('.grid-row-check:last').click();
cy.get('@table').find('.grid-footer').contains('Delete').click();
cy.get('.grid-heading-row .grid-row .search').should('not.exist');
cy.get('.frappe-control[data-fieldname="child_table_1"]').as("table");
cy.get("@table").find(".grid-row-check:last").click();
cy.get("@table").find(".grid-footer").contains("Delete").click();
cy.get(".grid-heading-row .grid-row .search").should("not.exist");
});
it('test search field for different fieldtypes', () => {
it("test search field for different fieldtypes", () => {
cy.visit(`/app/doctype-with-child-table/Test Grid Search`);
cy.get('.frappe-control[data-fieldname="child_table_1"]').as('table');
cy.get('.frappe-control[data-fieldname="child_table_1"]').as("table");
// Index Column
cy.get('@table').find('.grid-heading-row .row-index.search input').type('3');
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 2);
cy.get('@table').find('.grid-heading-row .row-index.search input').clear();
cy.get("@table").find(".grid-heading-row .row-index.search input").type("3");
cy.get("@table").find(".grid-body .rows .grid-row").should("have.length", 2);
cy.get("@table").find(".grid-heading-row .row-index.search input").clear();
// Data Column
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Data"]').type('Data');
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 1);
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Data"]').clear();
cy.get("@table")
.find('.grid-heading-row .search input[data-fieldtype="Data"]')
.type("Data");
cy.get("@table").find(".grid-body .rows .grid-row").should("have.length", 1);
cy.get("@table").find('.grid-heading-row .search input[data-fieldtype="Data"]').clear();
// Barcode Column
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Barcode"]').type('092');
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 4);
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Barcode"]').clear();
cy.get("@table")
.find('.grid-heading-row .search input[data-fieldtype="Barcode"]')
.type("092");
cy.get("@table").find(".grid-body .rows .grid-row").should("have.length", 4);
cy.get("@table").find('.grid-heading-row .search input[data-fieldtype="Barcode"]').clear();
// Check Column
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Check"]').type('1');
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 9);
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Check"]').clear();
cy.get("@table").find('.grid-heading-row .search input[data-fieldtype="Check"]').type("1");
cy.get("@table").find(".grid-body .rows .grid-row").should("have.length", 9);
cy.get("@table").find('.grid-heading-row .search input[data-fieldtype="Check"]').clear();
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Check"]').type('0');
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 11);
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Check"]').clear();
cy.get("@table").find('.grid-heading-row .search input[data-fieldtype="Check"]').type("0");
cy.get("@table").find(".grid-body .rows .grid-row").should("have.length", 11);
cy.get("@table").find('.grid-heading-row .search input[data-fieldtype="Check"]').clear();
// Rating Column
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Rating"]').type('3');
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 3);
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Rating"]').clear();
cy.get("@table")
.find('.grid-heading-row .search input[data-fieldtype="Rating"]')
.type("3");
cy.get("@table").find(".grid-body .rows .grid-row").should("have.length", 3);
cy.get("@table").find('.grid-heading-row .search input[data-fieldtype="Rating"]').clear();
// Duration Column
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Duration"]').type('3d');
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 3);
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Duration"]').clear();
cy.get("@table")
.find('.grid-heading-row .search input[data-fieldtype="Duration"]')
.type("3d");
cy.get("@table").find(".grid-body .rows .grid-row").should("have.length", 3);
cy.get("@table")
.find('.grid-heading-row .search input[data-fieldtype="Duration"]')
.clear();
// Date Column
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Date"]').type('2022');
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 4);
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Date"]').clear();
cy.get("@table")
.find('.grid-heading-row .search input[data-fieldtype="Date"]')
.type("2022");
cy.get("@table").find(".grid-body .rows .grid-row").should("have.length", 4);
cy.get("@table").find('.grid-heading-row .search input[data-fieldtype="Date"]').clear();
});
it('test with multiple filter', () => {
cy.get('.frappe-control[data-fieldname="child_table_1"]').as('table');
it("test with multiple filter", () => {
cy.get('.frappe-control[data-fieldname="child_table_1"]').as("table");
// Data Column
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Data"]').type('a');
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 10);
cy.get("@table").find('.grid-heading-row .search input[data-fieldtype="Data"]').type("a");
cy.get("@table").find(".grid-body .rows .grid-row").should("have.length", 10);
// Barcode Column
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Barcode"]').type('0');
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 8);
cy.get("@table")
.find('.grid-heading-row .search input[data-fieldtype="Barcode"]')
.type("0");
cy.get("@table").find(".grid-body .rows .grid-row").should("have.length", 8);
// Duration Column
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Duration"]').type('d');
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 5);
cy.get("@table")
.find('.grid-heading-row .search input[data-fieldtype="Duration"]')
.type("d");
cy.get("@table").find(".grid-body .rows .grid-row").should("have.length", 5);
// Date Column
cy.get('@table').find('.grid-heading-row .search input[data-fieldtype="Date"]').type('02-');
cy.get('@table').find('.grid-body .rows .grid-row').should('have.length', 2);
cy.get("@table")
.find('.grid-heading-row .search input[data-fieldtype="Date"]')
.type("02-");
cy.get("@table").find(".grid-body .rows .grid-row").should("have.length", 2);
});
});
});

View File

@ -1,75 +1,100 @@
context('Kanban Board', () => {
context("Kanban Board", () => {
before(() => {
cy.login();
cy.visit('/app');
cy.visit("/app");
});
it('Create ToDo Kanban', () => {
cy.visit('/app/todo');
it("Create ToDo Kanban", () => {
cy.visit("/app/todo");
cy.get('.page-actions .custom-btn-group button').click();
cy.get('.page-actions .custom-btn-group ul.dropdown-menu li').contains('Kanban').click();
cy.get(".page-actions .custom-btn-group button").click();
cy.get(".page-actions .custom-btn-group ul.dropdown-menu li").contains("Kanban").click();
cy.focused().blur();
cy.fill_field('board_name', 'ToDo Kanban', 'Data');
cy.fill_field('field_name', 'Status', 'Select');
cy.click_modal_primary_button('Save');
cy.fill_field("board_name", "ToDo Kanban", "Data");
cy.fill_field("field_name", "Status", "Select");
cy.click_modal_primary_button("Save");
cy.get('.title-text').should('contain', 'ToDo Kanban');
cy.get(".title-text").should("contain", "ToDo Kanban");
});
it('Create ToDo from kanban', () => {
it("Create ToDo from kanban", () => {
cy.intercept({
method: 'POST',
url: 'api/method/frappe.client.save'
}).as('save-todo');
method: "POST",
url: "api/method/frappe.client.save",
}).as("save-todo");
cy.click_listview_primary_button('Add ToDo');
cy.click_listview_primary_button("Add ToDo");
cy.fill_field('description', 'Test Kanban ToDo', 'Text Editor').wait(300);
cy.get('.modal-footer .btn-primary').last().click();
cy.fill_field("description", "Test Kanban ToDo", "Text Editor").wait(300);
cy.get(".modal-footer .btn-primary").last().click();
cy.wait('@save-todo');
cy.wait("@save-todo");
});
it('Add and Remove fields', () => {
cy.visit('/app/todo/view/kanban/ToDo Kanban');
it("Add and Remove fields", () => {
cy.visit("/app/todo/view/kanban/ToDo Kanban");
cy.intercept('POST', '/api/method/frappe.desk.doctype.kanban_board.kanban_board.save_settings').as('save-kanban');
cy.intercept('POST', '/api/method/frappe.desk.doctype.kanban_board.kanban_board.update_order').as('update-order');
cy.intercept(
"POST",
"/api/method/frappe.desk.doctype.kanban_board.kanban_board.save_settings"
).as("save-kanban");
cy.intercept(
"POST",
"/api/method/frappe.desk.doctype.kanban_board.kanban_board.update_order"
).as("update-order");
cy.get('.page-actions .menu-btn-group > .btn').click();
cy.get('.page-actions .menu-btn-group .dropdown-menu li').contains('Kanban Settings').click();
cy.get('.add-new-fields').click();
cy.get(".page-actions .menu-btn-group > .btn").click();
cy.get(".page-actions .menu-btn-group .dropdown-menu li")
.contains("Kanban Settings")
.click();
cy.get(".add-new-fields").click();
cy.get('.checkbox-options .checkbox').contains('ID').click();
cy.get('.checkbox-options .checkbox').contains('Status').first().click();
cy.get('.checkbox-options .checkbox').contains('Priority').click();
cy.get(".checkbox-options .checkbox").contains("ID").click();
cy.get(".checkbox-options .checkbox").contains("Status").first().click();
cy.get(".checkbox-options .checkbox").contains("Priority").click();
cy.get('.modal-footer .btn-primary').last().click();
cy.get(".modal-footer .btn-primary").last().click();
cy.get('.frappe-control .label-area').contains('Show Labels').click();
cy.click_modal_primary_button('Save');
cy.get(".frappe-control .label-area").contains("Show Labels").click();
cy.click_modal_primary_button("Save");
cy.wait('@save-kanban');
cy.wait("@save-kanban");
cy.get('.kanban-column[data-column-value="Open"] .kanban-cards').as('open-cards');
cy.get('@open-cards').find('.kanban-card .kanban-card-doc').first().should('contain', 'ID:');
cy.get('@open-cards').find('.kanban-card .kanban-card-doc').first().should('contain', 'Status:');
cy.get('@open-cards').find('.kanban-card .kanban-card-doc').first().should('contain', 'Priority:');
cy.get('.kanban-column[data-column-value="Open"] .kanban-cards').as("open-cards");
cy.get("@open-cards")
.find(".kanban-card .kanban-card-doc")
.first()
.should("contain", "ID:");
cy.get("@open-cards")
.find(".kanban-card .kanban-card-doc")
.first()
.should("contain", "Status:");
cy.get("@open-cards")
.find(".kanban-card .kanban-card-doc")
.first()
.should("contain", "Priority:");
cy.get('.page-actions .menu-btn-group > .btn').click();
cy.get('.page-actions .menu-btn-group .dropdown-menu li').contains('Kanban Settings').click();
cy.get_open_dialog().find('.frappe-control[data-fieldname="fields_html"] div[data-label="ID"] .remove-field').click();
cy.get(".page-actions .menu-btn-group > .btn").click();
cy.get(".page-actions .menu-btn-group .dropdown-menu li")
.contains("Kanban Settings")
.click();
cy.get_open_dialog()
.find(
'.frappe-control[data-fieldname="fields_html"] div[data-label="ID"] .remove-field'
)
.click();
cy.wait('@update-order');
cy.get_open_dialog().find('.frappe-control .label-area').contains('Show Labels').click();
cy.get('.modal-footer .btn-primary').last().click();
cy.wait("@update-order");
cy.get_open_dialog().find(".frappe-control .label-area").contains("Show Labels").click();
cy.get(".modal-footer .btn-primary").last().click();
cy.wait('@save-kanban');
cy.get('@open-cards').find('.kanban-card .kanban-card-doc').first().should('not.contain', 'ID:');
cy.wait("@save-kanban");
cy.get("@open-cards")
.find(".kanban-card .kanban-card-doc")
.first()
.should("not.contain", "ID:");
});
// it('Drag todo', () => {
@ -84,4 +109,4 @@ context('Kanban Board', () => {
// cy.wait('@drag-completed');
// });
});
});

View File

@ -1,39 +1,42 @@
context('List Paging', () => {
context("List Paging", () => {
before(() => {
cy.login();
cy.visit('/app/website');
return cy.window().its('frappe').then(frappe => {
return frappe.call("frappe.tests.ui_test_helpers.create_multiple_todo_records");
});
cy.visit("/app/website");
return cy
.window()
.its("frappe")
.then((frappe) => {
return frappe.call("frappe.tests.ui_test_helpers.create_multiple_todo_records");
});
});
it('test load more with count selection buttons', () => {
cy.visit('/app/todo/view/report');
cy.clear_filters()
it("test load more with count selection buttons", () => {
cy.visit("/app/todo/view/report");
cy.clear_filters();
cy.get('.list-paging-area .list-count').should('contain.text', '20 of');
cy.get('.list-paging-area .btn-more').click();
cy.get('.list-paging-area .list-count').should('contain.text', '40 of');
cy.get('.list-paging-area .btn-more').click();
cy.get('.list-paging-area .list-count').should('contain.text', '60 of');
cy.get(".list-paging-area .list-count").should("contain.text", "20 of");
cy.get(".list-paging-area .btn-more").click();
cy.get(".list-paging-area .list-count").should("contain.text", "40 of");
cy.get(".list-paging-area .btn-more").click();
cy.get(".list-paging-area .list-count").should("contain.text", "60 of");
cy.get('.list-paging-area .btn-group .btn-paging[data-value="100"]').click();
cy.get('.list-paging-area .list-count').should('contain.text', '100 of');
cy.get('.list-paging-area .btn-more').click();
cy.get('.list-paging-area .list-count').should('contain.text', '200 of');
cy.get('.list-paging-area .btn-more').click();
cy.get('.list-paging-area .list-count').should('contain.text', '300 of');
cy.get(".list-paging-area .list-count").should("contain.text", "100 of");
cy.get(".list-paging-area .btn-more").click();
cy.get(".list-paging-area .list-count").should("contain.text", "200 of");
cy.get(".list-paging-area .btn-more").click();
cy.get(".list-paging-area .list-count").should("contain.text", "300 of");
// check if refresh works after load more
cy.get('.page-head .standard-actions [data-original-title="Refresh"]').click();
cy.get('.list-paging-area .list-count').should('contain.text', '300 of');
cy.get(".list-paging-area .list-count").should("contain.text", "300 of");
cy.get('.list-paging-area .btn-group .btn-paging[data-value="500"]').click();
cy.get('.list-paging-area .list-count').should('contain.text', '500 of');
cy.get('.list-paging-area .btn-more').click();
cy.get(".list-paging-area .list-count").should("contain.text", "500 of");
cy.get(".list-paging-area .btn-more").click();
cy.get('.list-paging-area .list-count').should('contain.text', '1000 of');
cy.get(".list-paging-area .list-count").should("contain.text", "1000 of");
});
});

View File

@ -1,48 +1,67 @@
context('List View', () => {
context("List View", () => {
before(() => {
cy.login();
cy.visit('/app/website');
return cy.window().its('frappe').then(frappe => {
return frappe.xcall("frappe.tests.ui_test_helpers.setup_workflow");
});
cy.visit("/app/website");
return cy
.window()
.its("frappe")
.then((frappe) => {
return frappe.xcall("frappe.tests.ui_test_helpers.setup_workflow");
});
});
it('Keep checkbox checked after Refresh', () => {
cy.go_to_list('ToDo');
cy.clear_filters()
cy.get('.list-row-container .list-row-checkbox').click({ multiple: true, force: true });
cy.get('.actions-btn-group button').contains('Actions').should('be.visible');
cy.intercept('/api/method/frappe.desk.reportview.get').as('list-refresh');
it("Keep checkbox checked after Refresh", () => {
cy.go_to_list("ToDo");
cy.clear_filters();
cy.get(".list-row-container .list-row-checkbox").click({ multiple: true, force: true });
cy.get(".actions-btn-group button").contains("Actions").should("be.visible");
cy.intercept("/api/method/frappe.desk.reportview.get").as("list-refresh");
cy.wait(3000); // wait before you hit another refresh
cy.get('button[data-original-title="Refresh"]').click();
cy.wait('@list-refresh');
cy.get('.list-row-container .list-row-checkbox:checked').should('be.visible');
cy.wait("@list-refresh");
cy.get(".list-row-container .list-row-checkbox:checked").should("be.visible");
});
it('enables "Actions" button', () => {
const actions = ['Approve', 'Reject', 'Edit', 'Export', 'Assign To', 'Apply Assignment Rule', 'Add Tags', 'Print', 'Delete'];
cy.go_to_list('ToDo');
cy.clear_filters()
cy.get('.list-row-container:contains("Pending") .list-row-checkbox').click({ multiple: true, force: true });
cy.get('.actions-btn-group button').contains('Actions').should('be.visible').click();
cy.get('.dropdown-menu li:visible .dropdown-item').should('have.length', 9).each((el, index) => {
cy.wrap(el).contains(actions[index]);
}).then((elements) => {
cy.intercept({
method: 'POST',
url: 'api/method/frappe.model.workflow.bulk_workflow_approval'
}).as('bulk-approval');
cy.intercept({
method: 'POST',
url: 'api/method/frappe.desk.reportview.get'
}).as('real-time-update');
cy.wrap(elements).contains('Approve').click();
cy.wait(['@bulk-approval', '@real-time-update']);
cy.wait(300);
cy.get_open_dialog().find('.btn-modal-close').click();
cy.reload();
cy.clear_filters();
cy.get('.list-row-container:visible').should('contain', 'Approved');
const actions = [
"Approve",
"Reject",
"Edit",
"Export",
"Assign To",
"Apply Assignment Rule",
"Add Tags",
"Print",
"Delete",
];
cy.go_to_list("ToDo");
cy.clear_filters();
cy.get('.list-row-container:contains("Pending") .list-row-checkbox').click({
multiple: true,
force: true,
});
cy.get(".actions-btn-group button").contains("Actions").should("be.visible").click();
cy.get(".dropdown-menu li:visible .dropdown-item")
.should("have.length", 9)
.each((el, index) => {
cy.wrap(el).contains(actions[index]);
})
.then((elements) => {
cy.intercept({
method: "POST",
url: "api/method/frappe.model.workflow.bulk_workflow_approval",
}).as("bulk-approval");
cy.intercept({
method: "POST",
url: "api/method/frappe.desk.reportview.get",
}).as("real-time-update");
cy.wrap(elements).contains("Approve").click();
cy.wait(["@bulk-approval", "@real-time-update"]);
cy.wait(300);
cy.get_open_dialog().find(".btn-modal-close").click();
cy.reload();
cy.clear_filters();
cy.get(".list-row-container:visible").should("contain", "Approved");
});
});
});

View File

@ -1,36 +1,36 @@
context('List View Settings', () => {
context("List View Settings", () => {
beforeEach(() => {
cy.login();
cy.visit('/app/website');
cy.visit("/app/website");
});
it('Default settings', () => {
cy.visit('/app/List/DocType/List');
cy.get('.list-count').should('contain', "20 of");
cy.get('.list-stats').should('contain', "Tags");
it("Default settings", () => {
cy.visit("/app/List/DocType/List");
cy.get(".list-count").should("contain", "20 of");
cy.get(".list-stats").should("contain", "Tags");
});
it('disable count and sidebar stats then verify', () => {
it("disable count and sidebar stats then verify", () => {
cy.wait(300);
cy.visit('/app/List/DocType/List');
cy.visit("/app/List/DocType/List");
cy.wait(300);
cy.get('.list-count').should('contain', "20 of");
cy.get('.menu-btn-group button').click();
cy.get('.dropdown-menu li').filter(':visible').contains('List Settings').click();
cy.get('.modal-dialog').should('contain', 'DocType Settings');
cy.get(".list-count").should("contain", "20 of");
cy.get(".menu-btn-group button").click();
cy.get(".dropdown-menu li").filter(":visible").contains("List Settings").click();
cy.get(".modal-dialog").should("contain", "DocType Settings");
cy.findByLabelText('Disable Count').check({ force: true });
cy.findByLabelText('Disable Sidebar Stats').check({ force: true });
cy.findByRole('button', {name: 'Save'}).click();
cy.findByLabelText("Disable Count").check({ force: true });
cy.findByLabelText("Disable Sidebar Stats").check({ force: true });
cy.findByRole("button", { name: "Save" }).click();
cy.reload({ force: true });
cy.get('.list-count').should('be.empty');
cy.get('.list-sidebar .list-tags').should('not.exist');
cy.get(".list-count").should("be.empty");
cy.get(".list-sidebar .list-tags").should("not.exist");
cy.get('.menu-btn-group button').click({ force: true });
cy.get('.dropdown-menu li').filter(':visible').contains('List Settings').click();
cy.get('.modal-dialog').should('contain', 'DocType Settings');
cy.findByLabelText('Disable Count').uncheck({ force: true });
cy.findByLabelText('Disable Sidebar Stats').uncheck({ force: true });
cy.findByRole('button', {name: 'Save'}).click();
cy.get(".menu-btn-group button").click({ force: true });
cy.get(".dropdown-menu li").filter(":visible").contains("List Settings").click();
cy.get(".modal-dialog").should("contain", "DocType Settings");
cy.findByLabelText("Disable Count").uncheck({ force: true });
cy.findByLabelText("Disable Sidebar Stats").uncheck({ force: true });
cy.findByRole("button", { name: "Save" }).click();
});
});

View File

@ -1,68 +1,66 @@
context('Login', () => {
context("Login", () => {
beforeEach(() => {
cy.request('/api/method/logout');
cy.visit('/login');
cy.location('pathname').should('eq', '/login');
cy.request("/api/method/logout");
cy.visit("/login");
cy.location("pathname").should("eq", "/login");
});
it('greets with login screen', () => {
cy.get('.page-card-head').contains('Login');
it("greets with login screen", () => {
cy.get(".page-card-head").contains("Login");
});
it('validates password', () => {
cy.get('#login_email').type('Administrator');
cy.findByRole('button', {name: 'Login'}).click();
cy.location('pathname').should('eq', '/login');
it("validates password", () => {
cy.get("#login_email").type("Administrator");
cy.findByRole("button", { name: "Login" }).click();
cy.location("pathname").should("eq", "/login");
});
it('validates email', () => {
cy.get('#login_password').type('qwe');
cy.findByRole('button', {name: 'Login'}).click();
cy.location('pathname').should('eq', '/login');
it("validates email", () => {
cy.get("#login_password").type("qwe");
cy.findByRole("button", { name: "Login" }).click();
cy.location("pathname").should("eq", "/login");
});
it('shows invalid login if incorrect credentials', () => {
cy.get('#login_email').type('Administrator');
cy.get('#login_password').type('qwer');
it("shows invalid login if incorrect credentials", () => {
cy.get("#login_email").type("Administrator");
cy.get("#login_password").type("qwer");
cy.findByRole('button', {name: 'Login'}).click();
cy.findByRole('button', {name: 'Invalid Login. Try again.'}).should('exist');
cy.location('pathname').should('eq', '/login');
cy.findByRole("button", { name: "Login" }).click();
cy.findByRole("button", { name: "Invalid Login. Try again." }).should("exist");
cy.location("pathname").should("eq", "/login");
});
it('logs in using correct credentials', () => {
cy.get('#login_email').type('Administrator');
cy.get('#login_password').type(Cypress.config('adminPassword'));
it("logs in using correct credentials", () => {
cy.get("#login_email").type("Administrator");
cy.get("#login_password").type(Cypress.config("adminPassword"));
cy.findByRole('button', {name: 'Login'}).click();
cy.location('pathname').should('eq', '/app');
cy.window().its('frappe.session.user').should('eq', 'Administrator');
cy.findByRole("button", { name: "Login" }).click();
cy.location("pathname").should("eq", "/app");
cy.window().its("frappe.session.user").should("eq", "Administrator");
});
it('check redirect after login', () => {
it("check redirect after login", () => {
// mock for OAuth 2.0 client_id, redirect_uri, scope and state
const payload = new URLSearchParams({
uuid: '6fed1519-cfd8-4a2d-84a6-9a1799c7c741',
encoded_string: 'hello all',
encoded_url: 'http://test.localhost/callback',
base64_string: 'aGVsbG8gYWxs'
uuid: "6fed1519-cfd8-4a2d-84a6-9a1799c7c741",
encoded_string: "hello all",
encoded_url: "http://test.localhost/callback",
base64_string: "aGVsbG8gYWxs",
});
cy.request('/api/method/logout');
cy.request("/api/method/logout");
// redirect-to /me page with params to mock OAuth 2.0 like request
cy.visit(
'/login?redirect-to=/me?' +
encodeURIComponent(payload.toString().replace("+", " "))
"/login?redirect-to=/me?" + encodeURIComponent(payload.toString().replace("+", " "))
);
cy.get('#login_email').type('Administrator');
cy.get('#login_password').type(Cypress.config('adminPassword'));
cy.get("#login_email").type("Administrator");
cy.get("#login_password").type(Cypress.config("adminPassword"));
cy.findByRole('button', {name: 'Login'}).click();
cy.findByRole("button", { name: "Login" }).click();
// verify redirected location and url params after login
cy.url().should('include', '/me?' + payload.toString().replace('+', '%20'));
cy.url().should("include", "/me?" + payload.toString().replace("+", "%20"));
});
});

View File

@ -1,99 +1,102 @@
context('MultiSelectDialog', () => {
context("MultiSelectDialog", () => {
before(() => {
cy.login();
cy.visit('/app');
cy.visit("/app");
const contact_template = {
"doctype": "Contact",
"first_name": "Test",
"status": "Passive",
"email_ids": [
doctype: "Contact",
first_name: "Test",
status: "Passive",
email_ids: [
{
"doctype": "Contact Email",
"email_id": "test@example.com",
"is_primary": 0
}
]
doctype: "Contact Email",
email_id: "test@example.com",
is_primary: 0,
},
],
};
const promises = Array.from({length: 25})
.map(() => cy.insert_doc('Contact', contact_template, true));
const promises = Array.from({ length: 25 }).map(() =>
cy.insert_doc("Contact", contact_template, true)
);
Promise.all(promises);
});
function open_multi_select_dialog() {
cy.window().its('frappe').then(frappe => {
new frappe.ui.form.MultiSelectDialog({
doctype: "Contact",
target: {},
setters: {
status: null,
gender: null
},
add_filters_group: 1,
allow_child_item_selection: 1,
child_fieldname: "email_ids",
child_columns: ["email_id", "is_primary"]
cy.window()
.its("frappe")
.then((frappe) => {
new frappe.ui.form.MultiSelectDialog({
doctype: "Contact",
target: {},
setters: {
status: null,
gender: null,
},
add_filters_group: 1,
allow_child_item_selection: 1,
child_fieldname: "email_ids",
child_columns: ["email_id", "is_primary"],
});
});
});
}
it('checks multi select dialog api works', () => {
it("checks multi select dialog api works", () => {
open_multi_select_dialog();
cy.get_open_dialog().should('contain', 'Select Contacts');
cy.get_open_dialog().should("contain", "Select Contacts");
});
it('checks for filters', () => {
['search_term', 'status', 'gender'].forEach(fieldname => {
cy.get_open_dialog().get(`.frappe-control[data-fieldname="${fieldname}"]`).should('exist');
it("checks for filters", () => {
["search_term", "status", "gender"].forEach((fieldname) => {
cy.get_open_dialog()
.get(`.frappe-control[data-fieldname="${fieldname}"]`)
.should("exist");
});
// add_filters_group: 1 should add a filter group
cy.get_open_dialog().get(`.frappe-control[data-fieldname="filter_area"]`).should('exist');
cy.get_open_dialog().get(`.frappe-control[data-fieldname="filter_area"]`).should("exist");
});
it('checks for child item selection', () => {
cy.get_open_dialog()
.get(`.dt-row-header`).should('not.exist');
it("checks for child item selection", () => {
cy.get_open_dialog().get(`.dt-row-header`).should("not.exist");
cy.get_open_dialog()
.get(`.frappe-control[data-fieldname="allow_child_item_selection"]`)
.find('input[data-fieldname="allow_child_item_selection"]')
.should('exist')
.click({force: true});
.should("exist")
.click({ force: true });
cy.get_open_dialog()
.get(`.frappe-control[data-fieldname="child_selection_area"]`)
.should('exist');
.should("exist");
cy.get_open_dialog()
.get(`.dt-row-header`).should('contain', 'Contact');
cy.get_open_dialog().get(`.dt-row-header`).should("contain", "Contact");
cy.get_open_dialog()
.get(`.dt-row-header`).should('contain', 'Email Id');
cy.get_open_dialog().get(`.dt-row-header`).should("contain", "Email Id");
cy.get_open_dialog()
.get(`.dt-row-header`).should('contain', 'Is Primary');
cy.get_open_dialog().get(`.dt-row-header`).should("contain", "Is Primary");
});
it('tests more button', () => {
it("tests more button", () => {
cy.get_open_dialog()
.get(`.frappe-control[data-fieldname="more_child_btn"]`)
.should('exist')
.as('more-btn');
cy.get_open_dialog().get('.datatable .dt-scrollable .dt-row').should(($rows) => {
expect($rows).to.have.length(20);
});
.should("exist")
.as("more-btn");
cy.intercept('POST', 'api/method/frappe.client.get_list').as('get-more-records');
cy.get('@more-btn').find('button').click({force: true});
cy.wait('@get-more-records');
cy.get_open_dialog()
.get(".datatable .dt-scrollable .dt-row")
.should(($rows) => {
expect($rows).to.have.length(20);
});
cy.get_open_dialog().get('.datatable .dt-scrollable .dt-row').should(($rows) => {
if ($rows.length <= 20) {
throw new Error("More button doesn't work");
}
});
cy.intercept("POST", "api/method/frappe.client.get_list").as("get-more-records");
cy.get("@more-btn").find("button").click({ force: true });
cy.wait("@get-more-records");
cy.get_open_dialog()
.get(".datatable .dt-scrollable .dt-row")
.should(($rows) => {
if ($rows.length <= 20) {
throw new Error("More button doesn't work");
}
});
});
});
});

View File

@ -1,25 +1,29 @@
context('Navigation', () => {
context("Navigation", () => {
before(() => {
cy.login();
});
it('Navigate to route with hash in document name', () => {
cy.insert_doc('ToDo', {'__newname': 'ABC#123', 'description': 'Test this', 'ignore_duplicate': true});
cy.visit('/app/todo/ABC#123');
cy.title().should('eq', 'Test this - ABC#123');
cy.get_field('description', 'Text Editor').contains('Test this');
cy.go('back');
cy.title().should('eq', 'Website');
it("Navigate to route with hash in document name", () => {
cy.insert_doc("ToDo", {
__newname: "ABC#123",
description: "Test this",
ignore_duplicate: true,
});
cy.visit("/app/todo/ABC#123");
cy.title().should("eq", "Test this - ABC#123");
cy.get_field("description", "Text Editor").contains("Test this");
cy.go("back");
cy.title().should("eq", "Website");
});
it.only('Navigate to previous page after login', () => {
cy.visit('/app/todo');
cy.get('.page-head').findByTitle('To Do').should('be.visible');
cy.request('/api/method/logout');
cy.reload().as('reload');
cy.get('@reload').get('.page-card .btn-primary').contains('Login').click();
cy.location('pathname').should('eq', '/login');
it.only("Navigate to previous page after login", () => {
cy.visit("/app/todo");
cy.get(".page-head").findByTitle("To Do").should("be.visible");
cy.request("/api/method/logout");
cy.reload().as("reload");
cy.get("@reload").get(".page-card .btn-primary").contains("Login").click();
cy.location("pathname").should("eq", "/login");
cy.login();
cy.visit('/app');
cy.location('pathname').should('eq', '/app/todo');
cy.visit("/app");
cy.location("pathname").should("eq", "/app/todo");
});
});

View File

@ -1,22 +1,22 @@
context('Number Card', () => {
context("Number Card", () => {
before(() => {
cy.login();
cy.visit('/app/website');
cy.visit("/app/website");
});
it('Check filter populate for child table doctype', () => {
cy.visit('/app/number-card/new-number-card-1');
cy.get('[data-fieldname="parent_document_type"]').should('have.css', 'display', 'none');
it("Check filter populate for child table doctype", () => {
cy.visit("/app/number-card/new-number-card-1");
cy.get('[data-fieldname="parent_document_type"]').should("have.css", "display", "none");
cy.get_field('document_type', 'Link');
cy.fill_field('document_type', 'Workspace Link', 'Link').focus().blur();
cy.get_field('document_type', 'Link').should('have.value', 'Workspace Link');
cy.get_field("document_type", "Link");
cy.fill_field("document_type", "Workspace Link", "Link").focus().blur();
cy.get_field("document_type", "Link").should("have.value", "Workspace Link");
cy.fill_field('label', 'Test Number Card', 'Data');
cy.fill_field("label", "Test Number Card", "Data");
cy.get('[data-fieldname="filters_json"]').click().wait(200);
cy.get('.modal-body .filter-action-buttons .add-filter').click();
cy.get('.modal-body .fieldname-select-area').click();
cy.get('.modal-actions .btn-modal-close').click();
cy.get(".modal-body .filter-action-buttons .add-filter").click();
cy.get(".modal-body .fieldname-select-area").click();
cy.get(".modal-actions .btn-modal-close").click();
});
});
});

View File

@ -1,63 +1,91 @@
context('Query Report', () => {
context("Query Report", () => {
before(() => {
cy.login();
cy.visit('/app/website');
cy.insert_doc('Report', {
'report_name': 'Test ToDo Report',
'ref_doctype': 'ToDo',
'report_type': 'Query Report',
'query': 'select * from tabToDo'
}, true).as('doc');
cy.visit("/app/website");
cy.insert_doc(
"Report",
{
report_name: "Test ToDo Report",
ref_doctype: "ToDo",
report_type: "Query Report",
query: "select * from tabToDo",
},
true
).as("doc");
cy.create_records({
doctype: 'ToDo',
description: 'this is a test todo for query report'
}).as('todos');
doctype: "ToDo",
description: "this is a test todo for query report",
}).as("todos");
});
it('add custom column in report', () => {
cy.visit('/app/query-report/Permitted Documents For User');
it("add custom column in report", () => {
cy.visit("/app/query-report/Permitted Documents For User");
cy.get('.page-form.flex', { timeout: 60000 }).should('have.length', 1).then(() => {
cy.get('#page-query-report input[data-fieldname="user"]').as('input-user');
cy.get('@input-user').focus().type('test@erpnext.com', { delay: 100 }).blur();
cy.wait(300);
cy.get('#page-query-report input[data-fieldname="doctype"]').as('input-role');
cy.get('@input-role').focus().type('Role', { delay: 100 }).blur();
cy.get(".page-form.flex", { timeout: 60000 })
.should("have.length", 1)
.then(() => {
cy.get('#page-query-report input[data-fieldname="user"]').as("input-user");
cy.get("@input-user").focus().type("test@erpnext.com", { delay: 100 }).blur();
cy.wait(300);
cy.get('#page-query-report input[data-fieldname="doctype"]').as("input-role");
cy.get("@input-role").focus().type("Role", { delay: 100 }).blur();
cy.get('.datatable').should('exist');
cy.get('#page-query-report .page-actions .menu-btn-group button').click({ force: true });
cy.get('#page-query-report .menu-btn-group .dropdown-menu').contains('Add Column').click({ force: true });
cy.get_open_dialog().get('.modal-title').should('contain', 'Add Column');
cy.get('select[data-fieldname="doctype"]').select("Role", { force: true });
cy.get('select[data-fieldname="field"]').select("Role Name", { force: true });
cy.get('select[data-fieldname="insert_after"]').select("Name", { force: true });
cy.get_open_dialog().findByRole('button', {name: 'Submit'}).click({ force: true });
cy.get('#page-query-report .page-actions .menu-btn-group button').click({ force: true });
cy.get('#page-query-report .menu-btn-group .dropdown-menu').contains('Save').click({ timeout: 100, force: true });
cy.get_open_dialog().get('.modal-title').should('contain', 'Save Report');
cy.get(".datatable").should("exist");
cy.get("#page-query-report .page-actions .menu-btn-group button").click({
force: true,
});
cy.get("#page-query-report .menu-btn-group .dropdown-menu")
.contains("Add Column")
.click({ force: true });
cy.get_open_dialog().get(".modal-title").should("contain", "Add Column");
cy.get('select[data-fieldname="doctype"]').select("Role", { force: true });
cy.get('select[data-fieldname="field"]').select("Role Name", { force: true });
cy.get('select[data-fieldname="insert_after"]').select("Name", { force: true });
cy.get_open_dialog()
.findByRole("button", { name: "Submit" })
.click({ force: true });
cy.get("#page-query-report .page-actions .menu-btn-group button").click({
force: true,
});
cy.get("#page-query-report .menu-btn-group .dropdown-menu")
.contains("Save")
.click({ timeout: 100, force: true });
cy.get_open_dialog().get(".modal-title").should("contain", "Save Report");
cy.get('input[data-fieldname="report_name"]').type("Test Report", { delay: 100, force: true });
cy.get_open_dialog().findByRole('button', {name: 'Submit'}).click({ timeout: 1000, force: true });
});
cy.get('input[data-fieldname="report_name"]').type("Test Report", {
delay: 100,
force: true,
});
cy.get_open_dialog()
.findByRole("button", { name: "Submit" })
.click({ timeout: 1000, force: true });
});
});
let save_report_and_open = (report, update_name) => {
cy.get('#page-query-report .page-actions .menu-btn-group button').click({ force: true });
cy.get('#page-query-report .menu-btn-group .dropdown-menu').contains('Save').click({ timeout: 100, force: true });
cy.get_open_dialog().get('.modal-title').should('contain', 'Save Report');
cy.get("#page-query-report .page-actions .menu-btn-group button").click({ force: true });
cy.get("#page-query-report .menu-btn-group .dropdown-menu")
.contains("Save")
.click({ timeout: 100, force: true });
cy.get_open_dialog().get(".modal-title").should("contain", "Save Report");
cy.get('input[data-fieldname="report_name"]').type(update_name, { delay: 100, force: true });
cy.get_open_dialog().findByRole('button', {name: 'Submit'}).click({ timeout: 1000, force: true });
cy.get('input[data-fieldname="report_name"]').type(update_name, {
delay: 100,
force: true,
});
cy.get_open_dialog()
.findByRole("button", { name: "Submit" })
.click({ timeout: 1000, force: true });
cy.visit('/app/query-report/'+report);
cy.get('.datatable').should('exist');
cy.visit("/app/query-report/" + report);
cy.get(".datatable").should("exist");
};
it('test multi level query report', () => {
cy.visit('/app/query-report/Test ToDo Report');
cy.get('.datatable').should('exist');
it("test multi level query report", () => {
cy.visit("/app/query-report/Test ToDo Report");
cy.get(".datatable").should("exist");
save_report_and_open('Test ToDo Report 1', ' 1');
save_report_and_open('Test ToDo Report 11', '1');
save_report_and_open("Test ToDo Report 1", " 1");
save_report_and_open("Test ToDo Report 11", "1");
});
});
});

View File

@ -1,66 +1,72 @@
context.skip('Recorder', () => {
context.skip("Recorder", () => {
before(() => {
cy.login();
});
beforeEach(() => {
cy.visit('/app/recorder');
return cy.window().its('frappe').then(frappe => {
// reset recorder
return frappe.xcall("frappe.recorder.stop").then(() => {
return frappe.xcall("frappe.recorder.delete");
cy.visit("/app/recorder");
return cy
.window()
.its("frappe")
.then((frappe) => {
// reset recorder
return frappe.xcall("frappe.recorder.stop").then(() => {
return frappe.xcall("frappe.recorder.delete");
});
});
});
});
it('Recorder Empty State', () => {
cy.get('.page-head').findByTitle('Recorder').should('exist');
it("Recorder Empty State", () => {
cy.get(".page-head").findByTitle("Recorder").should("exist");
cy.get('.indicator-pill').should('contain', 'Inactive').should('have.class', 'red');
cy.get(".indicator-pill").should("contain", "Inactive").should("have.class", "red");
cy.get('.page-actions').findByRole('button', {name: 'Start'}).should('exist');
cy.get('.page-actions').findByRole('button', {name: 'Clear'}).should('exist');
cy.get(".page-actions").findByRole("button", { name: "Start" }).should("exist");
cy.get(".page-actions").findByRole("button", { name: "Clear" }).should("exist");
cy.get('.msg-box').should('contain', 'Recorder is Inactive');
cy.get('.msg-box').findByRole('button', {name: 'Start Recording'}).should('exist');
cy.get(".msg-box").should("contain", "Recorder is Inactive");
cy.get(".msg-box").findByRole("button", { name: "Start Recording" }).should("exist");
});
it('Recorder Start', () => {
cy.get('.page-actions').findByRole('button', {name: 'Start'}).click();
cy.get('.indicator-pill').should('contain', 'Active').should('have.class', 'green');
it("Recorder Start", () => {
cy.get(".page-actions").findByRole("button", { name: "Start" }).click();
cy.get(".indicator-pill").should("contain", "Active").should("have.class", "green");
cy.get('.msg-box').should('contain', 'No Requests found');
cy.get(".msg-box").should("contain", "No Requests found");
cy.visit('/app/List/DocType/List');
cy.intercept('POST', '/api/method/frappe.desk.reportview.get').as('list_refresh');
cy.wait('@list_refresh');
cy.visit("/app/List/DocType/List");
cy.intercept("POST", "/api/method/frappe.desk.reportview.get").as("list_refresh");
cy.wait("@list_refresh");
cy.get('.page-head').findByTitle('DocType').should('exist');
cy.get('.list-count').should('contain', '20 of ');
cy.get(".page-head").findByTitle("DocType").should("exist");
cy.get(".list-count").should("contain", "20 of ");
cy.visit('/app/recorder');
cy.get('.page-head').findByTitle('Recorder').should('exist');
cy.get('.frappe-list .result-list').should('contain', '/api/method/frappe.desk.reportview.get');
cy.visit("/app/recorder");
cy.get(".page-head").findByTitle("Recorder").should("exist");
cy.get(".frappe-list .result-list").should(
"contain",
"/api/method/frappe.desk.reportview.get"
);
});
it('Recorder View Request', () => {
cy.get('.page-actions').findByRole('button', {name: 'Start'}).click();
it("Recorder View Request", () => {
cy.get(".page-actions").findByRole("button", { name: "Start" }).click();
cy.visit('/app/List/DocType/List');
cy.intercept('POST', '/api/method/frappe.desk.reportview.get').as('list_refresh');
cy.wait('@list_refresh');
cy.visit("/app/List/DocType/List");
cy.intercept("POST", "/api/method/frappe.desk.reportview.get").as("list_refresh");
cy.wait("@list_refresh");
cy.get('.page-head').findByTitle('DocType').should('exist');
cy.get('.list-count').should('contain', '20 of ');
cy.get(".page-head").findByTitle("DocType").should("exist");
cy.get(".list-count").should("contain", "20 of ");
cy.visit('/app/recorder');
cy.visit("/app/recorder");
cy.get('.frappe-list .list-row-container span')
.contains('/api/method/frappe')
.should('be.visible')
.click({force: true});
cy.get(".frappe-list .list-row-container span")
.contains("/api/method/frappe")
.should("be.visible")
.click({ force: true });
cy.url().should('include', '/recorder/request');
cy.get('form').should('contain', '/api/method/frappe');
cy.url().should("include", "/recorder/request");
cy.get("form").should("contain", "/api/method/frappe");
});
});

View File

@ -1,42 +1,46 @@
import custom_submittable_doctype from '../fixtures/custom_submittable_doctype';
import custom_submittable_doctype from "../fixtures/custom_submittable_doctype";
const doctype_name = custom_submittable_doctype.name;
context('Report View', () => {
context("Report View", () => {
before(() => {
cy.login();
cy.visit('/app/website');
cy.insert_doc('DocType', custom_submittable_doctype, true);
cy.visit("/app/website");
cy.insert_doc("DocType", custom_submittable_doctype, true);
cy.clear_cache();
cy.insert_doc(doctype_name, {
'title': 'Doc 1',
'description': 'Random Text',
'enabled': 0,
'docstatus': 1 // submit document
}, true);
cy.insert_doc(
doctype_name,
{
title: "Doc 1",
description: "Random Text",
enabled: 0,
docstatus: 1, // submit document
},
true
);
});
it('Field with enabled allow_on_submit should be editable.', () => {
cy.intercept('POST', 'api/method/frappe.client.set_value').as('value-update');
it("Field with enabled allow_on_submit should be editable.", () => {
cy.intercept("POST", "api/method/frappe.client.set_value").as("value-update");
cy.visit(`/app/List/${doctype_name}/Report`);
// check status column added from docstatus
cy.get('.dt-row-0 > .dt-cell--col-3').should('contain', 'Submitted');
let cell = cy.get('.dt-row-0 > .dt-cell--col-4');
cy.get(".dt-row-0 > .dt-cell--col-3").should("contain", "Submitted");
let cell = cy.get(".dt-row-0 > .dt-cell--col-4");
// select the cell
cell.dblclick();
cell.get('.dt-cell__edit--col-4').findByRole('checkbox').check({ force: true });
cy.get('.dt-row-0 > .dt-cell--col-3').click(); // click outside
cell.get(".dt-cell__edit--col-4").findByRole("checkbox").check({ force: true });
cy.get(".dt-row-0 > .dt-cell--col-3").click(); // click outside
cy.wait('@value-update');
cy.wait("@value-update");
cy.call('frappe.client.get_value', {
cy.call("frappe.client.get_value", {
doctype: doctype_name,
filters: {
title: 'Doc 1',
title: "Doc 1",
},
fieldname: 'enabled'
}).then(r => {
fieldname: "enabled",
}).then((r) => {
expect(r.message.enabled).to.equals(1);
});
});

View File

@ -1,55 +1,64 @@
context('Sidebar', () => {
context("Sidebar", () => {
before(() => {
cy.visit('/login');
cy.visit("/login");
cy.login();
cy.visit('/app/doctype');
cy.visit("/app/doctype");
});
it('Test for checking "Assigned To" counter value, adding filter and adding & removing an assignment', () => {
cy.click_sidebar_button("Assigned To");
//To check if no filter is available in "Assigned To" dropdown
cy.get('.empty-state').should('contain', 'No filters found');
cy.get(".empty-state").should("contain", "No filters found");
cy.click_sidebar_button("Created By");
//To check if "Created By" dropdown contains filter
cy.get('.group-by-item > .dropdown-item').should('contain', 'Me');
cy.get(".group-by-item > .dropdown-item").should("contain", "Me");
//Assigning a doctype to a user
cy.visit('/app/doctype/ToDo');
cy.get('.form-assignments > .flex > .text-muted').click();
cy.get_field('assign_to_me', 'Check').click();
cy.get('.modal-footer > .standard-actions > .btn-primary').click();
cy.visit('/app/doctype');
cy.visit("/app/doctype/ToDo");
cy.get(".form-assignments > .flex > .text-muted").click();
cy.get_field("assign_to_me", "Check").click();
cy.get(".modal-footer > .standard-actions > .btn-primary").click();
cy.visit("/app/doctype");
cy.click_sidebar_button("Assigned To");
//To check if filter is added in "Assigned To" dropdown after assignment
cy.get('.group-by-field.show > .dropdown-menu > .group-by-item > .dropdown-item').should('contain', '1');
cy.get(".group-by-field.show > .dropdown-menu > .group-by-item > .dropdown-item").should(
"contain",
"1"
);
//To check if there is no filter added to the listview
cy.get('.filter-selector > .btn').should('contain', 'Filter');
cy.get(".filter-selector > .btn").should("contain", "Filter");
//To add a filter to display data into the listview
cy.get('.group-by-field.show > .dropdown-menu > .group-by-item > .dropdown-item').click();
cy.get(".group-by-field.show > .dropdown-menu > .group-by-item > .dropdown-item").click();
//To check if filter is applied
cy.click_filter_button().should('contain', '1 filter');
cy.get('.fieldname-select-area > .awesomplete > .form-control').should('have.value', 'Assigned To');
cy.get('.condition').should('have.value', 'like');
cy.get('.filter-field > .form-group > .input-with-feedback').should('have.value', '%Administrator%');
cy.click_filter_button().should("contain", "1 filter");
cy.get(".fieldname-select-area > .awesomplete > .form-control").should(
"have.value",
"Assigned To"
);
cy.get(".condition").should("have.value", "like");
cy.get(".filter-field > .form-group > .input-with-feedback").should(
"have.value",
"%Administrator%"
);
cy.click_filter_button();
//To remove the applied filter
cy.clear_filters();
//To remove the assignment
cy.visit('/app/doctype/ToDo');
cy.get('.assignments > .avatar-group > .avatar > .avatar-frame').click();
cy.get('.remove-btn').click({force: true});
cy.visit("/app/doctype/ToDo");
cy.get(".assignments > .avatar-group > .avatar > .avatar-frame").click();
cy.get(".remove-btn").click({ force: true });
cy.hide_dialog();
cy.visit('/app/doctype');
cy.visit("/app/doctype");
cy.click_sidebar_button("Assigned To");
cy.get('.empty-state').should('contain', 'No filters found');
cy.get(".empty-state").should("contain", "No filters found");
});
});

View File

@ -1,51 +1,57 @@
context('Table MultiSelect', () => {
context("Table MultiSelect", () => {
before(() => {
cy.login();
});
let name = 'table multiselect' + Math.random().toString().slice(2, 8);
let name = "table multiselect" + Math.random().toString().slice(2, 8);
it('select value from multiselect dropdown', () => {
cy.new_form('Assignment Rule');
cy.fill_field('__newname', name);
cy.fill_field('document_type', 'Blog Post');
cy.get('.section-head').contains('Assignment Rules').scrollIntoView();
cy.fill_field('assign_condition', 'status=="Open"', 'Code');
cy.get('input[data-fieldname="users"]').focus().as('input');
cy.get('input[data-fieldname="users"] + ul').should('be.visible');
cy.get('@input').type('test{enter}', { delay: 100 });
cy.get('.frappe-control[data-fieldname="users"] .form-control .tb-selected-value .btn-link-to-form')
.as('selected-value');
cy.get('@selected-value').should('contain', 'test@erpnext.com');
it("select value from multiselect dropdown", () => {
cy.new_form("Assignment Rule");
cy.fill_field("__newname", name);
cy.fill_field("document_type", "Blog Post");
cy.get(".section-head").contains("Assignment Rules").scrollIntoView();
cy.fill_field("assign_condition", 'status=="Open"', "Code");
cy.get('input[data-fieldname="users"]').focus().as("input");
cy.get('input[data-fieldname="users"] + ul').should("be.visible");
cy.get("@input").type("test{enter}", { delay: 100 });
cy.get(
'.frappe-control[data-fieldname="users"] .form-control .tb-selected-value .btn-link-to-form'
).as("selected-value");
cy.get("@selected-value").should("contain", "test@erpnext.com");
cy.intercept('POST', '/api/method/frappe.desk.form.save.savedocs').as('save_form');
cy.intercept("POST", "/api/method/frappe.desk.form.save.savedocs").as("save_form");
// trigger save
cy.get('.primary-action').click();
cy.wait('@save_form').its('response.statusCode').should('eq', 200);
cy.get('@selected-value').should('contain', 'test@erpnext.com');
cy.get(".primary-action").click();
cy.wait("@save_form").its("response.statusCode").should("eq", 200);
cy.get("@selected-value").should("contain", "test@erpnext.com");
});
it('delete value using backspace', () => {
cy.go_to_list('Assignment Rule');
cy.get(`.list-subject:contains("table multiselect")`).last().find('a').click();
cy.get('input[data-fieldname="users"]').focus().type('{backspace}');
cy.get('.frappe-control[data-fieldname="users"] .form-control .tb-selected-value')
.should('not.exist');
it("delete value using backspace", () => {
cy.go_to_list("Assignment Rule");
cy.get(`.list-subject:contains("table multiselect")`).last().find("a").click();
cy.get('input[data-fieldname="users"]').focus().type("{backspace}");
cy.get('.frappe-control[data-fieldname="users"] .form-control .tb-selected-value').should(
"not.exist"
);
});
it('delete value using x', () => {
cy.go_to_list('Assignment Rule');
cy.get(`.list-subject:contains("table multiselect")`).last().find('a').click();
cy.get('.frappe-control[data-fieldname="users"] .form-control .tb-selected-value').as('existing_value');
cy.get('@existing_value').find('.btn-remove').click();
cy.get('@existing_value').should('not.exist');
it("delete value using x", () => {
cy.go_to_list("Assignment Rule");
cy.get(`.list-subject:contains("table multiselect")`).last().find("a").click();
cy.get('.frappe-control[data-fieldname="users"] .form-control .tb-selected-value').as(
"existing_value"
);
cy.get("@existing_value").find(".btn-remove").click();
cy.get("@existing_value").should("not.exist");
});
it('navigate to selected value', () => {
cy.go_to_list('Assignment Rule');
cy.get(`.list-subject:contains("table multiselect")`).last().find('a').click();
cy.get('.frappe-control[data-fieldname="users"] .form-control .tb-selected-value').as('existing_value');
cy.get('@existing_value').find('.btn-link-to-form').click();
cy.location('pathname').should('contain', '/user/test@erpnext.com');
it("navigate to selected value", () => {
cy.go_to_list("Assignment Rule");
cy.get(`.list-subject:contains("table multiselect")`).last().find("a").click();
cy.get('.frappe-control[data-fieldname="users"] .form-control .tb-selected-value').as(
"existing_value"
);
cy.get("@existing_value").find(".btn-link-to-form").click();
cy.location("pathname").should("contain", "/user/test@erpnext.com");
});
});
});

View File

@ -1,30 +1,29 @@
context('Theme Switcher Shortcut', () => {
context("Theme Switcher Shortcut", () => {
before(() => {
cy.login();
cy.visit('/app');
cy.visit("/app");
});
beforeEach(() => {
cy.reload();
});
it('Check Toggle', () => {
cy.open_theme_dialog('{ctrl+shift+g}');
cy.get('.modal-backdrop').should('exist');
cy.get('.theme-grid > div').first().click();
cy.close_theme('{ctrl+shift+g}');
cy.get('.modal-backdrop').should('not.exist');
it("Check Toggle", () => {
cy.open_theme_dialog("{ctrl+shift+g}");
cy.get(".modal-backdrop").should("exist");
cy.get(".theme-grid > div").first().click();
cy.close_theme("{ctrl+shift+g}");
cy.get(".modal-backdrop").should("not.exist");
});
it('Check Enter', () => {
cy.open_theme_dialog('{ctrl+shift+g}');
cy.get('.theme-grid > div').first().click();
cy.close_theme('{enter}');
cy.get('.modal-backdrop').should('not.exist');
it("Check Enter", () => {
cy.open_theme_dialog("{ctrl+shift+g}");
cy.get(".theme-grid > div").first().click();
cy.close_theme("{enter}");
cy.get(".modal-backdrop").should("not.exist");
});
});
Cypress.Commands.add('open_theme_dialog', (shortcut_keys) => {
cy.get('body').type(shortcut_keys);
Cypress.Commands.add("open_theme_dialog", (shortcut_keys) => {
cy.get("body").type(shortcut_keys);
});
Cypress.Commands.add("close_theme", (shortcut_keys) => {
cy.get(".modal-header").type(shortcut_keys);
});
Cypress.Commands.add('close_theme', (shortcut_keys) => {
cy.get('.modal-header').type(shortcut_keys);
});

View File

@ -1,83 +1,91 @@
import custom_submittable_doctype from '../fixtures/custom_submittable_doctype';
import custom_submittable_doctype from "../fixtures/custom_submittable_doctype";
context('Timeline', () => {
context("Timeline", () => {
before(() => {
cy.visit('/login');
cy.visit("/login");
cy.login();
});
it('Adding new ToDo, adding new comment, verifying comment addition & deletion and deleting ToDo', () => {
it("Adding new ToDo, adding new comment, verifying comment addition & deletion and deleting ToDo", () => {
//Adding new ToDo
cy.visit('/app/todo/new-todo-1');
cy.get('[data-fieldname="description"] .ql-editor.ql-blank').type('Test ToDo', {force: true}).wait(200);
cy.get('.page-head .page-actions').findByRole('button', {name: 'Save'}).click();
cy.visit("/app/todo/new-todo-1");
cy.get('[data-fieldname="description"] .ql-editor.ql-blank')
.type("Test ToDo", { force: true })
.wait(200);
cy.get(".page-head .page-actions").findByRole("button", { name: "Save" }).click();
cy.go_to_list('ToDo');
cy.clear_filters()
cy.go_to_list("ToDo");
cy.clear_filters();
cy.click_listview_row_item(0);
//To check if the comment box is initially empty and tying some text into it
cy.get('[data-fieldname="comment"] .ql-editor').should('contain', '').type('Testing Timeline');
cy.get('[data-fieldname="comment"] .ql-editor')
.should("contain", "")
.type("Testing Timeline");
//Adding new comment
cy.get('.comment-box').findByRole('button', {name: 'Comment'}).click();
cy.get(".comment-box").findByRole("button", { name: "Comment" }).click();
//To check if the commented text is visible in the timeline content
cy.get('.timeline-content').should('contain', 'Testing Timeline');
cy.get(".timeline-content").should("contain", "Testing Timeline");
//Editing comment
cy.click_timeline_action_btn("Edit");
cy.get('.timeline-content [data-fieldname="comment"] .ql-editor').first().type(' 123');
cy.get('.timeline-content [data-fieldname="comment"] .ql-editor').first().type(" 123");
cy.click_timeline_action_btn("Save");
//To check if the edited comment text is visible in timeline content
cy.get('.timeline-content').should('contain', 'Testing Timeline 123');
cy.get(".timeline-content").should("contain", "Testing Timeline 123");
//Discarding comment
cy.click_timeline_action_btn("Edit");
cy.click_timeline_action_btn("Dismiss");
//To check if after discarding the timeline content is same as previous
cy.get('.timeline-content').should('contain', 'Testing Timeline 123');
cy.get(".timeline-content").should("contain", "Testing Timeline 123");
//Deleting the added comment
cy.get('.timeline-message-box .more-actions > .action-btn').click(); //Menu button in timeline item
cy.get('.timeline-message-box .more-actions .dropdown-item').contains('Delete').click({ force: true });
cy.get_open_dialog().findByRole('button', {name: 'Yes'}).click({ force: true });
cy.get(".timeline-message-box .more-actions > .action-btn").click(); //Menu button in timeline item
cy.get(".timeline-message-box .more-actions .dropdown-item")
.contains("Delete")
.click({ force: true });
cy.get_open_dialog().findByRole("button", { name: "Yes" }).click({ force: true });
cy.get('.timeline-content').should('not.contain', 'Testing Timeline 123');
cy.get(".timeline-content").should("not.contain", "Testing Timeline 123");
});
it('Timeline should have submit and cancel activity information', () => {
cy.visit('/app/doctype');
it("Timeline should have submit and cancel activity information", () => {
cy.visit("/app/doctype");
//Creating custom doctype
cy.insert_doc('DocType', custom_submittable_doctype, true);
cy.insert_doc("DocType", custom_submittable_doctype, true);
cy.visit('/app/custom-submittable-doctype');
cy.click_listview_primary_button('Add Custom Submittable DocType');
cy.visit("/app/custom-submittable-doctype");
cy.click_listview_primary_button("Add Custom Submittable DocType");
//Adding a new entry for the created custom doctype
cy.fill_field('title', 'Test');
cy.click_modal_primary_button('Save');
cy.click_modal_primary_button('Submit');
cy.fill_field("title", "Test");
cy.click_modal_primary_button("Save");
cy.click_modal_primary_button("Submit");
cy.visit('/app/custom-submittable-doctype');
cy.visit("/app/custom-submittable-doctype");
cy.click_listview_row_item(0);
//To check if the submission of the documemt is visible in the timeline content
cy.get('.timeline-content').should('contain', 'Administrator submitted this document');
cy.get('[id="page-Custom Submittable DocType"] .page-actions').findByRole('button', {name: 'Cancel'}).click();
cy.get_open_dialog().findByRole('button', {name: 'Yes'}).click();
cy.get(".timeline-content").should("contain", "Administrator submitted this document");
cy.get('[id="page-Custom Submittable DocType"] .page-actions')
.findByRole("button", { name: "Cancel" })
.click();
cy.get_open_dialog().findByRole("button", { name: "Yes" }).click();
//To check if the cancellation of the documemt is visible in the timeline content
cy.get('.timeline-content').should('contain', 'Administrator cancelled this document');
cy.get(".timeline-content").should("contain", "Administrator cancelled this document");
//Deleting the document
cy.visit('/app/custom-submittable-doctype');
cy.visit("/app/custom-submittable-doctype");
cy.select_listview_row_checkbox(0);
cy.get('.page-actions').findByRole('button', {name: 'Actions'}).click();
cy.get(".page-actions").findByRole("button", { name: "Actions" }).click();
cy.get('.page-actions .actions-btn-group [data-label="Delete"]').click();
cy.click_modal_primary_button('Yes');
cy.click_modal_primary_button("Yes");
});
});

View File

@ -1,76 +1,93 @@
context('Timeline Email', () => {
context("Timeline Email", () => {
before(() => {
cy.visit('/login');
cy.visit("/login");
cy.login();
cy.visit('/app/todo');
cy.visit("/app/todo");
});
it('Adding new ToDo', () => {
cy.click_listview_primary_button('Add ToDo');
cy.get('.custom-actions:visible > .btn').contains("Edit Full Form").click({delay: 500});
cy.fill_field("description", "Test ToDo", "Text Editor");
it("Adding new ToDo", () => {
cy.click_listview_primary_button("Add ToDo");
cy.get(".custom-actions:visible > .btn").contains("Edit Full Form").click({ delay: 500 });
cy.fill_field("description", "Test ToDo", "Text Editor");
cy.wait(500);
cy.get('.primary-action').contains('Save').click({force: true});
cy.get(".primary-action").contains("Save").click({ force: true });
cy.wait(700);
});
it('Adding email and verifying timeline content for email attachment', () => {
cy.visit('/app/todo');
cy.click_listview_row_item_with_text('Test ToDo');
it("Adding email and verifying timeline content for email attachment", () => {
cy.visit("/app/todo");
cy.click_listview_row_item_with_text("Test ToDo");
//Creating a new email
cy.get('.timeline-actions > .timeline-item > .action-buttons > .action-btn').click();
cy.fill_field('recipients', 'test@example.com', 'MultiSelect');
cy.get('.modal.show > .modal-dialog > .modal-content > .modal-body > :nth-child(1) > .form-layout > .form-page > :nth-child(3) > .section-body > .form-column > form > [data-fieldtype="Text Editor"] > .form-group > .control-input-wrapper > .control-input > .ql-container > .ql-editor').type('Test Mail');
cy.get(".timeline-actions > .timeline-item > .action-buttons > .action-btn").click();
cy.fill_field("recipients", "test@example.com", "MultiSelect");
cy.get(
'.modal.show > .modal-dialog > .modal-content > .modal-body > :nth-child(1) > .form-layout > .form-page > :nth-child(3) > .section-body > .form-column > form > [data-fieldtype="Text Editor"] > .form-group > .control-input-wrapper > .control-input > .ql-container > .ql-editor'
).type("Test Mail");
//Adding attachment to the email
cy.get('.add-more-attachments > .btn').click();
cy.get('.mt-2 > .btn > .mt-1').eq(2).click();
cy.get('.input-group > .form-control').type('https://wallpaperplay.com/walls/full/8/2/b/72402.jpg');
cy.get('.btn-primary').contains('Upload').click();
cy.get(".add-more-attachments > .btn").click();
cy.get(".mt-2 > .btn > .mt-1").eq(2).click();
cy.get(".input-group > .form-control").type(
"https://wallpaperplay.com/walls/full/8/2/b/72402.jpg"
);
cy.get(".btn-primary").contains("Upload").click();
//Sending the email
cy.click_modal_primary_button('Send', {delay: 500});
cy.click_modal_primary_button("Send", { delay: 500 });
//To check if the sent mail content is shown in the timeline content
cy.get('[data-doctype="Communication"] > .timeline-content').should('contain', 'Test Mail');
cy.get('[data-doctype="Communication"] > .timeline-content').should(
"contain",
"Test Mail"
);
//To check if the attachment of email is shown in the timeline content
cy.get('.timeline-content').should('contain', 'Added 72402.jpg');
cy.get(".timeline-content").should("contain", "Added 72402.jpg");
//Deleting the sent email
cy.get('[title="Open Communication"] > .icon').first().click({force: true});
cy.get('#page-Communication > .page-head > .container > .row > .col > .standard-actions > .menu-btn-group > .btn').click();
cy.get('#page-Communication > .page-head > .container > .row > .col > .standard-actions > .menu-btn-group > .dropdown-menu > li > .grey-link').eq(9).click();
cy.get('.modal.show > .modal-dialog > .modal-content > .modal-footer > .standard-actions > .btn-primary').click();
cy.get('[title="Open Communication"] > .icon').first().click({ force: true });
cy.get(
"#page-Communication > .page-head > .container > .row > .col > .standard-actions > .menu-btn-group > .btn"
).click();
cy.get(
"#page-Communication > .page-head > .container > .row > .col > .standard-actions > .menu-btn-group > .dropdown-menu > li > .grey-link"
)
.eq(9)
.click();
cy.get(
".modal.show > .modal-dialog > .modal-content > .modal-footer > .standard-actions > .btn-primary"
).click();
});
it('Deleting attachment and ToDo', () => {
cy.visit('/app/todo');
cy.click_listview_row_item_with_text('Test ToDo');
it("Deleting attachment and ToDo", () => {
cy.visit("/app/todo");
cy.click_listview_row_item_with_text("Test ToDo");
//Removing the added attachment
cy.get('.attachment-row > .data-pill > .remove-btn > .icon').click();
cy.get(".attachment-row > .data-pill > .remove-btn > .icon").click();
cy.wait(500);
cy.get('.modal-footer:visible > .standard-actions > .btn-primary').contains('Yes').click();
cy.get(".modal-footer:visible > .standard-actions > .btn-primary").contains("Yes").click();
//To check if the removed attachment is shown in the timeline content
cy.get('.timeline-content').should('contain', 'Removed 72402.jpg');
cy.get(".timeline-content").should("contain", "Removed 72402.jpg");
cy.wait(500);
//To check if the discard button functionality in email is working correctly
cy.get('.timeline-actions > .timeline-item > .action-buttons > .action-btn').click();
cy.fill_field('recipients', 'test@example.com', 'MultiSelect');
cy.get('.modal-footer > .standard-actions > .btn-secondary').contains('Discard').click();
cy.get(".timeline-actions > .timeline-item > .action-buttons > .action-btn").click();
cy.fill_field("recipients", "test@example.com", "MultiSelect");
cy.get(".modal-footer > .standard-actions > .btn-secondary").contains("Discard").click();
cy.wait(500);
cy.get('.timeline-actions > .timeline-item > .action-buttons > .action-btn').click();
cy.get(".timeline-actions > .timeline-item > .action-buttons > .action-btn").click();
cy.wait(500);
cy.get_field('recipients', 'MultiSelect').should('have.text', '');
cy.get('.modal-header:visible > .modal-actions > .btn-modal-close > .icon').click();
cy.get_field("recipients", "MultiSelect").should("have.text", "");
cy.get(".modal-header:visible > .modal-actions > .btn-modal-close > .icon").click();
//Deleting the added ToDo
cy.get('.menu-btn-group:visible > .btn').click();
cy.get('.menu-btn-group:visible > .dropdown-menu > li > .dropdown-item').contains('Delete').click();
cy.get('.modal-footer:visible > .standard-actions > .btn-primary').click();
cy.get(".menu-btn-group:visible > .btn").click();
cy.get(".menu-btn-group:visible > .dropdown-menu > li > .dropdown-item")
.contains("Delete")
.click();
cy.get(".modal-footer:visible > .standard-actions > .btn-primary").click();
});
});

View File

@ -1,43 +1,42 @@
import data_field_validation_doctype from '../fixtures/data_field_validation_doctype';
import data_field_validation_doctype from "../fixtures/data_field_validation_doctype";
const doctype_name = data_field_validation_doctype.name;
context('URL Data Field Input', () => {
context("URL Data Field Input", () => {
before(() => {
cy.login();
cy.visit('/app/website');
return cy.insert_doc('DocType', data_field_validation_doctype, true);
cy.visit("/app/website");
return cy.insert_doc("DocType", data_field_validation_doctype, true);
});
describe('URL Data Field Input ', () => {
it('should not show URL link button without focus', () => {
describe("URL Data Field Input ", () => {
it("should not show URL link button without focus", () => {
cy.new_form(doctype_name);
cy.get_field('url').clear().type('https://frappe.io');
cy.get_field('url').blur().wait(500);
cy.get('.link-btn').should('not.be.visible');
cy.get_field("url").clear().type("https://frappe.io");
cy.get_field("url").blur().wait(500);
cy.get(".link-btn").should("not.be.visible");
});
it('should show URL link button on focus', () => {
cy.get_field('url').focus().wait(500);
cy.get('.link-btn').should('be.visible');
it("should show URL link button on focus", () => {
cy.get_field("url").focus().wait(500);
cy.get(".link-btn").should("be.visible");
});
it('should not show URL link button for invalid URL', () => {
cy.get_field('url').clear().type('fuzzbuzz');
cy.get('.link-btn').should('not.be.visible');
it("should not show URL link button for invalid URL", () => {
cy.get_field("url").clear().type("fuzzbuzz");
cy.get(".link-btn").should("not.be.visible");
});
it('should have valid URL link with target _blank', () => {
cy.get_field('url').clear().type('https://frappe.io');
cy.get('.link-btn .btn-open').should('have.attr', 'href', 'https://frappe.io');
cy.get('.link-btn .btn-open').should('have.attr', 'target', '_blank');
it("should have valid URL link with target _blank", () => {
cy.get_field("url").clear().type("https://frappe.io");
cy.get(".link-btn .btn-open").should("have.attr", "href", "https://frappe.io");
cy.get(".link-btn .btn-open").should("have.attr", "target", "_blank");
});
it('should inject anchor tag in read-only URL data field', () => {
it("should inject anchor tag in read-only URL data field", () => {
cy.get('[data-fieldname="read_only_url"]')
.find('a')
.should('have.attr', 'target', '_blank');
.find("a")
.should("have.attr", "target", "_blank");
});
});
});
});

View File

@ -1,256 +1,270 @@
context('Web Form', () => {
context("Web Form", () => {
before(() => {
cy.login();
});
it('Create Web Form', () => {
cy.visit('/app/web-form/new');
it("Create Web Form", () => {
cy.visit("/app/web-form/new");
cy.intercept('POST', '/api/method/frappe.desk.form.save.savedocs').as('save_form');
cy.intercept("POST", "/api/method/frappe.desk.form.save.savedocs").as("save_form");
cy.fill_field('title', 'Note');
cy.fill_field('doc_type', 'Note', 'Link');
cy.fill_field('module', 'Website', 'Link');
cy.click_custom_action_button('Get Fields');
cy.click_custom_action_button('Publish');
cy.fill_field("title", "Note");
cy.fill_field("doc_type", "Note", "Link");
cy.fill_field("module", "Website", "Link");
cy.click_custom_action_button("Get Fields");
cy.click_custom_action_button("Publish");
cy.wait('@save_form');
cy.wait("@save_form");
cy.get_field('route').should('have.value', 'note');
cy.get('.title-area .indicator-pill').contains('Published');
cy.get_field("route").should("have.value", "note");
cy.get(".title-area .indicator-pill").contains("Published");
});
it('Open Web Form (Logged in User)', () => {
cy.visit('/note');
it("Open Web Form (Logged in User)", () => {
cy.visit("/note");
cy.fill_field('title', 'Note 1');
cy.get('.web-form-actions button').contains('Save').click();
cy.fill_field("title", "Note 1");
cy.get(".web-form-actions button").contains("Save").click();
cy.url().should('include', '/note/Note%201');
cy.url().should("include", "/note/Note%201");
cy.visit('/note');
cy.url().should('include', '/note/Note%201');
cy.visit("/note");
cy.url().should("include", "/note/Note%201");
});
it('Open Web Form (Guest)', () => {
cy.request('/api/method/logout');
cy.visit('/note');
it("Open Web Form (Guest)", () => {
cy.request("/api/method/logout");
cy.visit("/note");
cy.url().should('include', '/note/new');
cy.url().should("include", "/note/new");
cy.fill_field('title', 'Guest Note 1');
cy.get('.web-form-actions button').contains('Save').click();
cy.fill_field("title", "Guest Note 1");
cy.get(".web-form-actions button").contains("Save").click();
cy.url().should('include', '/note/new');
cy.url().should("include", "/note/new");
cy.visit('/note');
cy.url().should('include', '/note/new');
cy.visit("/note");
cy.url().should("include", "/note/new");
});
it('Login Required', () => {
it("Login Required", () => {
cy.login();
cy.visit('/app/web-form/note');
cy.visit("/app/web-form/note");
cy.findByRole("tab", {name: "Form Settings"}).click();
cy.get('input[data-fieldname="login_required"]').check({force: true});
cy.findByRole("tab", { name: "Form Settings" }).click();
cy.get('input[data-fieldname="login_required"]').check({ force: true });
cy.save();
cy.visit('/note');
cy.url().should('include', '/note/Note%201');
cy.visit("/note");
cy.url().should("include", "/note/Note%201");
cy.call('logout');
cy.call("logout");
cy.visit('/note');
cy.visit("/note");
cy.get_open_dialog()
.get('.modal-message')
.contains('You are not permitted to access this page without login.');
.get(".modal-message")
.contains("You are not permitted to access this page without login.");
});
it('Show List', () => {
it("Show List", () => {
cy.login();
cy.visit('/app/web-form/note');
cy.visit("/app/web-form/note");
cy.findByRole("tab", {name: "List Settings"}).click();
cy.findByRole("tab", { name: "List Settings" }).click();
cy.get('input[data-fieldname="show_list"]').check();
cy.save();
cy.visit('/note');
cy.url().should('include', '/note/list');
cy.get('.web-list-table').should('be.visible');
cy.visit("/note");
cy.url().should("include", "/note/list");
cy.get(".web-list-table").should("be.visible");
});
it('Show Custom List Title', () => {
cy.visit('/app/web-form/note');
it("Show Custom List Title", () => {
cy.visit("/app/web-form/note");
cy.findByRole("tab", {name: "List Settings"}).click();
cy.fill_field('list_title', 'Note List');
cy.findByRole("tab", { name: "List Settings" }).click();
cy.fill_field("list_title", "Note List");
cy.save();
cy.visit('/note');
cy.url().should('include', '/note/list');
cy.get('.web-list-header h1').should('contain.text', 'Note List');
cy.visit("/note");
cy.url().should("include", "/note/list");
cy.get(".web-list-header h1").should("contain.text", "Note List");
});
it('Show Custom List Columns', () => {
cy.visit('/note');
cy.url().should('include', '/note/list');
it("Show Custom List Columns", () => {
cy.visit("/note");
cy.url().should("include", "/note/list");
cy.get('.web-list-table thead th').contains('Name');
cy.get('.web-list-table thead th').contains('Title');
cy.get(".web-list-table thead th").contains("Name");
cy.get(".web-list-table thead th").contains("Title");
cy.visit('/app/web-form/note');
cy.visit("/app/web-form/note");
cy.findByRole("tab", {name: "List Settings"}).click();
cy.findByRole("tab", { name: "List Settings" }).click();
cy.get('[data-fieldname="list_columns"] .grid-footer button').contains('Add Row').as('add-row');
cy.get('[data-fieldname="list_columns"] .grid-footer button')
.contains("Add Row")
.as("add-row");
cy.get('@add-row').click();
cy.get('[data-fieldname="list_columns"] .grid-body .rows').as('grid-rows');
cy.get('@grid-rows').find('.grid-row:first [data-fieldname="fieldname"]').click();
cy.get('@grid-rows').find('.grid-row:first select[data-fieldname="fieldname"]').select('Title (Data)');
cy.get("@add-row").click();
cy.get('[data-fieldname="list_columns"] .grid-body .rows').as("grid-rows");
cy.get("@grid-rows").find('.grid-row:first [data-fieldname="fieldname"]').click();
cy.get("@grid-rows")
.find('.grid-row:first select[data-fieldname="fieldname"]')
.select("Title (Data)");
cy.get('@add-row').click();
cy.get('@grid-rows').find('.grid-row[data-idx="2"] [data-fieldname="fieldname"]').click();
cy.get('@grid-rows').find('.grid-row[data-idx="2"] select[data-fieldname="fieldname"]').select('Public (Check)');
cy.get("@add-row").click();
cy.get("@grid-rows").find('.grid-row[data-idx="2"] [data-fieldname="fieldname"]').click();
cy.get("@grid-rows")
.find('.grid-row[data-idx="2"] select[data-fieldname="fieldname"]')
.select("Public (Check)");
cy.get('@add-row').click();
cy.get('@grid-rows').find('.grid-row:last [data-fieldname="fieldname"]').click();
cy.get('@grid-rows').find('.grid-row:last select[data-fieldname="fieldname"]').select('Content (Text Editor)');
cy.get("@add-row").click();
cy.get("@grid-rows").find('.grid-row:last [data-fieldname="fieldname"]').click();
cy.get("@grid-rows")
.find('.grid-row:last select[data-fieldname="fieldname"]')
.select("Content (Text Editor)");
cy.save();
cy.visit('/note');
cy.url().should('include', '/note/list');
cy.get('.web-list-table thead th').contains('Title');
cy.get('.web-list-table thead th').contains('Public');
cy.get('.web-list-table thead th').contains('Content');
cy.visit("/note");
cy.url().should("include", "/note/list");
cy.get(".web-list-table thead th").contains("Title");
cy.get(".web-list-table thead th").contains("Public");
cy.get(".web-list-table thead th").contains("Content");
});
it('Breadcrumbs', () => {
cy.visit('/note/Note 1');
cy.get('.breadcrumb-container .breadcrumb .breadcrumb-item:first a')
.should('contain.text', 'Note').click();
cy.url().should('include', '/note/list');
it("Breadcrumbs", () => {
cy.visit("/note/Note 1");
cy.get(".breadcrumb-container .breadcrumb .breadcrumb-item:first a")
.should("contain.text", "Note")
.click();
cy.url().should("include", "/note/list");
});
it('Custom Breadcrumbs', () => {
cy.visit('/app/web-form/note');
cy.findByRole("tab", {name: "Form Settings"}).click();
cy.get('.form-section .section-head').contains('Customization').click();
cy.fill_field('breadcrumbs', '[{"label": _("Notes"), "route":"note"}]', 'Code');
cy.get('.form-section .section-head').contains('Customization').click();
it("Custom Breadcrumbs", () => {
cy.visit("/app/web-form/note");
cy.findByRole("tab", { name: "Form Settings" }).click();
cy.get(".form-section .section-head").contains("Customization").click();
cy.fill_field("breadcrumbs", '[{"label": _("Notes"), "route":"note"}]', "Code");
cy.get(".form-section .section-head").contains("Customization").click();
cy.save();
cy.visit('/note/Note 1');
cy.get('.breadcrumb-container .breadcrumb .breadcrumb-item:first a')
.should('contain.text', 'Notes');
cy.visit("/note/Note 1");
cy.get(".breadcrumb-container .breadcrumb .breadcrumb-item:first a").should(
"contain.text",
"Notes"
);
});
it('Read Only', () => {
it("Read Only", () => {
cy.login();
cy.visit('/note');
cy.url().should('include', '/note/list');
cy.visit("/note");
cy.url().should("include", "/note/list");
// Read Only Field
cy.get('.web-list-table tbody tr[id="Note 1"]').click();
cy.get('.frappe-control[data-fieldname="title"] .control-input')
.should('have.css', 'display', 'none');
cy.get('.frappe-control[data-fieldname="title"] .control-input').should(
"have.css",
"display",
"none"
);
});
it('Edit Mode', () => {
cy.visit('/app/web-form/note');
it("Edit Mode", () => {
cy.visit("/app/web-form/note");
cy.findByRole("tab", {name: "Form Settings"}).click();
cy.findByRole("tab", { name: "Form Settings" }).click();
cy.get('input[data-fieldname="allow_edit"]').check();
cy.save();
cy.visit('/note/Note 1');
cy.url().should('include', '/note/Note%201');
cy.visit("/note/Note 1");
cy.url().should("include", "/note/Note%201");
cy.get('.web-form-actions a').contains('Edit').click();
cy.url().should('include', '/note/Note%201/edit');
cy.get(".web-form-actions a").contains("Edit").click();
cy.url().should("include", "/note/Note%201/edit");
// Editable Field
cy.get_field('title').should('have.value', 'Note 1');
cy.fill_field('title', ' Edited');
cy.get('.web-form-actions button').contains('Save').click();
cy.get_field('title').should('have.value', 'Note 1 Edited');
cy.get_field("title").should("have.value", "Note 1");
cy.fill_field("title", " Edited");
cy.get(".web-form-actions button").contains("Save").click();
cy.get_field("title").should("have.value", "Note 1 Edited");
});
it('Allow Multiple Response', () => {
cy.visit('/app/web-form/note');
it("Allow Multiple Response", () => {
cy.visit("/app/web-form/note");
cy.findByRole("tab", {name: "Form Settings"}).click();
cy.findByRole("tab", { name: "Form Settings" }).click();
cy.get('input[data-fieldname="allow_multiple"]').check();
cy.save();
cy.visit('/note');
cy.url().should('include', '/note/list');
cy.visit("/note");
cy.url().should("include", "/note/list");
cy.get('.web-list-actions a:visible').contains('New').click();
cy.url().should('include', '/note/new');
cy.get(".web-list-actions a:visible").contains("New").click();
cy.url().should("include", "/note/new");
cy.fill_field('title', 'Note 2');
cy.get('.web-form-actions button').contains('Save').click();
cy.fill_field("title", "Note 2");
cy.get(".web-form-actions button").contains("Save").click();
});
it('Allow Delete', () => {
cy.visit('/app/web-form/note');
it("Allow Delete", () => {
cy.visit("/app/web-form/note");
cy.findByRole("tab", {name: "Form Settings"}).click();
cy.findByRole("tab", { name: "Form Settings" }).click();
cy.get('input[data-fieldname="allow_delete"]').check();
cy.save();
cy.visit('/note');
cy.url().should('include', '/note/list');
cy.visit("/note");
cy.url().should("include", "/note/list");
cy.get('.web-list-table tbody tr[id="Note 1"] .list-col-checkbox').click();
cy.get('.web-list-table tbody tr[id="Note 2"] .list-col-checkbox').click();
cy.get('.web-list-actions button:visible').contains('Delete').click({force: true});
cy.get(".web-list-actions button:visible").contains("Delete").click({ force: true });
cy.get('.web-list-actions button').contains('Delete').should('not.be.visible');
cy.get(".web-list-actions button").contains("Delete").should("not.be.visible");
cy.visit('/note');
cy.get('.web-list-table tbody tr[id="Note 1"]').should('not.exist');
cy.get('.web-list-table tbody tr[id="Note 2"]').should('not.exist');
cy.get('.web-list-table tbody tr[id="Guest Note 1"]').should('exist');
cy.visit("/note");
cy.get('.web-list-table tbody tr[id="Note 1"]').should("not.exist");
cy.get('.web-list-table tbody tr[id="Note 2"]').should("not.exist");
cy.get('.web-list-table tbody tr[id="Guest Note 1"]').should("exist");
});
it('Navigate and Submit a WebForm', () => {
cy.visit('/update-profile');
it("Navigate and Submit a WebForm", () => {
cy.visit("/update-profile");
cy.get('.web-form-actions a').contains('Edit').click();
cy.get(".web-form-actions a").contains("Edit").click();
cy.fill_field('last_name', '_Test User');
cy.fill_field("last_name", "_Test User");
cy.get('.web-form-actions .btn-primary').click();
cy.url().should('include', '/me');
cy.get(".web-form-actions .btn-primary").click();
cy.url().should("include", "/me");
});
it('Navigate and Submit a MultiStep WebForm', () => {
cy.call('frappe.tests.ui_test_helpers.update_webform_to_multistep').then(() => {
cy.visit('/update-profile-duplicate');
it("Navigate and Submit a MultiStep WebForm", () => {
cy.call("frappe.tests.ui_test_helpers.update_webform_to_multistep").then(() => {
cy.visit("/update-profile-duplicate");
cy.get('.web-form-actions a').contains('Edit').click();
cy.get(".web-form-actions a").contains("Edit").click();
cy.fill_field('last_name', '_Test User');
cy.fill_field("last_name", "_Test User");
cy.get('.btn-next').should('be.visible');
cy.get('.btn-next').click();
cy.get(".btn-next").should("be.visible");
cy.get(".btn-next").click();
cy.get('.btn-previous').should('be.visible');
cy.get('.btn-next').should('not.be.visible');
cy.get(".btn-previous").should("be.visible");
cy.get(".btn-next").should("not.be.visible");
cy.get('.web-form-actions .btn-primary').click();
cy.url().should('include', '/me');
cy.get(".web-form-actions .btn-primary").click();
cy.url().should("include", "/me");
});
});
});

View File

@ -1,185 +1,214 @@
context('Workspace 2.0', () => {
context("Workspace 2.0", () => {
before(() => {
cy.visit('/login');
cy.visit("/login");
cy.login();
});
it('Navigate to page from sidebar', () => {
cy.visit('/app/build');
cy.get('.codex-editor__redactor .ce-block');
it("Navigate to page from sidebar", () => {
cy.visit("/app/build");
cy.get(".codex-editor__redactor .ce-block");
cy.get('.sidebar-item-container[item-name="Settings"]').first().click();
cy.location('pathname').should('eq', '/app/settings');
cy.location("pathname").should("eq", "/app/settings");
});
it('Create Private Page', () => {
it("Create Private Page", () => {
cy.intercept({
method: 'POST',
url: 'api/method/frappe.desk.doctype.workspace.workspace.new_page'
}).as('new_page');
method: "POST",
url: "api/method/frappe.desk.doctype.workspace.workspace.new_page",
}).as("new_page");
cy.get('.codex-editor__redactor .ce-block');
cy.get(".codex-editor__redactor .ce-block");
cy.get('.custom-actions button[data-label="Create%20Workspace"]').click();
cy.fill_field('title', 'Test Private Page', 'Data');
cy.fill_field('icon', 'edit', 'Icon');
cy.get_open_dialog().find('.modal-header').click();
cy.get_open_dialog().find('.btn-primary').click();
cy.fill_field("title", "Test Private Page", "Data");
cy.fill_field("icon", "edit", "Icon");
cy.get_open_dialog().find(".modal-header").click();
cy.get_open_dialog().find(".btn-primary").click();
// check if sidebar item is added in pubic section
cy.get('.sidebar-item-container[item-name="Test Private Page"]').should('have.attr', 'item-public', '0');
cy.get('.sidebar-item-container[item-name="Test Private Page"]').should(
"have.attr",
"item-public",
"0"
);
cy.get('.standard-actions .btn-primary[data-label="Save"]').click();
cy.wait(300);
cy.get('.sidebar-item-container[item-name="Test Private Page"]').should('have.attr', 'item-public', '0');
cy.get('.sidebar-item-container[item-name="Test Private Page"]').should(
"have.attr",
"item-public",
"0"
);
cy.wait('@new_page');
cy.wait("@new_page");
});
it('Create Child Page', () => {
it("Create Child Page", () => {
cy.intercept({
method: 'POST',
url: 'api/method/frappe.desk.doctype.workspace.workspace.new_page'
}).as('new_page');
method: "POST",
url: "api/method/frappe.desk.doctype.workspace.workspace.new_page",
}).as("new_page");
cy.get('.codex-editor__redactor .ce-block');
cy.get(".codex-editor__redactor .ce-block");
cy.get('.custom-actions button[data-label="Create%20Workspace"]').click();
cy.fill_field('title', 'Test Child Page', 'Data');
cy.fill_field('parent', 'Test Private Page', 'Select');
cy.fill_field('icon', 'edit', 'Icon');
cy.get_open_dialog().find('.modal-header').click();
cy.get_open_dialog().find('.btn-primary').click();
cy.fill_field("title", "Test Child Page", "Data");
cy.fill_field("parent", "Test Private Page", "Select");
cy.fill_field("icon", "edit", "Icon");
cy.get_open_dialog().find(".modal-header").click();
cy.get_open_dialog().find(".btn-primary").click();
// check if sidebar item is added in pubic section
cy.get('.sidebar-item-container[item-name="Test Child Page"]').should('have.attr', 'item-public', '0');
cy.get('.sidebar-item-container[item-name="Test Child Page"]').should(
"have.attr",
"item-public",
"0"
);
cy.get('.standard-actions .btn-primary[data-label="Save"]').click();
cy.wait(300);
cy.get('.sidebar-item-container[item-name="Test Child Page"]').should('have.attr', 'item-public', '0');
cy.get('.sidebar-item-container[item-name="Test Child Page"]').should(
"have.attr",
"item-public",
"0"
);
cy.wait('@new_page');
cy.wait("@new_page");
});
it('Duplicate Page', () => {
it("Duplicate Page", () => {
cy.intercept({
method: 'POST',
url: 'api/method/frappe.desk.doctype.workspace.workspace.duplicate_page'
}).as('page_duplicated');
method: "POST",
url: "api/method/frappe.desk.doctype.workspace.workspace.duplicate_page",
}).as("page_duplicated");
cy.get('.codex-editor__redactor .ce-block');
cy.get('.standard-actions .btn-secondary[data-label=Edit]').click();
cy.get(".codex-editor__redactor .ce-block");
cy.get(".standard-actions .btn-secondary[data-label=Edit]").click();
cy.get('.sidebar-item-container[item-name="Test Private Page"]').as('sidebar-item');
cy.get('.sidebar-item-container[item-name="Test Private Page"]').as("sidebar-item");
cy.get('@sidebar-item').find('.standard-sidebar-item').first().click();
cy.get('@sidebar-item').find('.dropdown-btn').first().click();
cy.get('@sidebar-item').find('.dropdown-list .dropdown-item').contains('Duplicate').first().click({force: true});
cy.get("@sidebar-item").find(".standard-sidebar-item").first().click();
cy.get("@sidebar-item").find(".dropdown-btn").first().click();
cy.get("@sidebar-item")
.find(".dropdown-list .dropdown-item")
.contains("Duplicate")
.first()
.click({ force: true });
cy.get_open_dialog().fill_field('title', 'Duplicate Page', 'Data');
cy.click_modal_primary_button('Duplicate');
cy.get_open_dialog().fill_field("title", "Duplicate Page", "Data");
cy.click_modal_primary_button("Duplicate");
cy.wait('@page_duplicated');
cy.wait("@page_duplicated");
});
it('Drag Sidebar Item', () => {
it("Drag Sidebar Item", () => {
cy.intercept({
method: 'POST',
url: 'api/method/frappe.desk.doctype.workspace.workspace.sort_pages'
}).as('page_sorted');
method: "POST",
url: "api/method/frappe.desk.doctype.workspace.workspace.sort_pages",
}).as("page_sorted");
cy.get('.sidebar-item-container[item-name="Duplicate Page"]').as('sidebar-item');
cy.get('.sidebar-item-container[item-name="Duplicate Page"]').as("sidebar-item");
cy.get('@sidebar-item').find('.standard-sidebar-item').first().click();
cy.get('@sidebar-item').find('.drag-handle').first().move({ deltaX: 0, deltaY: 100 });
cy.get("@sidebar-item").find(".standard-sidebar-item").first().click();
cy.get("@sidebar-item").find(".drag-handle").first().move({ deltaX: 0, deltaY: 100 });
cy.get('.sidebar-item-container[item-name="Build"]').as('sidebar-item');
cy.get('.sidebar-item-container[item-name="Build"]').as("sidebar-item");
cy.get('@sidebar-item').find('.standard-sidebar-item').first().click();
cy.get('@sidebar-item').find('.drag-handle').first().move({ deltaX: 0, deltaY: 100 });
cy.get("@sidebar-item").find(".standard-sidebar-item").first().click();
cy.get("@sidebar-item").find(".drag-handle").first().move({ deltaX: 0, deltaY: 100 });
cy.wait('@page_sorted');
cy.wait("@page_sorted");
});
it('Edit Page Detail', () => {
it("Edit Page Detail", () => {
cy.intercept({
method: 'POST',
url: 'api/method/frappe.desk.doctype.workspace.workspace.update_page'
}).as('page_updated');
method: "POST",
url: "api/method/frappe.desk.doctype.workspace.workspace.update_page",
}).as("page_updated");
cy.get('.sidebar-item-container[item-name="Test Private Page"]').as('sidebar-item');
cy.get('.sidebar-item-container[item-name="Test Private Page"]').as("sidebar-item");
cy.get('@sidebar-item').find('.standard-sidebar-item').first().click();
cy.get('@sidebar-item').find('.dropdown-btn').first().click();
cy.get('@sidebar-item').find('.dropdown-list .dropdown-item').contains('Edit').first().click({force: true});
cy.get("@sidebar-item").find(".standard-sidebar-item").first().click();
cy.get("@sidebar-item").find(".dropdown-btn").first().click();
cy.get("@sidebar-item")
.find(".dropdown-list .dropdown-item")
.contains("Edit")
.first()
.click({ force: true });
cy.get_open_dialog().fill_field('title', ' 1', 'Data');
cy.get_open_dialog().fill_field("title", " 1", "Data");
cy.get_open_dialog().find('input[data-fieldname="is_public"]').check();
cy.click_modal_primary_button('Update');
cy.click_modal_primary_button("Update");
cy.get('.standard-sidebar-section:first .sidebar-item-container[item-name="Test Private Page"]').should('not.exist');
cy.get('.standard-sidebar-section:last .sidebar-item-container[item-name="Test Private Page 1"]').should('exist');
cy.get(
'.standard-sidebar-section:first .sidebar-item-container[item-name="Test Private Page"]'
).should("not.exist");
cy.get(
'.standard-sidebar-section:last .sidebar-item-container[item-name="Test Private Page 1"]'
).should("exist");
cy.wait('@page_updated');
cy.wait("@page_updated");
});
it('Add New Block', () => {
cy.get('.sidebar-item-container[item-name="Duplicate Page"]').as('sidebar-item');
it("Add New Block", () => {
cy.get('.sidebar-item-container[item-name="Duplicate Page"]').as("sidebar-item");
cy.get('@sidebar-item').find('.standard-sidebar-item').first().click();
cy.get("@sidebar-item").find(".standard-sidebar-item").first().click();
cy.get('.ce-block').click().type('{enter}');
cy.get('.block-list-container .block-list-item').contains('Heading').click();
cy.get(":focus").type('Header');
cy.get(".ce-block:last").find('.ce-header').should('exist');
cy.get(".ce-block").click().type("{enter}");
cy.get(".block-list-container .block-list-item").contains("Heading").click();
cy.get(":focus").type("Header");
cy.get(".ce-block:last").find(".ce-header").should("exist");
cy.get('.ce-block:last').click().type('{enter}');
cy.get('.block-list-container .block-list-item').contains('Text').click();
cy.get(":focus").type('Paragraph text');
cy.get(".ce-block:last").find('.ce-paragraph').should('exist');
cy.get(".ce-block:last").click().type("{enter}");
cy.get(".block-list-container .block-list-item").contains("Text").click();
cy.get(":focus").type("Paragraph text");
cy.get(".ce-block:last").find(".ce-paragraph").should("exist");
});
it('Delete A Block', () => {
it("Delete A Block", () => {
cy.get(":focus").click();
cy.get('.paragraph-control .setting-btn').click();
cy.get('.paragraph-control .dropdown-item').contains('Delete').click();
cy.get(".ce-block:last").find('.ce-paragraph').should('not.exist');
cy.get(".paragraph-control .setting-btn").click();
cy.get(".paragraph-control .dropdown-item").contains("Delete").click();
cy.get(".ce-block:last").find(".ce-paragraph").should("not.exist");
});
it('Shrink and Expand A Block', () => {
it("Shrink and Expand A Block", () => {
cy.get(":focus").click();
cy.get('.ce-block:last .setting-btn').click();
cy.get('.ce-block:last .dropdown-item').contains('Shrink').click();
cy.get(".ce-block:last").should('have.class', 'col-xs-11');
cy.get('.ce-block:last .dropdown-item').contains('Shrink').click();
cy.get(".ce-block:last").should('have.class', 'col-xs-10');
cy.get('.ce-block:last .dropdown-item').contains('Shrink').click();
cy.get(".ce-block:last").should('have.class', 'col-xs-9');
cy.get('.ce-block:last .dropdown-item').contains('Expand').click();
cy.get(".ce-block:last").should('have.class', 'col-xs-10');
cy.get('.ce-block:last .dropdown-item').contains('Expand').click();
cy.get(".ce-block:last").should('have.class', 'col-xs-11');
cy.get('.ce-block:last .dropdown-item').contains('Expand').click();
cy.get(".ce-block:last").should('have.class', 'col-xs-12');
cy.get(".ce-block:last .setting-btn").click();
cy.get(".ce-block:last .dropdown-item").contains("Shrink").click();
cy.get(".ce-block:last").should("have.class", "col-xs-11");
cy.get(".ce-block:last .dropdown-item").contains("Shrink").click();
cy.get(".ce-block:last").should("have.class", "col-xs-10");
cy.get(".ce-block:last .dropdown-item").contains("Shrink").click();
cy.get(".ce-block:last").should("have.class", "col-xs-9");
cy.get(".ce-block:last .dropdown-item").contains("Expand").click();
cy.get(".ce-block:last").should("have.class", "col-xs-10");
cy.get(".ce-block:last .dropdown-item").contains("Expand").click();
cy.get(".ce-block:last").should("have.class", "col-xs-11");
cy.get(".ce-block:last .dropdown-item").contains("Expand").click();
cy.get(".ce-block:last").should("have.class", "col-xs-12");
cy.get('.standard-actions .btn-primary[data-label="Save"]').click();
});
it('Delete Duplicate Page', () => {
it("Delete Duplicate Page", () => {
cy.intercept({
method: 'POST',
url: 'api/method/frappe.desk.doctype.workspace.workspace.delete_page'
}).as('page_deleted');
method: "POST",
url: "api/method/frappe.desk.doctype.workspace.workspace.delete_page",
}).as("page_deleted");
cy.get('.codex-editor__redactor .ce-block');
cy.get('.standard-actions .btn-secondary[data-label=Edit]').click();
cy.get(".codex-editor__redactor .ce-block");
cy.get(".standard-actions .btn-secondary[data-label=Edit]").click();
cy.get('.sidebar-item-container[item-name="Duplicate Page"]')
.find('.sidebar-item-control .setting-btn').click();
.find(".sidebar-item-control .setting-btn")
.click();
cy.get('.sidebar-item-container[item-name="Duplicate Page"]')
.find('.dropdown-item[title="Delete Workspace"]').click({force: true});
.find('.dropdown-item[title="Delete Workspace"]')
.click({ force: true });
cy.wait(300);
cy.get('.modal-footer > .standard-actions > .btn-modal-primary:visible').first().click();
cy.get('.sidebar-item-container[item-name="Duplicate Page"]').should('not.exist');
cy.get(".modal-footer > .standard-actions > .btn-modal-primary:visible").first().click();
cy.get('.sidebar-item-container[item-name="Duplicate Page"]').should("not.exist");
cy.wait('@page_deleted');
cy.wait("@page_deleted");
});
});
});

View File

@ -1,140 +1,152 @@
context('Workspace Blocks', () => {
context("Workspace Blocks", () => {
before(() => {
cy.login();
cy.visit('/app');
return cy.window().its('frappe').then(frappe => {
return frappe.xcall("frappe.tests.ui_test_helpers.setup_workflow");
});
cy.visit("/app");
return cy
.window()
.its("frappe")
.then((frappe) => {
return frappe.xcall("frappe.tests.ui_test_helpers.setup_workflow");
});
});
it('Create Test Page', () => {
it("Create Test Page", () => {
cy.intercept({
method: 'POST',
url: 'api/method/frappe.desk.doctype.workspace.workspace.new_page'
}).as('new_page');
method: "POST",
url: "api/method/frappe.desk.doctype.workspace.workspace.new_page",
}).as("new_page");
cy.visit('/app/website');
cy.get('.codex-editor__redactor .ce-block');
cy.visit("/app/website");
cy.get(".codex-editor__redactor .ce-block");
cy.get('.custom-actions button[data-label="Create%20Workspace"]').click();
cy.fill_field('title', 'Test Block Page', 'Data');
cy.fill_field('icon', 'edit', 'Icon');
cy.get_open_dialog().find('.modal-header').click();
cy.get_open_dialog().find('.btn-primary').click();
cy.fill_field("title", "Test Block Page", "Data");
cy.fill_field("icon", "edit", "Icon");
cy.get_open_dialog().find(".modal-header").click();
cy.get_open_dialog().find(".btn-primary").click();
// check if sidebar item is added in private section
cy.get('.sidebar-item-container[item-name="Test Block Page"]').should('have.attr', 'item-public', '0');
cy.get('.sidebar-item-container[item-name="Test Block Page"]').should(
"have.attr",
"item-public",
"0"
);
cy.get('.standard-actions .btn-primary[data-label="Save"]').click();
cy.wait(300);
cy.get('.sidebar-item-container[item-name="Test Block Page"]').should('have.attr', 'item-public', '0');
cy.get('.sidebar-item-container[item-name="Test Block Page"]').should(
"have.attr",
"item-public",
"0"
);
cy.wait('@new_page');
cy.wait("@new_page");
});
it('Quick List Block', () => {
it("Quick List Block", () => {
cy.create_records([
{
doctype: 'ToDo',
description: 'Quick List ToDo 1',
status: 'Open'
doctype: "ToDo",
description: "Quick List ToDo 1",
status: "Open",
},
{
doctype: 'ToDo',
description: 'Quick List ToDo 2',
status: 'Open'
doctype: "ToDo",
description: "Quick List ToDo 2",
status: "Open",
},
{
doctype: 'ToDo',
description: 'Quick List ToDo 3',
status: 'Open'
doctype: "ToDo",
description: "Quick List ToDo 3",
status: "Open",
},
{
doctype: 'ToDo',
description: 'Quick List ToDo 4',
status: 'Open'
}
doctype: "ToDo",
description: "Quick List ToDo 4",
status: "Open",
},
]);
cy.intercept({
method: 'GET',
url: 'api/method/frappe.desk.form.load.getdoctype'
}).as('get_doctype');
method: "GET",
url: "api/method/frappe.desk.form.load.getdoctype",
}).as("get_doctype");
cy.get('.codex-editor__redactor .ce-block');
cy.get('.standard-actions .btn-secondary[data-label=Edit]').click();
cy.get(".codex-editor__redactor .ce-block");
cy.get(".standard-actions .btn-secondary[data-label=Edit]").click();
// test quick list creation
cy.get('.ce-block').first().click({force: true}).type('{enter}');
cy.get('.block-list-container .block-list-item').contains('Quick List').click();
cy.get(".ce-block").first().click({ force: true }).type("{enter}");
cy.get(".block-list-container .block-list-item").contains("Quick List").click();
cy.get_open_dialog().find('.modal-header').click();
cy.get_open_dialog().find(".modal-header").click();
cy.fill_field('document_type', 'ToDo', 'Link').blur();
cy.fill_field('label', 'ToDo', 'Data').blur();
cy.wait('@get_doctype');
cy.fill_field("document_type", "ToDo", "Link").blur();
cy.fill_field("label", "ToDo", "Data").blur();
cy.wait("@get_doctype");
cy.get_open_dialog().find('.filter-edit-area').should('contain', 'No filters selected');
cy.get_open_dialog().find('.filter-area .add-filter').click();
cy.get_open_dialog().find(".filter-edit-area").should("contain", "No filters selected");
cy.get_open_dialog().find(".filter-area .add-filter").click();
cy.get_open_dialog().find('.fieldname-select-area input').type('Workflow State{enter}').blur();
cy.get_open_dialog().find('.filter-field .input-with-feedback').type('Pending');
cy.get_open_dialog()
.find(".fieldname-select-area input")
.type("Workflow State{enter}")
.blur();
cy.get_open_dialog().find(".filter-field .input-with-feedback").type("Pending");
cy.get_open_dialog().find('.modal-header').click();
cy.get_open_dialog().find('.btn-primary').click();
cy.get_open_dialog().find(".modal-header").click();
cy.get_open_dialog().find(".btn-primary").click();
cy.get('.standard-actions .btn-primary[data-label="Save"]').click();
cy.get(".codex-editor__redactor .ce-block");
cy.get('.codex-editor__redactor .ce-block');
cy.get(".ce-block .quick-list-widget-box").first().as("todo-quick-list");
cy.get('.ce-block .quick-list-widget-box').first().as('todo-quick-list');
cy.get('@todo-quick-list').find('.quick-list-item .status').should('contain', 'Pending');
cy.get("@todo-quick-list").find(".quick-list-item .status").should("contain", "Pending");
// test quick-list-item
cy.get('@todo-quick-list').find('.quick-list-item .title')
cy.get("@todo-quick-list")
.find(".quick-list-item .title")
.first()
.invoke('attr', 'title')
.then(title => {
cy.get('@todo-quick-list').find('.quick-list-item').contains(title).click();
cy.get_field('description', 'Text Editor').should('contain', title);
cy.click_action_button('Approve');
.invoke("attr", "title")
.then((title) => {
cy.get("@todo-quick-list").find(".quick-list-item").contains(title).click();
cy.get_field("description", "Text Editor").should("contain", title);
cy.click_action_button("Approve");
});
cy.go('back');
cy.go("back");
// test filter-list
cy.get('@todo-quick-list').realHover().find('.widget-control .filter-list').click();
cy.get("@todo-quick-list").realHover().find(".widget-control .filter-list").click();
cy.get_open_dialog().find('.filter-field .input-with-feedback').type('{selectall}Approved');
cy.get_open_dialog().find('.modal-header').click();
cy.get_open_dialog().find('.btn-primary').click();
cy.get('@todo-quick-list').find('.quick-list-item .status').should('contain', 'Approved');
cy.get_open_dialog()
.find(".filter-field .input-with-feedback")
.type("{selectall}Approved");
cy.get_open_dialog().find(".modal-header").click();
cy.get_open_dialog().find(".btn-primary").click();
cy.get("@todo-quick-list").find(".quick-list-item .status").should("contain", "Approved");
// test refresh-list
cy.intercept({
method: 'POST',
url: 'api/method/frappe.desk.reportview.get'
}).as('refresh-list');
cy.get('@todo-quick-list').realHover().find('.widget-control .refresh-list').click();
cy.wait('@refresh-list');
method: "POST",
url: "api/method/frappe.desk.reportview.get",
}).as("refresh-list");
cy.get("@todo-quick-list").realHover().find(".widget-control .refresh-list").click();
cy.wait("@refresh-list");
// test add-new
cy.get('@todo-quick-list').realHover().find('.widget-control .add-new').click();
cy.url().should('include', `/todo/new-todo-1`);
cy.go('back');
cy.get("@todo-quick-list").realHover().find(".widget-control .add-new").click();
cy.url().should("include", `/todo/new-todo-1`);
cy.go("back");
// test see-all
cy.get('@todo-quick-list').find('.widget-footer .see-all').click();
cy.get("@todo-quick-list").find(".widget-footer .see-all").click();
cy.open_list_filter();
cy.get('.filter-field input[data-fieldname="workflow_state"]')
.invoke('val')
.should('eq', 'Pending');
cy.go('back');
.invoke("val")
.should("eq", "Pending");
cy.go("back");
});
});
});

View File

@ -12,6 +12,6 @@
// the project's config changing)
module.exports = (on, config) => {
require('@cypress/code-coverage/task')(on, config);
require("@cypress/code-coverage/task")(on, config);
return config;
};
};

View File

@ -1,6 +1,6 @@
import 'cypress-file-upload';
import '@testing-library/cypress/add-commands';
import '@4tw/cypress-drag-drop';
import "cypress-file-upload";
import "@testing-library/cypress/add-commands";
import "@4tw/cypress-drag-drop";
import "cypress-real-events/support";
// ***********************************************
// This example commands.js shows you how to
@ -28,296 +28,304 @@ import "cypress-real-events/support";
// -- This is will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... });
Cypress.Commands.add('login', (email, password) => {
Cypress.Commands.add("login", (email, password) => {
if (!email) {
email = 'Administrator';
email = "Administrator";
}
if (!password) {
password = Cypress.env('adminPassword');
password = Cypress.env("adminPassword");
}
cy.request({
url: '/api/method/login',
method: 'POST',
url: "/api/method/login",
method: "POST",
body: {
usr: email,
pwd: password
}
pwd: password,
},
});
});
Cypress.Commands.add('call', (method, args) => {
Cypress.Commands.add("call", (method, args) => {
return cy
.window()
.its('frappe.csrf_token')
.then(csrf_token => {
.its("frappe.csrf_token")
.then((csrf_token) => {
return cy
.request({
url: `/api/method/${method}`,
method: 'POST',
method: "POST",
body: args,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'X-Frappe-CSRF-Token': csrf_token
}
Accept: "application/json",
"Content-Type": "application/json",
"X-Frappe-CSRF-Token": csrf_token,
},
})
.then(res => {
.then((res) => {
expect(res.status).eq(200);
return res.body;
});
});
});
Cypress.Commands.add('get_list', (doctype, fields = [], filters = []) => {
Cypress.Commands.add("get_list", (doctype, fields = [], filters = []) => {
filters = JSON.stringify(filters);
fields = JSON.stringify(fields);
let url = `/api/resource/${doctype}?fields=${fields}&filters=${filters}`;
return cy
.window()
.its('frappe.csrf_token')
.then(csrf_token => {
.its("frappe.csrf_token")
.then((csrf_token) => {
return cy
.request({
method: 'GET',
method: "GET",
url,
headers: {
Accept: 'application/json',
'X-Frappe-CSRF-Token': csrf_token
}
Accept: "application/json",
"X-Frappe-CSRF-Token": csrf_token,
},
})
.then(res => {
.then((res) => {
expect(res.status).eq(200);
return res.body;
});
});
});
Cypress.Commands.add('get_doc', (doctype, name) => {
Cypress.Commands.add("get_doc", (doctype, name) => {
return cy
.window()
.its('frappe.csrf_token')
.then(csrf_token => {
.its("frappe.csrf_token")
.then((csrf_token) => {
return cy
.request({
method: 'GET',
method: "GET",
url: `/api/resource/${doctype}/${name}`,
headers: {
Accept: 'application/json',
'X-Frappe-CSRF-Token': csrf_token
}
Accept: "application/json",
"X-Frappe-CSRF-Token": csrf_token,
},
})
.then(res => {
.then((res) => {
expect(res.status).eq(200);
return res.body;
});
});
});
Cypress.Commands.add('remove_doc', (doctype, name) => {
Cypress.Commands.add("remove_doc", (doctype, name) => {
return cy
.window()
.its('frappe.csrf_token')
.then(csrf_token => {
.its("frappe.csrf_token")
.then((csrf_token) => {
return cy
.request({
method: 'DELETE',
method: "DELETE",
url: `/api/resource/${doctype}/${name}`,
headers: {
Accept: 'application/json',
'X-Frappe-CSRF-Token': csrf_token
}
Accept: "application/json",
"X-Frappe-CSRF-Token": csrf_token,
},
})
.then(res => {
.then((res) => {
expect(res.status).eq(202);
return res.body;
});
});
});
Cypress.Commands.add('create_records', doc => {
Cypress.Commands.add("create_records", (doc) => {
return cy
.call('frappe.tests.ui_test_helpers.create_if_not_exists', {doc: JSON.stringify(doc)})
.then(r => r.message);
.call("frappe.tests.ui_test_helpers.create_if_not_exists", { doc: JSON.stringify(doc) })
.then((r) => r.message);
});
Cypress.Commands.add('set_value', (doctype, name, obj) => {
return cy.call('frappe.client.set_value', {
Cypress.Commands.add("set_value", (doctype, name, obj) => {
return cy.call("frappe.client.set_value", {
doctype,
name,
fieldname: obj
fieldname: obj,
});
});
Cypress.Commands.add('fill_field', (fieldname, value, fieldtype = 'Data') => {
cy.get_field(fieldname, fieldtype).as('input');
Cypress.Commands.add("fill_field", (fieldname, value, fieldtype = "Data") => {
cy.get_field(fieldname, fieldtype).as("input");
if (['Date', 'Time', 'Datetime'].includes(fieldtype)) {
cy.get('@input').click().wait(200);
cy.get('.datepickers-container .datepicker.active').should('exist');
if (["Date", "Time", "Datetime"].includes(fieldtype)) {
cy.get("@input").click().wait(200);
cy.get(".datepickers-container .datepicker.active").should("exist");
}
if (fieldtype === 'Time') {
cy.get('@input').clear().wait(200);
if (fieldtype === "Time") {
cy.get("@input").clear().wait(200);
}
if (fieldtype === 'Select') {
cy.get('@input').select(value);
if (fieldtype === "Select") {
cy.get("@input").select(value);
} else {
cy.get('@input').type(value, {
cy.get("@input").type(value, {
waitForAnimations: false,
parseSpecialCharSequences: false,
force: true,
delay: 100
delay: 100,
});
}
return cy.get('@input');
return cy.get("@input");
});
Cypress.Commands.add('get_field', (fieldname, fieldtype = 'Data') => {
let field_element = fieldtype === 'Select' ? 'select': 'input';
Cypress.Commands.add("get_field", (fieldname, fieldtype = "Data") => {
let field_element = fieldtype === "Select" ? "select" : "input";
let selector = `[data-fieldname="${fieldname}"] ${field_element}:visible`;
if (fieldtype === 'Text Editor') {
if (fieldtype === "Text Editor") {
selector = `[data-fieldname="${fieldname}"] .ql-editor[contenteditable=true]:visible`;
}
if (fieldtype === 'Code') {
if (fieldtype === "Code") {
selector = `[data-fieldname="${fieldname}"] .ace_text-input`;
}
if (fieldtype === 'Markdown Editor') {
if (fieldtype === "Markdown Editor") {
selector = `[data-fieldname="${fieldname}"] .ace-editor-target`;
}
return cy.get(selector).first();
});
Cypress.Commands.add('fill_table_field', (tablefieldname, row_idx, fieldname, value, fieldtype = 'Data') => {
cy.get_table_field(tablefieldname, row_idx, fieldname, fieldtype).as('input');
Cypress.Commands.add(
"fill_table_field",
(tablefieldname, row_idx, fieldname, value, fieldtype = "Data") => {
cy.get_table_field(tablefieldname, row_idx, fieldname, fieldtype).as("input");
if (['Date', 'Time', 'Datetime'].includes(fieldtype)) {
cy.get('@input').click().wait(200);
cy.get('.datepickers-container .datepicker.active').should('exist');
}
if (fieldtype === 'Time') {
cy.get('@input').clear().wait(200);
}
if (["Date", "Time", "Datetime"].includes(fieldtype)) {
cy.get("@input").click().wait(200);
cy.get(".datepickers-container .datepicker.active").should("exist");
}
if (fieldtype === "Time") {
cy.get("@input").clear().wait(200);
}
if (fieldtype === 'Select') {
cy.get('@input').select(value);
} else {
cy.get('@input').type(value, {waitForAnimations: false, force: true});
if (fieldtype === "Select") {
cy.get("@input").select(value);
} else {
cy.get("@input").type(value, { waitForAnimations: false, force: true });
}
return cy.get("@input");
}
return cy.get('@input');
);
Cypress.Commands.add(
"get_table_field",
(tablefieldname, row_idx, fieldname, fieldtype = "Data") => {
let selector = `.frappe-control[data-fieldname="${tablefieldname}"]`;
selector += ` [data-idx="${row_idx}"]`;
if (fieldtype === "Text Editor") {
selector += ` [data-fieldname="${fieldname}"] .ql-editor[contenteditable=true]`;
} else if (fieldtype === "Code") {
selector += ` [data-fieldname="${fieldname}"] .ace_text-input`;
} else {
selector += ` [data-fieldname="${fieldname}"]`;
return cy.get(selector).find(".form-control:visible, .static-area:visible").first();
}
return cy.get(selector);
}
);
Cypress.Commands.add("awesomebar", (text) => {
cy.get("#navbar-search").type(`${text}{downarrow}{enter}`, { delay: 700 });
});
Cypress.Commands.add('get_table_field', (tablefieldname, row_idx, fieldname, fieldtype = 'Data') => {
let selector = `.frappe-control[data-fieldname="${tablefieldname}"]`;
selector += ` [data-idx="${row_idx}"]`;
if (fieldtype === 'Text Editor') {
selector += ` [data-fieldname="${fieldname}"] .ql-editor[contenteditable=true]`;
} else if (fieldtype === 'Code') {
selector += ` [data-fieldname="${fieldname}"] .ace_text-input`;
} else {
selector += ` [data-fieldname="${fieldname}"]`;
return cy.get(selector).find('.form-control:visible, .static-area:visible').first();
}
return cy.get(selector);
});
Cypress.Commands.add('awesomebar', text => {
cy.get('#navbar-search').type(`${text}{downarrow}{enter}`, {delay: 700});
});
Cypress.Commands.add('new_form', doctype => {
let dt_in_route = doctype.toLowerCase().replace(/ /g, '-');
Cypress.Commands.add("new_form", (doctype) => {
let dt_in_route = doctype.toLowerCase().replace(/ /g, "-");
cy.visit(`/app/${dt_in_route}/new`);
cy.get('body').should('have.attr', 'data-route', `Form/${doctype}/new-${dt_in_route}-1`);
cy.get('body').should('have.attr', 'data-ajax-state', 'complete');
cy.get("body").should("have.attr", "data-route", `Form/${doctype}/new-${dt_in_route}-1`);
cy.get("body").should("have.attr", "data-ajax-state", "complete");
});
Cypress.Commands.add('go_to_list', doctype => {
let dt_in_route = doctype.toLowerCase().replace(/ /g, '-');
Cypress.Commands.add("go_to_list", (doctype) => {
let dt_in_route = doctype.toLowerCase().replace(/ /g, "-");
cy.visit(`/app/${dt_in_route}`);
});
Cypress.Commands.add('clear_cache', () => {
Cypress.Commands.add("clear_cache", () => {
cy.window()
.its('frappe')
.then(frappe => {
.its("frappe")
.then((frappe) => {
frappe.ui.toolbar.clear_cache();
});
});
Cypress.Commands.add('dialog', opts => {
return cy.window({ log: false }).its('frappe', { log: false }).then(frappe => {
Cypress.log({
name: "dialog",
displayName: "dialog",
message: 'frappe.ui.Dialog',
consoleProps: () => {
return {
options: opts,
dialog: d
}
}
Cypress.Commands.add("dialog", (opts) => {
return cy
.window({ log: false })
.its("frappe", { log: false })
.then((frappe) => {
Cypress.log({
name: "dialog",
displayName: "dialog",
message: "frappe.ui.Dialog",
consoleProps: () => {
return {
options: opts,
dialog: d,
};
},
});
var d = new frappe.ui.Dialog(opts);
d.show();
return d;
});
var d = new frappe.ui.Dialog(opts);
d.show();
return d;
});
});
Cypress.Commands.add('get_open_dialog', () => {
return cy.get('.modal:visible').last();
Cypress.Commands.add("get_open_dialog", () => {
return cy.get(".modal:visible").last();
});
Cypress.Commands.add('save', () => {
cy.intercept('/api').as('api');
cy.get(`button[data-label="Save"]:visible`).click({scrollBehavior: false, force: true});
cy.wait('@api');
Cypress.Commands.add("save", () => {
cy.intercept("/api").as("api");
cy.get(`button[data-label="Save"]:visible`).click({ scrollBehavior: false, force: true });
cy.wait("@api");
});
Cypress.Commands.add('hide_dialog', () => {
Cypress.Commands.add("hide_dialog", () => {
cy.wait(300);
cy.get_open_dialog().focus().find('.btn-modal-close').click();
cy.get('.modal:visible').should('not.exist');
cy.get_open_dialog().focus().find(".btn-modal-close").click();
cy.get(".modal:visible").should("not.exist");
});
Cypress.Commands.add('clear_dialogs', () => {
Cypress.Commands.add("clear_dialogs", () => {
cy.window().then((win) => {
win.$('.modal, .modal-backdrop').remove();
win.$(".modal, .modal-backdrop").remove();
});
cy.get('.modal').should('not.exist');
cy.get(".modal").should("not.exist");
});
Cypress.Commands.add('clear_datepickers', () => {
Cypress.Commands.add("clear_datepickers", () => {
cy.window().then((win) => {
win.$('.datepicker').remove();
win.$(".datepicker").remove();
});
cy.get('.datepicker').should('not.exist');
cy.get(".datepicker").should("not.exist");
});
Cypress.Commands.add('insert_doc', (doctype, args, ignore_duplicate) => {
Cypress.Commands.add("insert_doc", (doctype, args, ignore_duplicate) => {
if (!args.doctype) {
args.doctype = doctype;
}
return cy
.window()
.its('frappe.csrf_token')
.then(csrf_token => {
.its("frappe.csrf_token")
.then((csrf_token) => {
return cy
.request({
method: 'POST',
method: "POST",
url: `/api/resource/${doctype}`,
body: args,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'X-Frappe-CSRF-Token': csrf_token
Accept: "application/json",
"Content-Type": "application/json",
"X-Frappe-CSRF-Token": csrf_token,
},
failOnStatusCode: !ignore_duplicate
failOnStatusCode: !ignore_duplicate,
})
.then(res => {
.then((res) => {
let status_codes = [200];
if (ignore_duplicate) {
status_codes.push(409);
@ -325,7 +333,11 @@ Cypress.Commands.add('insert_doc', (doctype, args, ignore_duplicate) => {
let message = null;
if (ignore_duplicate && !status_codes.includes(res.status)) {
message = `Document insert failed, response: ${JSON.stringify(res, null, '\t')}`;
message = `Document insert failed, response: ${JSON.stringify(
res,
null,
"\t"
)}`;
}
expect(res.status).to.be.oneOf(status_codes, message);
return res.body.data;
@ -333,112 +345,117 @@ Cypress.Commands.add('insert_doc', (doctype, args, ignore_duplicate) => {
});
});
Cypress.Commands.add('update_doc', (doctype, docname, args) => {
Cypress.Commands.add("update_doc", (doctype, docname, args) => {
return cy
.window()
.its('frappe.csrf_token')
.then(csrf_token => {
.its("frappe.csrf_token")
.then((csrf_token) => {
return cy
.request({
method: 'PUT',
method: "PUT",
url: `/api/resource/${doctype}/${docname}`,
body: args,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'X-Frappe-CSRF-Token': csrf_token
Accept: "application/json",
"Content-Type": "application/json",
"X-Frappe-CSRF-Token": csrf_token,
},
})
.then(res => {
.then((res) => {
expect(res.status).to.eq(200);
return res.body.data;
});
});
});
Cypress.Commands.add('open_list_filter', () => {
cy.get('.filter-section .filter-button').click();
Cypress.Commands.add("open_list_filter", () => {
cy.get(".filter-section .filter-button").click();
cy.wait(300);
cy.get('.filter-popover').should('exist');
cy.get(".filter-popover").should("exist");
});
Cypress.Commands.add('click_custom_action_button', (name) => {
Cypress.Commands.add("click_custom_action_button", (name) => {
cy.get(`.custom-actions [data-label="${encodeURIComponent(name)}"]`).click();
});
Cypress.Commands.add('click_action_button', (name) => {
cy.findByRole('button', {name: 'Actions'}).click();
Cypress.Commands.add("click_action_button", (name) => {
cy.findByRole("button", { name: "Actions" }).click();
cy.get(`.actions-btn-group [data-label="${encodeURIComponent(name)}"]`).click();
});
Cypress.Commands.add('click_menu_button', (name) => {
cy.get('.standard-actions .menu-btn-group > .btn').click();
Cypress.Commands.add("click_menu_button", (name) => {
cy.get(".standard-actions .menu-btn-group > .btn").click();
cy.get(`.menu-btn-group [data-label="${encodeURIComponent(name)}"]`).click();
});
Cypress.Commands.add('clear_filters', () => {
Cypress.Commands.add("clear_filters", () => {
let has_filter = false;
cy.intercept({
method: 'POST',
url: 'api/method/frappe.model.utils.user_settings.save'
}).as('filter-saved');
cy.get('.filter-section .filter-button').click({force: true});
method: "POST",
url: "api/method/frappe.model.utils.user_settings.save",
}).as("filter-saved");
cy.get(".filter-section .filter-button").click({ force: true });
cy.wait(300);
cy.get('.filter-popover').should('exist');
cy.get('.filter-popover').then(popover => {
if (popover.find('input.input-with-feedback')[0].value != '') {
cy.get(".filter-popover").should("exist");
cy.get(".filter-popover").then((popover) => {
if (popover.find("input.input-with-feedback")[0].value != "") {
has_filter = true;
}
});
cy.get('.filter-popover').find('.clear-filters').click();
cy.get('.filter-section .filter-button').click();
cy.window().its('cur_list').then(cur_list => {
cur_list && cur_list.filter_area && cur_list.filter_area.clear();
has_filter && cy.wait('@filter-saved');
});
cy.get(".filter-popover").find(".clear-filters").click();
cy.get(".filter-section .filter-button").click();
cy.window()
.its("cur_list")
.then((cur_list) => {
cur_list && cur_list.filter_area && cur_list.filter_area.clear();
has_filter && cy.wait("@filter-saved");
});
});
Cypress.Commands.add('click_modal_primary_button', (btn_name) => {
Cypress.Commands.add("click_modal_primary_button", (btn_name) => {
cy.wait(400);
cy.get('.modal-footer > .standard-actions > .btn-primary').contains(btn_name).click({force: true});
cy.get(".modal-footer > .standard-actions > .btn-primary")
.contains(btn_name)
.click({ force: true });
});
Cypress.Commands.add('click_sidebar_button', (btn_name) => {
cy.get('.list-group-by-fields .list-link > a').contains(btn_name).click({force: true});
Cypress.Commands.add("click_sidebar_button", (btn_name) => {
cy.get(".list-group-by-fields .list-link > a").contains(btn_name).click({ force: true });
});
Cypress.Commands.add('click_listview_row_item', (row_no) => {
cy.get('.list-row > .level-left > .list-subject > .level-item > .ellipsis').eq(row_no).click({force: true});
Cypress.Commands.add("click_listview_row_item", (row_no) => {
cy.get(".list-row > .level-left > .list-subject > .level-item > .ellipsis")
.eq(row_no)
.click({ force: true });
});
Cypress.Commands.add('click_listview_row_item_with_text', (text) => {
cy.get('.list-row > .level-left > .list-subject > .level-item > .ellipsis')
Cypress.Commands.add("click_listview_row_item_with_text", (text) => {
cy.get(".list-row > .level-left > .list-subject > .level-item > .ellipsis")
.contains(text)
.first()
.click({force: true});
.click({ force: true });
});
Cypress.Commands.add('click_filter_button', () => {
cy.get('.filter-selector > .btn').click();
Cypress.Commands.add("click_filter_button", () => {
cy.get(".filter-selector > .btn").click();
});
Cypress.Commands.add('click_listview_primary_button', (btn_name) => {
cy.get('.primary-action').contains(btn_name).click({force: true});
Cypress.Commands.add("click_listview_primary_button", (btn_name) => {
cy.get(".primary-action").contains(btn_name).click({ force: true });
});
Cypress.Commands.add('click_doc_primary_button', (btn_name) => {
cy.get('.primary-action').contains(btn_name).click({force: true});
Cypress.Commands.add("click_doc_primary_button", (btn_name) => {
cy.get(".primary-action").contains(btn_name).click({ force: true });
});
Cypress.Commands.add('click_timeline_action_btn', (btn_name) => {
cy.get('.timeline-message-box .actions .action-btn').contains(btn_name).click();
Cypress.Commands.add("click_timeline_action_btn", (btn_name) => {
cy.get(".timeline-message-box .actions .action-btn").contains(btn_name).click();
});
Cypress.Commands.add('select_listview_row_checkbox', (row_no) => {
cy.get('.frappe-list .select-like > .list-row-checkbox').eq(row_no).click();
Cypress.Commands.add("select_listview_row_checkbox", (row_no) => {
cy.get(".frappe-list .select-like > .list-row-checkbox").eq(row_no).click();
});
Cypress.Commands.add('click_form_section', (section_name) => {
cy.get('.section-head').contains(section_name).click();
Cypress.Commands.add("click_form_section", (section_name) => {
cy.get(".section-head").contains(section_name).click();
});

View File

@ -14,10 +14,10 @@
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands';
import '@cypress/code-coverage/support';
import "./commands";
import "@cypress/code-coverage/support";
Cypress.on('uncaught:exception', (err, runnable) => {
Cypress.on("uncaught:exception", (err, runnable) => {
return false;
});
@ -25,5 +25,5 @@ Cypress.on('uncaught:exception', (err, runnable) => {
// require('./commands')
Cypress.Cookies.defaults({
preserve: 'sid'
});
preserve: "sid",
});

View File

@ -4,9 +4,9 @@ const fs = require("fs");
const glob = require("fast-glob");
module.exports = {
name: 'build_cleanup',
name: "build_cleanup",
setup(build) {
build.onEnd(result => {
build.onEnd((result) => {
if (result.errors.length) return;
clean_dist_files(Object.keys(result.metafile.outputs));
});
@ -14,25 +14,18 @@ module.exports = {
};
function clean_dist_files(new_files) {
new_files.forEach(
file => {
if (file.endsWith(".map")) return;
new_files.forEach((file) => {
if (file.endsWith(".map")) return;
const pattern = file.split(".").slice(0, -2).join(".") + "*";
glob.sync(pattern).forEach(
file_to_delete => {
if (file_to_delete.startsWith(file)) return;
const pattern = file.split(".").slice(0, -2).join(".") + "*";
glob.sync(pattern).forEach((file_to_delete) => {
if (file_to_delete.startsWith(file)) return;
fs.unlink(path.resolve(file_to_delete), err => {
if (!err) return;
fs.unlink(path.resolve(file_to_delete), (err) => {
if (!err) return;
console.error(
`Error deleting ${file.split(path.sep).pop()}`
);
});
}
);
}
);
}
console.error(`Error deleting ${file.split(path.sep).pop()}`);
});
});
});
}

View File

@ -8,7 +8,7 @@ const yargs = require("yargs");
const cliui = require("cliui")();
const chalk = require("chalk");
const html_plugin = require("./frappe-html");
const rtlcss = require('rtlcss');
const rtlcss = require("rtlcss");
const postCssPlugin = require("@frappe/esbuild-plugin-postcss2").default;
const ignore_assets = require("./ignore-assets");
const sass_options = require("./sass_options");
@ -25,44 +25,41 @@ const {
log_warn,
log_error,
bench_path,
get_redis_subscriber
get_redis_subscriber,
} = require("./utils");
const argv = yargs
.usage("Usage: node esbuild [options]")
.option("apps", {
type: "string",
description: "Run build for specific apps"
description: "Run build for specific apps",
})
.option("skip_frappe", {
type: "boolean",
description: "Skip building frappe assets"
description: "Skip building frappe assets",
})
.option("files", {
type: "string",
description: "Run build for specified bundles"
description: "Run build for specified bundles",
})
.option("watch", {
type: "boolean",
description: "Run in watch mode and rebuild on file changes"
description: "Run in watch mode and rebuild on file changes",
})
.option("live-reload", {
type: "boolean",
description: `Automatically reload Desk when assets are rebuilt.
Can only be used with the --watch flag.`
Can only be used with the --watch flag.`,
})
.option("production", {
type: "boolean",
description: "Run build in production mode"
description: "Run build in production mode",
})
.option("run-build-command", {
type: "boolean",
description: "Run build command for apps"
description: "Run build command for apps",
})
.example(
"node esbuild --apps frappe,erpnext",
"Run build only for frappe and erpnext"
)
.example("node esbuild --apps frappe,erpnext", "Run build only for frappe and erpnext")
.example(
"node esbuild --files frappe/website.bundle.js,frappe/desk.bundle.js",
"Run build only for specified bundles"
@ -70,7 +67,7 @@ const argv = yargs
.version(false).argv;
const APPS = (!argv.apps ? app_list : argv.apps.split(",")).filter(
app => !(argv.skip_frappe && app == "frappe")
(app) => !(argv.skip_frappe && app == "frappe")
);
const FILES_TO_BUILD = argv.files ? argv.files.split(",") : [];
const WATCH_MODE = Boolean(argv.watch);
@ -81,17 +78,15 @@ const TOTAL_BUILD_TIME = `${chalk.black.bgGreen(" DONE ")} Total Build Time`;
const NODE_PATHS = [].concat(
// node_modules of apps directly importable
app_list
.map(app => path.resolve(get_app_path(app), "../node_modules"))
.map((app) => path.resolve(get_app_path(app), "../node_modules"))
.filter(fs.existsSync),
// import js file of any app if you provide the full path
app_list
.map(app => path.resolve(get_app_path(app), ".."))
.filter(fs.existsSync)
app_list.map((app) => path.resolve(get_app_path(app), "..")).filter(fs.existsSync)
);
execute()
.then(() => RUN_BUILD_COMMAND && run_build_command_for_apps(APPS))
.catch(e => console.error(e));
.catch((e) => console.error(e));
if (WATCH_MODE) {
// listen for open files in editor event
@ -131,7 +126,7 @@ function build_assets_for_apps(apps, files) {
? get_files_to_build(files)
: get_all_files_to_build(apps);
return glob(include_patterns, { ignore: ignore_patterns }).then(files => {
return glob(include_patterns, { ignore: ignore_patterns }).then((files) => {
let output_path = assets_path;
let file_map = {};
@ -143,39 +138,38 @@ function build_assets_for_apps(apps, files) {
let extension = path.extname(file);
let output_name = path.basename(file, extension);
if (
[".css", ".scss", ".less", ".sass", ".styl"].includes(extension)
) {
if ([".css", ".scss", ".less", ".sass", ".styl"].includes(extension)) {
output_name = path.join("css", output_name);
} else if ([".js", ".ts"].includes(extension)) {
output_name = path.join("js", output_name);
}
output_name = path.join(app, "dist", output_name);
if (Object.keys(file_map).includes(output_name) || Object.keys(style_file_map).includes(output_name)) {
log_warn(
`Duplicate output file ${output_name} generated from ${file}`
);
if (
Object.keys(file_map).includes(output_name) ||
Object.keys(style_file_map).includes(output_name)
) {
log_warn(`Duplicate output file ${output_name} generated from ${file}`);
}
if ([".css", ".scss", ".less", ".sass", ".styl"].includes(extension)) {
style_file_map[output_name] = file;
rtl_style_file_map[output_name.replace('/css/', '/css-rtl/')] = file;
rtl_style_file_map[output_name.replace("/css/", "/css-rtl/")] = file;
} else {
file_map[output_name] = file;
}
}
let build = build_files({
files: file_map,
outdir: output_path
outdir: output_path,
});
let style_build = build_style_files({
files: style_file_map,
outdir: output_path
outdir: output_path,
});
let rtl_style_build = build_style_files({
files: rtl_style_file_map,
outdir: output_path,
rtl_style: true
rtl_style: true,
});
return Promise.all([build, style_build, rtl_style_build]);
});
@ -188,11 +182,7 @@ function get_all_files_to_build(apps) {
for (let app of apps) {
let public_path = get_public_path(app);
include_patterns.push(
path.resolve(
public_path,
"**",
"*.bundle.{js,ts,css,sass,scss,less,styl}"
)
path.resolve(public_path, "**", "*.bundle.{js,ts,css,sass,scss,less,styl}")
);
ignore_patterns.push(
path.resolve(public_path, "node_modules"),
@ -202,7 +192,7 @@ function get_all_files_to_build(apps) {
return {
include_patterns,
ignore_patterns
ignore_patterns,
};
}
@ -223,16 +213,12 @@ function get_files_to_build(files) {
return {
include_patterns,
ignore_patterns
ignore_patterns,
};
}
function build_files({ files, outdir }) {
let build_plugins = [
html_plugin,
build_cleanup_plugin,
vue(),
];
let build_plugins = [html_plugin, build_cleanup_plugin, vue()];
return esbuild.build(get_build_options(files, outdir, build_plugins));
}
@ -247,8 +233,8 @@ function build_style_files({ files, outdir, rtl_style = false }) {
build_cleanup_plugin,
postCssPlugin({
plugins: plugins,
sassOptions: sass_options
})
sassOptions: sass_options,
}),
];
plugins.push(require("autoprefixer"));
@ -259,7 +245,7 @@ function get_build_options(files, outdir, plugins) {
return {
entryPoints: files,
entryNames: "[dir]/[name].[hash]",
target: ['es2017'],
target: ["es2017"],
outdir,
sourcemap: true,
bundle: true,
@ -267,12 +253,10 @@ function get_build_options(files, outdir, plugins) {
minify: PRODUCTION,
nodePaths: NODE_PATHS,
define: {
"process.env.NODE_ENV": JSON.stringify(
PRODUCTION ? "production" : "development"
)
"process.env.NODE_ENV": JSON.stringify(PRODUCTION ? "production" : "development"),
},
plugins: plugins,
watch: get_watch_config()
watch: get_watch_config(),
};
}
@ -286,17 +270,13 @@ function get_watch_config() {
log(chalk.dim(error.stack));
notify_redis({ error });
} else {
let {
new_assets_json,
prev_assets_json
} = await write_assets_json(result.metafile);
let { new_assets_json, prev_assets_json } = await write_assets_json(
result.metafile
);
let changed_files;
if (prev_assets_json) {
changed_files = get_rebuilt_assets(
prev_assets_json,
new_assets_json
);
changed_files = get_rebuilt_assets(prev_assets_json, new_assets_json);
let timestamp = new Date().toLocaleTimeString();
let message = `${timestamp}: Compiled ${changed_files.length} files...`;
@ -309,7 +289,7 @@ function get_watch_config() {
}
notify_redis({ success: true, changed_files });
}
}
},
};
}
return null;
@ -324,11 +304,11 @@ function log_built_assets(results) {
cliui.div(
{
text: chalk.cyan.bold("File"),
width: column_widths[0]
width: column_widths[0],
},
{
text: chalk.cyan.bold("Size"),
width: column_widths[1]
width: column_widths[1],
}
);
cliui.div("");
@ -344,7 +324,7 @@ function log_built_assets(results) {
output_by_dist_path[dist_path] = output_by_dist_path[dist_path] || [];
output_by_dist_path[dist_path].push({
name: filename,
size: (data.bytes / 1000).toFixed(2) + " Kb"
size: (data.bytes / 1000).toFixed(2) + " Kb",
});
}
@ -352,7 +332,7 @@ function log_built_assets(results) {
let files = output_by_dist_path[dist_path];
cliui.div({
text: dist_path,
width: column_widths[0]
width: column_widths[0],
});
for (let i in files) {
@ -367,11 +347,11 @@ function log_built_assets(results) {
cliui.div(
{
text: branch + chalk[color]("" + file.name),
width: column_widths[0]
width: column_widths[0],
},
{
text: file.size,
width: column_widths[1]
width: column_widths[1],
}
);
}
@ -393,7 +373,7 @@ async function write_assets_json(metafile) {
let asset_path = "/" + path.relative(sites_path, output);
if (info.entryPoint) {
let key = path.basename(info.entryPoint);
if (key.endsWith('.css') && asset_path.includes('/css-rtl/')) {
if (key.endsWith(".css") && asset_path.includes("/css-rtl/")) {
rtl = true;
key = `rtl_${key}`;
}
@ -401,7 +381,7 @@ async function write_assets_json(metafile) {
}
}
let assets_json_path = path.resolve(assets_path, `assets${rtl?'-rtl':''}.json`);
let assets_json_path = path.resolve(assets_path, `assets${rtl ? "-rtl" : ""}.json`);
let assets_json;
try {
assets_json = await fs.promises.readFile(assets_json_path, "utf-8");
@ -413,26 +393,23 @@ async function write_assets_json(metafile) {
let new_assets_json = Object.assign({}, assets_json, out);
curr_assets_json = new_assets_json;
await fs.promises.writeFile(
assets_json_path,
JSON.stringify(new_assets_json, null, 4)
);
await fs.promises.writeFile(assets_json_path, JSON.stringify(new_assets_json, null, 4));
await update_assets_json_in_cache();
return {
new_assets_json,
prev_assets_json
prev_assets_json,
};
}
function update_assets_json_in_cache() {
// update assets_json cache in redis, so that it can be read directly by python
return new Promise(resolve => {
return new Promise((resolve) => {
let client = get_redis_subscriber("redis_cache");
// handle error event to avoid printing stack traces
client.on("error", _ => {
client.on("error", (_) => {
log_warn("Cannot connect to redis_cache to update assets_json");
});
client.del("assets_json", err => {
client.del("assets_json", (err) => {
client.unref();
resolve();
});
@ -464,7 +441,7 @@ function run_build_command_for_apps(apps) {
async function notify_redis({ error, success, changed_files }) {
// notify redis which in turns tells socketio to publish this to browser
let subscriber = get_redis_subscriber("redis_socketio");
subscriber.on("error", _ => {
subscriber.on("error", (_) => {
log_warn("Cannot connect to redis_socketio for browser events");
});
@ -472,20 +449,20 @@ async function notify_redis({ error, success, changed_files }) {
if (error) {
let formatted = await esbuild.formatMessages(error.errors, {
kind: "error",
terminalWidth: 100
terminalWidth: 100,
});
let stack = error.stack.replace(new RegExp(bench_path, "g"), "");
payload = {
error,
formatted,
stack
stack,
};
}
if (success) {
payload = {
success: true,
changed_files,
live_reload: argv["live-reload"]
live_reload: argv["live-reload"],
};
}
@ -493,14 +470,14 @@ async function notify_redis({ error, success, changed_files }) {
"events",
JSON.stringify({
event: "build_event",
message: payload
message: payload,
})
);
}
function open_in_editor() {
let subscriber = get_redis_subscriber("redis_socketio");
subscriber.on("error", _ => {
subscriber.on("error", (_) => {
log_warn("Cannot connect to redis_socketio for open_in_editor events");
});
subscriber.on("message", (event, file) => {

View File

@ -4,24 +4,24 @@ module.exports = {
let path = require("path");
let fs = require("fs/promises");
build.onResolve({ filter: /\.html$/ }, args => {
build.onResolve({ filter: /\.html$/ }, (args) => {
return {
path: path.join(args.resolveDir, args.path),
namespace: "frappe-html"
namespace: "frappe-html",
};
});
build.onLoad({ filter: /.*/, namespace: "frappe-html" }, args => {
build.onLoad({ filter: /.*/, namespace: "frappe-html" }, (args) => {
let filepath = args.path;
let filename = path.basename(filepath).split(".")[0];
return fs
.readFile(filepath, "utf-8")
.then(content => {
.then((content) => {
content = scrub_html_template(content);
return {
contents: `\n\tfrappe.templates['${filename}'] = \`${content}\`;\n`,
watchFiles: [filepath]
watchFiles: [filepath],
};
})
.catch(() => {
@ -29,13 +29,13 @@ module.exports = {
contents: "",
warnings: [
{
text: `There was an error importing ${filepath}`
}
]
text: `There was an error importing ${filepath}`,
},
],
};
});
});
}
},
};
function scrub_html_template(content) {

View File

@ -1,11 +1,11 @@
module.exports = {
name: "frappe-ignore-asset",
setup(build) {
build.onResolve({ filter: /^\/assets\// }, args => {
build.onResolve({ filter: /^\/assets\// }, (args) => {
return {
path: args.path,
external: true
external: true,
};
});
}
},
};

View File

@ -1,19 +1,13 @@
let path = require("path");
let { get_app_path, app_list } = require("./utils");
let node_modules_path = path.resolve(
get_app_path("frappe"),
"..",
"node_modules"
);
let app_paths = app_list
.map(get_app_path)
.map(app_path => path.resolve(app_path, ".."));
let node_modules_path = path.resolve(get_app_path("frappe"), "..", "node_modules");
let app_paths = app_list.map(get_app_path).map((app_path) => path.resolve(app_path, ".."));
module.exports = {
includePaths: [node_modules_path, ...app_paths],
quietDeps: true,
importer: function(url) {
importer: function (url) {
if (url.startsWith("~")) {
// strip ~ so that it can resolve from node_modules
url = url.slice(1);
@ -24,7 +18,7 @@ module.exports = {
}
// normal file, let it go
return {
file: url
file: url,
};
}
},
};

View File

@ -26,24 +26,20 @@ const bundle_map = app_list.reduce((out, app) => {
const public_js_path = public_js_paths[app];
if (fs.existsSync(public_js_path)) {
const all_files = fs.readdirSync(public_js_path);
const js_files = all_files.filter(file => file.endsWith(".js"));
const js_files = all_files.filter((file) => file.endsWith(".js"));
for (let js_file of js_files) {
const filename = path.basename(js_file).split(".")[0];
out[path.join(app, "js", filename)] = path.resolve(
public_js_path,
js_file
);
out[path.join(app, "js", filename)] = path.resolve(public_js_path, js_file);
}
}
return out;
}, {});
const get_public_path = app => public_paths[app];
const get_public_path = (app) => public_paths[app];
const get_build_json_path = app =>
path.resolve(get_public_path(app), "build.json");
const get_build_json_path = (app) => path.resolve(get_public_path(app), "build.json");
function get_build_json(app) {
try {
@ -62,7 +58,7 @@ function delete_file(path) {
function run_serially(tasks) {
let result = Promise.resolve();
tasks.forEach(task => {
tasks.forEach((task) => {
if (task) {
result = result.then ? result.then(task) : Promise.resolve();
}
@ -70,12 +66,12 @@ function run_serially(tasks) {
return result;
}
const get_app_path = app => app_paths[app];
const get_app_path = (app) => app_paths[app];
function get_apps_list() {
return fs
.readFileSync(path.resolve(sites_path, "apps.txt"), {
encoding: "utf-8"
encoding: "utf-8",
})
.split("\n")
.filter(Boolean);
@ -116,7 +112,7 @@ function get_redis_subscriber(kind) {
let { get_redis_subscriber: get_redis, get_conf } = require("../node_utils");
if (process.env.CI == 1 || get_conf().developer_mode == 1) {
retry_strategy = () => { }
retry_strategy = () => {};
} else {
retry_strategy = function (options) {
// abort after 10 connection attempts
@ -124,7 +120,7 @@ function get_redis_subscriber(kind) {
return undefined;
}
return Math.min(options.attempt * 100, 2000);
}
};
}
return get_redis(kind, { retry_strategy });
}
@ -146,5 +142,5 @@ module.exports = {
log,
log_warn,
log_error,
get_redis_subscriber
get_redis_subscriber,
};

View File

@ -1,82 +1,77 @@
// Copyright (c) 2019, Frappe Technologies and contributors
// For license information, please see license.txt
frappe.ui.form.on('Assignment Rule', {
refresh: function(frm) {
frm.trigger('setup_assignment_days_buttons');
frm.trigger('set_options');
frappe.ui.form.on("Assignment Rule", {
refresh: function (frm) {
frm.trigger("setup_assignment_days_buttons");
frm.trigger("set_options");
// refresh description
frm.events.rule(frm);
},
setup: function(frm) {
setup: function (frm) {
frm.set_query("document_type", () => {
return {
filters: {
name: ["!=", "ToDo"]
}
name: ["!=", "ToDo"],
},
};
});
},
document_type: function(frm) {
frm.trigger('set_options');
document_type: function (frm) {
frm.trigger("set_options");
},
setup_assignment_days_buttons: function(frm) {
const labels = ['Weekends', 'Weekdays', 'All Days'];
setup_assignment_days_buttons: function (frm) {
const labels = ["Weekends", "Weekdays", "All Days"];
let get_days = (label) => {
const weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'];
const weekends = ['Saturday', 'Sunday'];
const weekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"];
const weekends = ["Saturday", "Sunday"];
return {
'All Days': weekdays.concat(weekends),
'Weekdays': weekdays,
'Weekends': weekends,
"All Days": weekdays.concat(weekends),
Weekdays: weekdays,
Weekends: weekends,
}[label];
};
let set_days = (e) => {
frm.clear_table('assignment_days');
frm.clear_table("assignment_days");
const label = $(e.currentTarget).text();
get_days(label).forEach((day) =>
frm.add_child('assignment_days', { day: day })
);
frm.refresh_field('assignment_days');
get_days(label).forEach((day) => frm.add_child("assignment_days", { day: day }));
frm.refresh_field("assignment_days");
};
labels.forEach(label =>
frm.fields_dict['assignment_days'].grid.add_custom_button(
label,
set_days,
'top'
)
labels.forEach((label) =>
frm.fields_dict["assignment_days"].grid.add_custom_button(label, set_days, "top")
);
},
rule: function(frm) {
rule: function (frm) {
const description_map = {
'Round Robin': __('Assign one by one, in sequence'),
'Load Balancing': __('Assign to the one who has the least assignments'),
'Based on Field': __('Assign to the user set in this field'),
"Round Robin": __("Assign one by one, in sequence"),
"Load Balancing": __("Assign to the one who has the least assignments"),
"Based on Field": __("Assign to the user set in this field"),
};
frm.get_field('rule').set_description(description_map[frm.doc.rule]);
frm.get_field("rule").set_description(description_map[frm.doc.rule]);
},
set_options(frm) {
const doctype = frm.doc.document_type;
frm.set_fields_as_options(
'field',
"field",
doctype,
(df) => ['Dynamic Link', 'Data'].includes(df.fieldtype)
|| (df.fieldtype == 'Link' && df.options == 'User'),
[{ label: 'Owner', value: 'owner' }]
(df) =>
["Dynamic Link", "Data"].includes(df.fieldtype) ||
(df.fieldtype == "Link" && df.options == "User"),
[{ label: "Owner", value: "owner" }]
);
if (doctype) {
frm.set_fields_as_options(
'due_date_based_on',
doctype,
(df) => ['Date', 'Datetime'].includes(df.fieldtype)
).then(options => frm.set_df_property('due_date_based_on', 'hidden', !options.length));
frm.set_fields_as_options("due_date_based_on", doctype, (df) =>
["Date", "Datetime"].includes(df.fieldtype)
).then((options) =>
frm.set_df_property("due_date_based_on", "hidden", !options.length)
);
}
},
});

View File

@ -2,41 +2,45 @@
// For license information, please see license.txt
frappe.provide("frappe.auto_repeat");
frappe.ui.form.on('Auto Repeat', {
setup: function(frm) {
frm.fields_dict['reference_doctype'].get_query = function() {
frappe.ui.form.on("Auto Repeat", {
setup: function (frm) {
frm.fields_dict["reference_doctype"].get_query = function () {
return {
query: "frappe.automation.doctype.auto_repeat.auto_repeat.get_auto_repeat_doctypes"
query: "frappe.automation.doctype.auto_repeat.auto_repeat.get_auto_repeat_doctypes",
};
};
frm.fields_dict['reference_document'].get_query = function() {
frm.fields_dict["reference_document"].get_query = function () {
return {
filters: {
"auto_repeat": ''
}
auto_repeat: "",
},
};
};
frm.fields_dict['print_format'].get_query = function() {
frm.fields_dict["print_format"].get_query = function () {
return {
filters: {
"doc_type": frm.doc.reference_doctype
}
doc_type: frm.doc.reference_doctype,
},
};
};
},
refresh: function(frm) {
refresh: function (frm) {
// auto repeat message
if (frm.is_new()) {
let customize_form_link = `<a href="/app/customize-form">${__('Customize Form')}</a>`;
frm.dashboard.set_headline(__('To configure Auto Repeat, enable "Allow Auto Repeat" from {0}.', [customize_form_link]));
let customize_form_link = `<a href="/app/customize-form">${__("Customize Form")}</a>`;
frm.dashboard.set_headline(
__('To configure Auto Repeat, enable "Allow Auto Repeat" from {0}.', [
customize_form_link,
])
);
}
// view document button
if (!frm.is_dirty()) {
let label = __('View {0}', [__(frm.doc.reference_doctype)]);
let label = __("View {0}", [__(frm.doc.reference_doctype)]);
frm.add_custom_button(label, () =>
frappe.set_route("List", frm.doc.reference_doctype, { auto_repeat: frm.doc.name })
);
@ -45,24 +49,24 @@ frappe.ui.form.on('Auto Repeat', {
// auto repeat schedule
frappe.auto_repeat.render_schedule(frm);
frm.trigger('toggle_submit_on_creation');
frm.trigger("toggle_submit_on_creation");
},
reference_doctype: function(frm) {
frm.trigger('toggle_submit_on_creation');
reference_doctype: function (frm) {
frm.trigger("toggle_submit_on_creation");
},
toggle_submit_on_creation: function(frm) {
toggle_submit_on_creation: function (frm) {
// submit on creation checkbox
if (frm.doc.reference_doctype) {
frappe.model.with_doctype(frm.doc.reference_doctype, () => {
let meta = frappe.get_meta(frm.doc.reference_doctype);
frm.toggle_display('submit_on_creation', meta.is_submittable);
frm.toggle_display("submit_on_creation", meta.is_submittable);
});
}
},
template: function(frm) {
template: function (frm) {
if (frm.doc.template) {
frappe.model.with_doc("Email Template", frm.doc.template, () => {
let email_template = frappe.get_doc("Email Template", frm.doc.template);
@ -74,11 +78,11 @@ frappe.ui.form.on('Auto Repeat', {
}
},
get_contacts: function(frm) {
frm.call('fetch_linked_contacts');
get_contacts: function (frm) {
frm.call("fetch_linked_contacts");
},
preview_message: function(frm) {
preview_message: function (frm) {
if (frm.doc.message) {
frappe.call({
method: "frappe.automation.doctype.auto_repeat.auto_repeat.generate_message_preview",
@ -86,29 +90,29 @@ frappe.ui.form.on('Auto Repeat', {
reference_dt: frm.doc.reference_doctype,
reference_doc: frm.doc.reference_document,
subject: frm.doc.subject,
message: frm.doc.message
message: frm.doc.message,
},
callback: function(r) {
callback: function (r) {
if (r.message) {
frappe.msgprint(r.message.message, r.message.subject)
frappe.msgprint(r.message.message, r.message.subject);
}
}
},
});
} else {
frappe.msgprint(__("Please setup a message first"), __("Message not setup"))
frappe.msgprint(__("Please setup a message first"), __("Message not setup"));
}
}
},
});
frappe.auto_repeat.render_schedule = function(frm) {
if (!frm.is_dirty() && frm.doc.status !== 'Disabled') {
frm.call("get_auto_repeat_schedule").then(r => {
frappe.auto_repeat.render_schedule = function (frm) {
if (!frm.is_dirty() && frm.doc.status !== "Disabled") {
frm.call("get_auto_repeat_schedule").then((r) => {
frm.dashboard.reset();
frm.dashboard.add_section(
frappe.render_template("auto_repeat_schedule", {
schedule_details: r.message || []
schedule_details: r.message || [],
}),
__('Auto Repeat Schedule')
__("Auto Repeat Schedule")
);
frm.dashboard.show();
});

View File

@ -1,11 +1,11 @@
frappe.listview_settings['Auto Repeat'] = {
frappe.listview_settings["Auto Repeat"] = {
add_fields: ["next_schedule_date"],
get_indicator: function(doc) {
get_indicator: function (doc) {
var colors = {
"Active": "green",
"Disabled": "red",
"Completed": "blue",
Active: "green",
Disabled: "red",
Completed: "blue",
};
return [__(doc.status), colors[doc.status], "status,=," + doc.status];
}
},
};

View File

@ -1,8 +1,7 @@
// Copyright (c) 2019, Frappe Technologies and contributors
// For license information, please see license.txt
frappe.ui.form.on('Milestone', {
frappe.ui.form.on("Milestone", {
// refresh: function(frm) {
// }
});

View File

@ -1,14 +1,14 @@
// Copyright (c) 2019, Frappe Technologies and contributors
// For license information, please see license.txt
frappe.ui.form.on('Milestone Tracker', {
refresh: function(frm) {
frm.trigger('update_options');
frappe.ui.form.on("Milestone Tracker", {
refresh: function (frm) {
frm.trigger("update_options");
},
document_type: function(frm) {
frm.trigger('update_options');
document_type: function (frm) {
frm.trigger("update_options");
},
update_options: function(frm) {
update_options: function (frm) {
// update select options for `track_field`
let doctype = frm.doc.document_type;
let track_fields = [];
@ -16,18 +16,16 @@ frappe.ui.form.on('Milestone Tracker', {
if (doctype) {
frappe.model.with_doctype(doctype, () => {
// get all date and datetime fields
frappe.get_meta(doctype).fields.map(df => {
if (['Link', 'Select'].includes(df.fieldtype)) {
track_fields.push({label: df.label, value: df.fieldname});
frappe.get_meta(doctype).fields.map((df) => {
if (["Link", "Select"].includes(df.fieldtype)) {
track_fields.push({ label: df.label, value: df.fieldname });
}
});
frm.set_df_property('track_field', 'options', track_fields);
frm.set_df_property("track_field", "options", track_fields);
});
} else {
// update select options
frm.set_df_property('track_field', 'options', []);
frm.set_df_property("track_field", "options", []);
}
},
});

View File

@ -2,60 +2,74 @@
// For license information, please see license.txt
frappe.ui.form.on("Address", {
refresh: function(frm) {
if(frm.doc.__islocal) {
refresh: function (frm) {
if (frm.doc.__islocal) {
const last_doc = frappe.contacts.get_last_doc(frm);
if(frappe.dynamic_link && frappe.dynamic_link.doc
&& frappe.dynamic_link.doc.name == last_doc.docname) {
frm.set_value('links', '');
frm.add_child('links', {
if (
frappe.dynamic_link &&
frappe.dynamic_link.doc &&
frappe.dynamic_link.doc.name == last_doc.docname
) {
frm.set_value("links", "");
frm.add_child("links", {
link_doctype: frappe.dynamic_link.doctype,
link_name: frappe.dynamic_link.doc[frappe.dynamic_link.fieldname]
link_name: frappe.dynamic_link.doc[frappe.dynamic_link.fieldname],
});
}
}
frm.set_query('link_doctype', "links", function() {
frm.set_query("link_doctype", "links", function () {
return {
query: "frappe.contacts.address_and_contact.filter_dynamic_link_doctypes",
filters: {
fieldtype: "HTML",
fieldname: "address_html",
}
}
},
};
});
frm.refresh_field("links");
if (frm.doc.links) {
for (let i in frm.doc.links) {
let link = frm.doc.links[i];
frm.add_custom_button(__("{0}: {1}", [__(link.link_doctype), __(link.link_name)]), function() {
frappe.set_route("Form", link.link_doctype, link.link_name);
}, __("Links"));
frm.add_custom_button(
__("{0}: {1}", [__(link.link_doctype), __(link.link_name)]),
function () {
frappe.set_route("Form", link.link_doctype, link.link_name);
},
__("Links")
);
}
}
},
validate: function(frm) {
validate: function (frm) {
// clear linked customer / supplier / sales partner on saving...
if(frm.doc.links) {
frm.doc.links.forEach(function(d) {
if (frm.doc.links) {
frm.doc.links.forEach(function (d) {
frappe.model.remove_from_locals(d.link_doctype, d.link_name);
});
}
},
after_save: function(frm) {
after_save: function (frm) {
frappe.run_serially([
() => frappe.timeout(1),
() => {
const last_doc = frappe.contacts.get_last_doc(frm);
if (frappe.dynamic_link && frappe.dynamic_link.doc && frappe.dynamic_link.doc.name == last_doc.docname) {
if (
frappe.dynamic_link &&
frappe.dynamic_link.doc &&
frappe.dynamic_link.doc.name == last_doc.docname
) {
for (let i in frm.doc.links) {
let link = frm.doc.links[i];
if (last_doc.doctype == link.link_doctype && last_doc.docname == link.link_name) {
frappe.set_route('Form', last_doc.doctype, last_doc.docname);
if (
last_doc.doctype == link.link_doctype &&
last_doc.docname == link.link_name
) {
frappe.set_route("Form", last_doc.doctype, last_doc.docname);
}
}
}
}
},
]);
}
},
});

View File

@ -1,16 +1,16 @@
// Copyright (c) 2016, Frappe Technologies and contributors
// For license information, please see license.txt
frappe.ui.form.on('Address Template', {
refresh: function(frm) {
if(frm.is_new() && !frm.doc.template) {
frappe.ui.form.on("Address Template", {
refresh: function (frm) {
if (frm.is_new() && !frm.doc.template) {
// set default template via js so that it is translated
frappe.call({
method: 'frappe.contacts.doctype.address_template.address_template.get_default_address_template',
callback: function(r) {
frm.set_value('template', r.message);
}
method: "frappe.contacts.doctype.address_template.address_template.get_default_address_template",
callback: function (r) {
frm.set_value("template", r.message);
},
});
}
}
},
});

View File

@ -5,49 +5,52 @@ frappe.ui.form.on("Contact", {
onload(frm) {
frm.email_field = "email_id";
},
refresh: function(frm) {
if(frm.doc.__islocal) {
refresh: function (frm) {
if (frm.doc.__islocal) {
const last_doc = frappe.contacts.get_last_doc(frm);
if(frappe.dynamic_link && frappe.dynamic_link.doc
&& frappe.dynamic_link.doc.name == last_doc.docname) {
frm.set_value('links', '');
frm.add_child('links', {
if (
frappe.dynamic_link &&
frappe.dynamic_link.doc &&
frappe.dynamic_link.doc.name == last_doc.docname
) {
frm.set_value("links", "");
frm.add_child("links", {
link_doctype: frappe.dynamic_link.doctype,
link_name: frappe.dynamic_link.doc[frappe.dynamic_link.fieldname]
link_name: frappe.dynamic_link.doc[frappe.dynamic_link.fieldname],
});
}
}
if(!frm.doc.user && !frm.is_new() && frm.perm[0].write) {
frm.add_custom_button(__("Invite as User"), function() {
if (!frm.doc.user && !frm.is_new() && frm.perm[0].write) {
frm.add_custom_button(__("Invite as User"), function () {
return frappe.call({
method: "frappe.contacts.doctype.contact.contact.invite_user",
args: {
contact: frm.doc.name
contact: frm.doc.name,
},
callback: function(r) {
callback: function (r) {
frm.set_value("user", r.message);
}
},
});
});
}
frm.set_query('link_doctype', "links", function() {
frm.set_query("link_doctype", "links", function () {
return {
query: "frappe.contacts.address_and_contact.filter_dynamic_link_doctypes",
filters: {
fieldtype: "HTML",
fieldname: "contact_html",
}
}
},
};
});
frm.refresh_field("links");
let numbers = frm.doc.phone_nos;
if (numbers && numbers.length && frappe.phone_call.handler) {
frm.add_custom_button(__('Call'), () => {
frm.add_custom_button(__("Call"), () => {
numbers = frm.doc.phone_nos
.sort((prev, next) => next.is_primary_mobile_no - prev.is_primary_mobile_no)
.map(d => d.phone);
.map((d) => d.phone);
frappe.phone_call.handler(numbers);
});
}
@ -55,73 +58,94 @@ frappe.ui.form.on("Contact", {
if (frm.doc.links) {
frappe.call({
method: "frappe.contacts.doctype.contact.contact.address_query",
args: {links: frm.doc.links},
callback: function(r) {
args: { links: frm.doc.links },
callback: function (r) {
if (r && r.message) {
frm.set_query("address", function () {
return {
filters: {
name: ["in", r.message],
}
}
},
};
});
}
}
},
});
for (let i in frm.doc.links) {
let link = frm.doc.links[i];
frm.add_custom_button(__("{0}: {1}", [__(link.link_doctype), __(link.link_name)]), function() {
frappe.set_route("Form", link.link_doctype, link.link_name);
}, __("Links"));
frm.add_custom_button(
__("{0}: {1}", [__(link.link_doctype), __(link.link_name)]),
function () {
frappe.set_route("Form", link.link_doctype, link.link_name);
},
__("Links")
);
}
}
},
validate: function(frm) {
validate: function (frm) {
// clear linked customer / supplier / sales partner on saving...
if(frm.doc.links) {
frm.doc.links.forEach(function(d) {
if (frm.doc.links) {
frm.doc.links.forEach(function (d) {
frappe.model.remove_from_locals(d.link_doctype, d.link_name);
});
}
},
after_save: function(frm) {
after_save: function (frm) {
frappe.run_serially([
() => frappe.timeout(1),
() => {
const last_doc = frappe.contacts.get_last_doc(frm);
if (frappe.dynamic_link && frappe.dynamic_link.doc && frappe.dynamic_link.doc.name == last_doc.docname) {
if (
frappe.dynamic_link &&
frappe.dynamic_link.doc &&
frappe.dynamic_link.doc.name == last_doc.docname
) {
for (let i in frm.doc.links) {
let link = frm.doc.links[i];
if (last_doc.doctype == link.link_doctype && last_doc.docname == link.link_name) {
frappe.set_route('Form', last_doc.doctype, last_doc.docname);
if (
last_doc.doctype == link.link_doctype &&
last_doc.docname == link.link_name
) {
frappe.set_route("Form", last_doc.doctype, last_doc.docname);
}
}
}
}
},
]);
},
sync_with_google_contacts: function(frm) {
sync_with_google_contacts: function (frm) {
if (frm.doc.sync_with_google_contacts) {
frappe.db.get_value("Google Contacts", {"email_id": frappe.session.user}, "name", (r) => {
if (r && r.name) {
frm.set_value("google_contacts", r.name);
frappe.db.get_value(
"Google Contacts",
{ email_id: frappe.session.user },
"name",
(r) => {
if (r && r.name) {
frm.set_value("google_contacts", r.name);
}
}
})
);
}
}
},
});
frappe.ui.form.on("Dynamic Link", {
link_name:function(frm, cdt, cdn){
link_name: function (frm, cdt, cdn) {
var child = locals[cdt][cdn];
if(child.link_name) {
if (child.link_name) {
frappe.model.with_doctype(child.link_doctype, function () {
var title_field = frappe.get_meta(child.link_doctype).title_field || "name"
frappe.model.get_value(child.link_doctype, child.link_name, title_field, function (r) {
frappe.model.set_value(cdt, cdn, "link_title", r[title_field])
})
})
var title_field = frappe.get_meta(child.link_doctype).title_field || "name";
frappe.model.get_value(
child.link_doctype,
child.link_name,
title_field,
function (r) {
frappe.model.set_value(cdt, cdn, "link_title", r[title_field]);
}
);
});
}
}
})
},
});

View File

@ -1,3 +1,3 @@
frappe.listview_settings['Contact'] = {
frappe.listview_settings["Contact"] = {
add_fields: ["image"],
};
};

View File

@ -1,8 +1,6 @@
// Copyright (c) 2017, Frappe Technologies and contributors
// For license information, please see license.txt
frappe.ui.form.on('Gender', {
refresh: function() {
}
frappe.ui.form.on("Gender", {
refresh: function () {},
});

View File

@ -1,8 +1,6 @@
// Copyright (c) 2017, Frappe Technologies and contributors
// For license information, please see license.txt
frappe.ui.form.on('Salutation', {
refresh: function() {
}
frappe.ui.form.on("Salutation", {
refresh: function () {},
});

View File

@ -2,32 +2,32 @@
// For license information, please see license.txt
frappe.query_reports["Addresses And Contacts"] = {
"filters": [
filters: [
{
"reqd": 1,
"fieldname":"reference_doctype",
"label": __("Entity Type"),
"fieldtype": "Link",
"options": "DocType",
"get_query": function() {
reqd: 1,
fieldname: "reference_doctype",
label: __("Entity Type"),
fieldtype: "Link",
options: "DocType",
get_query: function () {
return {
"filters": {
"name": ["in", "Contact, Address"],
}
}
}
filters: {
name: ["in", "Contact, Address"],
},
};
},
},
{
"fieldname":"reference_name",
"label": __("Entity Name"),
"fieldtype": "Dynamic Link",
"get_options": function() {
let reference_doctype = frappe.query_report.get_filter_value('reference_doctype');
if(!reference_doctype) {
fieldname: "reference_name",
label: __("Entity Name"),
fieldtype: "Dynamic Link",
get_options: function () {
let reference_doctype = frappe.query_report.get_filter_value("reference_doctype");
if (!reference_doctype) {
frappe.throw(__("Please select Entity Type first"));
}
return reference_doctype;
}
}
]
}
},
},
],
};

View File

@ -1,17 +1,17 @@
// Copyright (c) 2019, Frappe Technologies and contributors
// For license information, please see license.txt
frappe.ui.form.on('Access Log', {
frappe.ui.form.on("Access Log", {
show_document: function (frm) {
frappe.set_route('Form', frm.doc.export_from, frm.doc.reference_document);
frappe.set_route("Form", frm.doc.export_from, frm.doc.reference_document);
},
show_report: function (frm) {
if (frm.doc.report_name.includes('/')) {
if (frm.doc.report_name.includes("/")) {
frappe.set_route(frm.doc.report_name);
} else {
let filters = frm.doc.filters ? JSON.parse(frm.doc.filters) : {};
frappe.set_route('query-report', frm.doc.report_name, filters);
frappe.set_route("query-report", frm.doc.report_name, filters);
}
}
},
});

View File

@ -1,8 +1,6 @@
// Copyright (c) 2017, Frappe Technologies and contributors
// For license information, please see license.txt
frappe.ui.form.on('Activity Log', {
refresh: function() {
}
frappe.ui.form.on("Activity Log", {
refresh: function () {},
});

View File

@ -1,13 +1,12 @@
frappe.listview_settings['Activity Log'] = {
get_indicator: function(doc) {
if(doc.operation == "Login" && doc.status == "Success")
return [__(doc.status), "green"];
else if(doc.operation == "Login" && doc.status == "Failed")
frappe.listview_settings["Activity Log"] = {
get_indicator: function (doc) {
if (doc.operation == "Login" && doc.status == "Success") return [__(doc.status), "green"];
else if (doc.operation == "Login" && doc.status == "Failed")
return [__(doc.status), "red"];
},
onload: function(listview) {
onload: function (listview) {
frappe.require("logtypes.bundle.js", () => {
frappe.utils.logtypes.show_log_retention_message(cur_list.doctype);
})
});
},
};

View File

@ -1,8 +1,7 @@
// Copyright (c) 2019, Frappe Technologies and contributors
// For license information, please see license.txt
frappe.ui.form.on('Comment', {
frappe.ui.form.on("Comment", {
// refresh: function(frm) {
// }
});

View File

@ -1,120 +1,158 @@
frappe.ui.form.on("Communication", {
onload: function(frm) {
if(frm.doc.content) {
onload: function (frm) {
if (frm.doc.content) {
frm.doc.content = frappe.dom.remove_script_and_style(frm.doc.content);
}
frm.set_query("reference_doctype", function() {
frm.set_query("reference_doctype", function () {
return {
filters: {
"issingle": 0,
"istable": 0
}
}
issingle: 0,
istable: 0,
},
};
});
},
refresh: function(frm) {
if(frm.is_new()) return;
refresh: function (frm) {
if (frm.is_new()) return;
frm.convert_to_click && frm.set_convert_button();
frm.subject_field = "subject";
// content field contains weird table html that does not render well in Quill
// this field is not to be edited directly anyway, so setting it as read only
frm.set_df_property('content', 'read_only', 1);
frm.set_df_property("content", "read_only", 1);
if(frm.doc.reference_doctype && frm.doc.reference_name) {
frm.add_custom_button(__(frm.doc.reference_name), function() {
if (frm.doc.reference_doctype && frm.doc.reference_name) {
frm.add_custom_button(__(frm.doc.reference_name), function () {
frappe.set_route("Form", frm.doc.reference_doctype, frm.doc.reference_name);
});
} else {
// if an unlinked communication, set email field
if (frm.doc.sent_or_received==="Received") {
if (frm.doc.sent_or_received === "Received") {
frm.email_field = "sender";
} else {
frm.email_field = "recipients";
}
}
if(frm.doc.status==="Open") {
frm.add_custom_button(__("Close"), function() {
frm.trigger('mark_as_closed_open');
if (frm.doc.status === "Open") {
frm.add_custom_button(__("Close"), function () {
frm.trigger("mark_as_closed_open");
});
} else if (frm.doc.status !== "Linked") {
frm.add_custom_button(__("Reopen"), function() {
frm.trigger('mark_as_closed_open');
frm.add_custom_button(__("Reopen"), function () {
frm.trigger("mark_as_closed_open");
});
}
frm.add_custom_button(__("Relink"), function() {
frm.trigger('show_relink_dialog');
frm.add_custom_button(__("Relink"), function () {
frm.trigger("show_relink_dialog");
});
if(frm.doc.communication_type=="Communication"
&& frm.doc.communication_medium == "Email"
&& frm.doc.sent_or_received == "Received") {
frm.add_custom_button(__("Reply"), function() {
frm.trigger('reply');
if (
frm.doc.communication_type == "Communication" &&
frm.doc.communication_medium == "Email" &&
frm.doc.sent_or_received == "Received"
) {
frm.add_custom_button(__("Reply"), function () {
frm.trigger("reply");
});
frm.add_custom_button(__("Reply All"), function() {
frm.trigger('reply_all');
}, __("Actions"));
frm.add_custom_button(
__("Reply All"),
function () {
frm.trigger("reply_all");
},
__("Actions")
);
frm.add_custom_button(__("Forward"), function() {
frm.trigger('forward_mail');
}, __("Actions"));
frm.add_custom_button(
__("Forward"),
function () {
frm.trigger("forward_mail");
},
__("Actions")
);
frm.add_custom_button(frm.doc.seen ? __("Mark as Unread") : __("Mark as Read"), function() {
frm.trigger('mark_as_read_unread');
}, __("Actions"));
frm.add_custom_button(
frm.doc.seen ? __("Mark as Unread") : __("Mark as Read"),
function () {
frm.trigger("mark_as_read_unread");
},
__("Actions")
);
frm.add_custom_button(__("Move"), function() {
frm.trigger('show_move_dialog');
}, __("Actions"));
frm.add_custom_button(
__("Move"),
function () {
frm.trigger("show_move_dialog");
},
__("Actions")
);
if(frm.doc.email_status != "Spam")
frm.add_custom_button(__("Mark as Spam"), function() {
frm.trigger('mark_as_spam');
}, __("Actions"));
if (frm.doc.email_status != "Spam")
frm.add_custom_button(
__("Mark as Spam"),
function () {
frm.trigger("mark_as_spam");
},
__("Actions")
);
if(frm.doc.email_status != "Trash") {
frm.add_custom_button(__("Move To Trash"), function() {
frm.trigger('move_to_trash');
}, __("Actions"));
if (frm.doc.email_status != "Trash") {
frm.add_custom_button(
__("Move To Trash"),
function () {
frm.trigger("move_to_trash");
},
__("Actions")
);
}
frm.add_custom_button(__("Contact"), function() {
frm.trigger('add_to_contact');
}, __('Create'));
frm.add_custom_button(
__("Contact"),
function () {
frm.trigger("add_to_contact");
},
__("Create")
);
}
if(frm.doc.communication_type=="Communication"
&& frm.doc.communication_medium == "Phone"
&& frm.doc.sent_or_received == "Received"){
frm.add_custom_button(__("Add Contact"), function() {
frm.trigger('add_to_contact');
}, __("Actions"));
if (
frm.doc.communication_type == "Communication" &&
frm.doc.communication_medium == "Phone" &&
frm.doc.sent_or_received == "Received"
) {
frm.add_custom_button(
__("Add Contact"),
function () {
frm.trigger("add_to_contact");
},
__("Actions")
);
}
},
show_relink_dialog: function(frm) {
var d = new frappe.ui.Dialog ({
show_relink_dialog: function (frm) {
var d = new frappe.ui.Dialog({
title: __("Relink Communication"),
fields: [{
"fieldtype": "Link",
"options": "DocType",
"label": __("Reference Doctype"),
"fieldname": "reference_doctype",
"get_query": function() {return {"query": "frappe.email.get_communication_doctype"}}
},
{
"fieldtype": "Dynamic Link",
"options": "reference_doctype",
"label": __("Reference Name"),
"fieldname": "reference_name"
}]
fields: [
{
fieldtype: "Link",
options: "DocType",
label: __("Reference Doctype"),
fieldname: "reference_doctype",
get_query: function () {
return { query: "frappe.email.get_communication_doctype" };
},
},
{
fieldtype: "Dynamic Link",
options: "reference_doctype",
label: __("Reference Name"),
fieldname: "reference_name",
},
],
});
d.set_value("reference_doctype", frm.doc.reference_doctype);
d.set_value("reference_name", frm.doc.reference_name);
@ -122,24 +160,27 @@ frappe.ui.form.on("Communication", {
var values = d.get_values();
if (values) {
frappe.confirm(
__('Are you sure you want to relink this communication to {0}?', [values["reference_name"]]),
__("Are you sure you want to relink this communication to {0}?", [
values["reference_name"],
]),
function () {
d.hide();
frappe.call({
method: "frappe.email.relink",
args: {
"name": frm.doc.name,
"reference_doctype": values["reference_doctype"],
"reference_name": values["reference_name"]
name: frm.doc.name,
reference_doctype: values["reference_doctype"],
reference_name: values["reference_name"],
},
callback: function () {
frm.refresh();
}
},
});
},
function() {
function () {
frappe.show_alert({
message: __('Document not Relinked'), 'indicator': 'info'
message: __("Document not Relinked"),
indicator: "info",
});
}
);
@ -148,24 +189,26 @@ frappe.ui.form.on("Communication", {
d.show();
},
show_move_dialog: function(frm) {
var d = new frappe.ui.Dialog ({
show_move_dialog: function (frm) {
var d = new frappe.ui.Dialog({
title: __("Move"),
fields: [{
"fieldtype": "Link",
"options": "Email Account",
"label": __("Email Account"),
"fieldname": "email_account",
"reqd": 1,
"get_query": function() {
return {
"filters": {
"name": ["!=", frm.doc.email_account],
"enable_incoming": ["=", 1]
}
};
}
}],
fields: [
{
fieldtype: "Link",
options: "Email Account",
label: __("Email Account"),
fieldname: "email_account",
reqd: 1,
get_query: function () {
return {
filters: {
name: ["!=", frm.doc.email_account],
enable_incoming: ["=", 1],
},
};
},
},
],
primary_action_label: __("Move"),
primary_action(values) {
d.hide();
@ -173,88 +216,88 @@ frappe.ui.form.on("Communication", {
method: "frappe.email.inbox.move_email",
args: {
communication: frm.doc.name,
email_account: values.email_account
email_account: values.email_account,
},
freeze: true,
callback: function() {
callback: function () {
window.history.back();
}
},
});
}
},
});
d.show();
},
mark_as_read_unread: function(frm) {
var action = frm.doc.seen? "Unread": "Read";
mark_as_read_unread: function (frm) {
var action = frm.doc.seen ? "Unread" : "Read";
var flag = "(\\SEEN)";
return frappe.call({
method: "frappe.email.inbox.create_email_flag_queue",
args: {
'names': [frm.doc.name],
'action': action,
'flag': flag
names: [frm.doc.name],
action: action,
flag: flag,
},
freeze: true,
callback: function() {
callback: function () {
frm.reload_doc();
}
},
});
},
mark_as_closed_open: function(frm) {
mark_as_closed_open: function (frm) {
var status = frm.doc.status == "Open" ? "Closed" : "Open";
return frappe.call({
method: "frappe.email.inbox.mark_as_closed_open",
args: {
communication: frm.doc.name,
status: status
status: status,
},
freeze: true,
callback: function() {
callback: function () {
frm.reload_doc();
}
},
});
},
reply: function(frm) {
reply: function (frm) {
var args = frm.events.get_mail_args(frm);
$.extend(args, {
subject: __("Re: {0}", [frm.doc.subject]),
recipients: frm.doc.sender
})
recipients: frm.doc.sender,
});
new frappe.views.CommunicationComposer(args);
},
reply_all: function(frm) {
var args = frm.events.get_mail_args(frm)
reply_all: function (frm) {
var args = frm.events.get_mail_args(frm);
$.extend(args, {
subject: __("Res: {0}", [frm.doc.subject]),
recipients: frm.doc.sender,
cc: frm.doc.cc
})
cc: frm.doc.cc,
});
new frappe.views.CommunicationComposer(args);
},
forward_mail: function(frm) {
var args = frm.events.get_mail_args(frm)
forward_mail: function (frm) {
var args = frm.events.get_mail_args(frm);
$.extend(args, {
forward: true,
subject: __("Fw: {0}", [frm.doc.subject]),
})
});
new frappe.views.CommunicationComposer(args);
},
get_mail_args: function(frm) {
var sender_email_id = ""
$.each(frappe.boot.email_accounts, function(idx, account) {
if(account.email_account == frm.doc.email_account) {
sender_email_id = account.email_id
return
get_mail_args: function (frm) {
var sender_email_id = "";
$.each(frappe.boot.email_accounts, function (idx, account) {
if (account.email_account == frm.doc.email_account) {
sender_email_id = account.email_id;
return;
}
});
@ -263,51 +306,51 @@ frappe.ui.form.on("Communication", {
doc: frm.doc,
last_email: frm.doc,
sender: sender_email_id,
attachments: frm.doc.attachments
}
attachments: frm.doc.attachments,
};
},
add_to_contact: function(frm) {
add_to_contact: function (frm) {
var me = this;
var fullname = frm.doc.sender_full_name || ""
var fullname = frm.doc.sender_full_name || "";
var names = fullname.split(" ")
var first_name = names[0]
var last_name = names.length >= 2? names[names.length - 1]: ""
var names = fullname.split(" ");
var first_name = names[0];
var last_name = names.length >= 2 ? names[names.length - 1] : "";
frappe.route_options = {
"email_id": frm.doc.sender || "",
"first_name": first_name,
"last_name": last_name,
"mobile_no": frm.doc.phone_no || ""
}
frappe.new_doc("Contact")
email_id: frm.doc.sender || "",
first_name: first_name,
last_name: last_name,
mobile_no: frm.doc.phone_no || "",
};
frappe.new_doc("Contact");
},
mark_as_spam: function(frm) {
mark_as_spam: function (frm) {
frappe.call({
method: "frappe.email.inbox.mark_as_spam",
args: {
communication: frm.doc.name,
sender: frm.doc.sender
sender: frm.doc.sender,
},
freeze: true,
callback: function(r) {
frappe.msgprint(__("Email has been marked as spam"))
}
})
callback: function (r) {
frappe.msgprint(__("Email has been marked as spam"));
},
});
},
move_to_trash: function(frm) {
move_to_trash: function (frm) {
frappe.call({
method: "frappe.email.inbox.mark_as_trash",
args: {
communication: frm.doc.name
communication: frm.doc.name,
},
freeze: true,
callback: function(r) {
frappe.msgprint(__("Email has been moved to trash"))
}
})
}
callback: function (r) {
frappe.msgprint(__("Email has been moved to trash"));
},
});
},
});

View File

@ -1,25 +1,32 @@
frappe.listview_settings['Communication'] = {
frappe.listview_settings["Communication"] = {
add_fields: [
"sent_or_received","recipients", "subject",
"communication_medium", "communication_type",
"sender", "seen", "reference_doctype", "reference_name",
"has_attachment", "communication_date"
"sent_or_received",
"recipients",
"subject",
"communication_medium",
"communication_type",
"sender",
"seen",
"reference_doctype",
"reference_name",
"has_attachment",
"communication_date",
],
filters: [["status", "=", "Open"]],
onload: function(list_view) {
let method = "frappe.email.inbox.create_email_flag_queue"
onload: function (list_view) {
let method = "frappe.email.inbox.create_email_flag_queue";
list_view.page.add_menu_item(__("Mark as Read"), function() {
list_view.page.add_menu_item(__("Mark as Read"), function () {
list_view.call_for_selected_items(method, { action: "Read" });
});
list_view.page.add_menu_item(__("Mark as Unread"), function() {
list_view.page.add_menu_item(__("Mark as Unread"), function () {
list_view.call_for_selected_items(method, { action: "Unread" });
});
},
primary_action: function() {
primary_action: function () {
new frappe.views.CommunicationComposer();
}
},
};

View File

@ -1,8 +1,6 @@
// Copyright (c) 2016, Frappe Technologies and contributors
// For license information, please see license.txt
frappe.ui.form.on('Custom DocPerm', {
refresh: function(frm) {
}
frappe.ui.form.on("Custom DocPerm", {
refresh: function (frm) {},
});

View File

@ -1,8 +1,6 @@
// Copyright (c) 2016, Frappe Technologies and contributors
// For license information, please see license.txt
frappe.ui.form.on('Custom Role', {
refresh: function(frm) {
}
frappe.ui.form.on("Custom Role", {
refresh: function (frm) {},
});

View File

@ -1,64 +1,65 @@
// Copyright (c) 2018, Frappe Technologies and contributors
// For license information, please see license.txt
frappe.ui.form.on('Data Export', {
refresh: frm => {
frappe.ui.form.on("Data Export", {
refresh: (frm) => {
frm.disable_save();
frm.page.set_primary_action('Export', () => {
frm.page.set_primary_action("Export", () => {
can_export(frm) ? export_data(frm) : null;
});
},
onload: (frm) => {
frm.set_query("reference_doctype", () => {
return {
"filters": {
"issingle": 0,
"istable": 0,
"name": ['in', frappe.boot.user.can_export]
}
filters: {
issingle: 0,
istable: 0,
name: ["in", frappe.boot.user.can_export],
},
};
});
},
reference_doctype: frm => {
reference_doctype: (frm) => {
const doctype = frm.doc.reference_doctype;
if (doctype) {
frappe.model.with_doctype(doctype, () => set_field_options(frm));
} else {
reset_filter_and_field(frm);
}
}
},
});
const can_export = frm => {
const can_export = (frm) => {
const doctype = frm.doc.reference_doctype;
const parent_multicheck_options = frm.fields_multicheck[doctype] ?
frm.fields_multicheck[doctype].get_checked_options() : [];
const parent_multicheck_options = frm.fields_multicheck[doctype]
? frm.fields_multicheck[doctype].get_checked_options()
: [];
let is_valid_form = false;
if (!doctype) {
frappe.msgprint(__('Please select the Document Type.'));
frappe.msgprint(__("Please select the Document Type."));
} else if (!parent_multicheck_options.length) {
frappe.msgprint(__('Atleast one field of Parent Document Type is mandatory'));
frappe.msgprint(__("Atleast one field of Parent Document Type is mandatory"));
} else {
is_valid_form = true;
}
return is_valid_form;
};
const export_data = frm => {
let get_template_url = '/api/method/frappe.core.doctype.data_export.exporter.export_data';
const export_data = (frm) => {
let get_template_url = "/api/method/frappe.core.doctype.data_export.exporter.export_data";
var export_params = () => {
let columns = {};
Object.keys(frm.fields_multicheck).forEach(dt => {
Object.keys(frm.fields_multicheck).forEach((dt) => {
const options = frm.fields_multicheck[dt].get_checked_options();
columns[dt] = options;
});
return {
doctype: frm.doc.reference_doctype,
select_columns: JSON.stringify(columns),
filters: frm.filter_list.get_filters().map(filter => filter.slice(1, 4)),
filters: frm.filter_list.get_filters().map((filter) => filter.slice(1, 4)),
file_type: frm.doc.file_type,
template: true,
with_data: 1
with_data: 1,
};
};
@ -86,26 +87,24 @@ const set_field_options = (frm) => {
frm.filter_list = new frappe.ui.FilterGroup({
parent: filter_wrapper,
doctype: doctype,
on_change: () => { },
on_change: () => {},
});
// Add 'Select All' and 'Unselect All' button
make_multiselect_buttons(parent_wrapper);
frm.fields_multicheck = {};
related_doctypes.forEach(dt => {
related_doctypes.forEach((dt) => {
frm.fields_multicheck[dt] = add_doctype_field_multicheck_control(dt, parent_wrapper);
});
frm.refresh();
};
const make_multiselect_buttons = parent_wrapper => {
const button_container = $(parent_wrapper)
.append('<div class="flex"></div>')
.find('.flex');
const make_multiselect_buttons = (parent_wrapper) => {
const button_container = $(parent_wrapper).append('<div class="flex"></div>').find(".flex");
["Select All", "Unselect All"].map(d => {
["Select All", "Unselect All"].map((d) => {
frappe.ui.form.make_control({
parent: $(button_container),
df: {
@ -113,59 +112,59 @@ const make_multiselect_buttons = parent_wrapper => {
fieldname: frappe.scrub(d),
fieldtype: "Button",
click: () => {
checkbox_toggle(d !== 'Select All');
}
checkbox_toggle(d !== "Select All");
},
},
render_input: true
render_input: true,
});
});
$(button_container).find('.frappe-control').map((index, button) => {
$(button).css({"margin-right": "1em"});
});
$(button_container)
.find(".frappe-control")
.map((index, button) => {
$(button).css({ "margin-right": "1em" });
});
function checkbox_toggle(checked) {
$(parent_wrapper).find('[data-fieldtype="MultiCheck"]').map((index, element) => {
$(element).find(`:checkbox`).prop("checked", checked).trigger('click');
});
$(parent_wrapper)
.find('[data-fieldtype="MultiCheck"]')
.map((index, element) => {
$(element).find(`:checkbox`).prop("checked", checked).trigger("click");
});
}
};
const get_doctypes = parentdt => {
return [parentdt].concat(
frappe.meta.get_table_fields(parentdt).map(df => df.options)
);
const get_doctypes = (parentdt) => {
return [parentdt].concat(frappe.meta.get_table_fields(parentdt).map((df) => df.options));
};
const add_doctype_field_multicheck_control = (doctype, parent_wrapper) => {
const fields = get_fields(doctype);
const options = fields
.map(df => {
return {
label: df.label,
value: df.fieldname,
danger: df.reqd,
checked: 1
};
});
const options = fields.map((df) => {
return {
label: df.label,
value: df.fieldname,
danger: df.reqd,
checked: 1,
};
});
const multicheck_control = frappe.ui.form.make_control({
parent: parent_wrapper,
df: {
"label": doctype,
"fieldname": doctype + '_fields',
"fieldtype": "MultiCheck",
"options": options,
"columns": 3,
label: doctype,
fieldname: doctype + "_fields",
fieldtype: "MultiCheck",
options: options,
columns: 3,
},
render_input: true
render_input: true,
});
multicheck_control.refresh_input();
return multicheck_control;
};
const filter_fields = df => frappe.model.is_value_type(df) && !df.hidden;
const get_fields = dt => frappe.meta.get_docfields(dt).filter(filter_fields);
const filter_fields = (df) => frappe.model.is_value_type(df) && !df.hidden;
const get_fields = (dt) => frappe.meta.get_docfields(dt).filter(filter_fields);

View File

@ -1,17 +1,17 @@
// Copyright (c) 2019, Frappe Technologies and contributors
// For license information, please see license.txt
frappe.ui.form.on('Data Import', {
frappe.ui.form.on("Data Import", {
setup(frm) {
frappe.realtime.on('data_import_refresh', ({ data_import }) => {
frappe.realtime.on("data_import_refresh", ({ data_import }) => {
frm.import_in_progress = false;
if (data_import !== frm.doc.name) return;
frappe.model.clear_doc('Data Import', frm.doc.name);
frappe.model.with_doc('Data Import', frm.doc.name).then(() => {
frappe.model.clear_doc("Data Import", frm.doc.name);
frappe.model.with_doc("Data Import", frm.doc.name).then(() => {
frm.refresh();
});
});
frappe.realtime.on('data_import_progress', data => {
frappe.realtime.on("data_import_progress", (data) => {
frm.import_in_progress = true;
if (data.data_import !== frm.doc.name) {
return;
@ -31,20 +31,16 @@ frappe.ui.form.on('Data Import', {
if (data.success) {
let message_args = [data.current, data.total, eta_message];
message =
frm.doc.import_type === 'Insert New Records'
? __('Importing {0} of {1}, {2}', message_args)
: __('Updating {0} of {1}, {2}', message_args);
frm.doc.import_type === "Insert New Records"
? __("Importing {0} of {1}, {2}", message_args)
: __("Updating {0} of {1}, {2}", message_args);
}
if (data.skipping) {
message = __('Skipping {0} of {1}, {2}', [
data.current,
data.total,
eta_message
]);
message = __("Skipping {0} of {1}, {2}", [data.current, data.total, eta_message]);
}
frm.dashboard.show_progress(__('Import Progress'), percent, message);
frm.page.set_indicator(__('In Progress'), 'orange');
frm.trigger('update_primary_action');
frm.dashboard.show_progress(__("Import Progress"), percent, message);
frm.page.set_indicator(__("In Progress"), "orange");
frm.trigger("update_primary_action");
// hide progress when complete
if (data.current === data.total) {
@ -55,18 +51,18 @@ frappe.ui.form.on('Data Import', {
}
});
frm.set_query('reference_doctype', () => {
frm.set_query("reference_doctype", () => {
return {
filters: {
name: ['in', frappe.boot.user.can_import]
}
name: ["in", frappe.boot.user.can_import],
},
};
});
frm.get_field('import_file').df.options = {
frm.get_field("import_file").df.options = {
restrictions: {
allowed_file_types: ['.csv', '.xls', '.xlsx']
}
allowed_file_types: [".csv", ".xls", ".xlsx"],
},
};
frm.has_import_file = () => {
@ -76,33 +72,31 @@ frappe.ui.form.on('Data Import', {
refresh(frm) {
frm.page.hide_icon_group();
frm.trigger('update_indicators');
frm.trigger('import_file');
frm.trigger('show_import_log');
frm.trigger('show_import_warnings');
frm.trigger('toggle_submit_after_import');
frm.trigger("update_indicators");
frm.trigger("import_file");
frm.trigger("show_import_log");
frm.trigger("show_import_warnings");
frm.trigger("toggle_submit_after_import");
if (frm.doc.status != 'Pending')
frm.trigger('show_import_status');
if (frm.doc.status != "Pending") frm.trigger("show_import_status");
frm.trigger('show_report_error_button');
frm.trigger("show_report_error_button");
if (frm.doc.status === 'Partial Success') {
frm.add_custom_button(__('Export Errored Rows'), () =>
frm.trigger('export_errored_rows')
if (frm.doc.status === "Partial Success") {
frm.add_custom_button(__("Export Errored Rows"), () =>
frm.trigger("export_errored_rows")
);
}
if (frm.doc.status.includes('Success')) {
frm.add_custom_button(
__('Go to {0} List', [__(frm.doc.reference_doctype)]),
() => frappe.set_route('List', frm.doc.reference_doctype)
if (frm.doc.status.includes("Success")) {
frm.add_custom_button(__("Go to {0} List", [__(frm.doc.reference_doctype)]), () =>
frappe.set_route("List", frm.doc.reference_doctype)
);
}
},
onload_post_render(frm) {
frm.trigger('update_primary_action');
frm.trigger("update_primary_action");
},
update_primary_action(frm) {
@ -111,13 +105,12 @@ frappe.ui.form.on('Data Import', {
return;
}
frm.disable_save();
if (frm.doc.status !== 'Success') {
if (!frm.is_new() && (frm.has_import_file())) {
let label =
frm.doc.status === 'Pending' ? __('Start Import') : __('Retry');
if (frm.doc.status !== "Success") {
if (!frm.is_new() && frm.has_import_file()) {
let label = frm.doc.status === "Pending" ? __("Start Import") : __("Retry");
frm.page.set_primary_action(label, () => frm.events.start_import(frm));
} else {
frm.page.set_primary_action(__('Save'), () => frm.save());
frm.page.set_primary_action(__("Save"), () => frm.save());
}
}
},
@ -133,11 +126,11 @@ frappe.ui.form.on('Data Import', {
show_import_status(frm) {
frappe.call({
'method': 'frappe.core.doctype.data_import.data_import.get_import_status',
'args': {
'data_import_name': frm.doc.name
method: "frappe.core.doctype.data_import.data_import.get_import_status",
args: {
data_import_name: frm.doc.name,
},
'callback': function(r) {
callback: function (r) {
let successful_records = cint(r.message.success);
let failed_records = cint(r.message.failed);
let total_records = cint(r.message.total_records);
@ -147,52 +140,64 @@ frappe.ui.form.on('Data Import', {
let message;
if (failed_records === 0) {
let message_args = [successful_records];
if (frm.doc.import_type === 'Insert New Records') {
if (frm.doc.import_type === "Insert New Records") {
message =
successful_records > 1
? __('Successfully imported {0} records.', message_args)
: __('Successfully imported {0} record.', message_args);
? __("Successfully imported {0} records.", message_args)
: __("Successfully imported {0} record.", message_args);
} else {
message =
successful_records > 1
? __('Successfully updated {0} records.', message_args)
: __('Successfully updated {0} record.', message_args);
? __("Successfully updated {0} records.", message_args)
: __("Successfully updated {0} record.", message_args);
}
} else {
let message_args = [successful_records, total_records];
if (frm.doc.import_type === 'Insert New Records') {
if (frm.doc.import_type === "Insert New Records") {
message =
successful_records > 1
? __('Successfully imported {0} records out of {1}. Click on Export Errored Rows, fix the errors and import again.', message_args)
: __('Successfully imported {0} record out of {1}. Click on Export Errored Rows, fix the errors and import again.', message_args);
? __(
"Successfully imported {0} records out of {1}. Click on Export Errored Rows, fix the errors and import again.",
message_args
)
: __(
"Successfully imported {0} record out of {1}. Click on Export Errored Rows, fix the errors and import again.",
message_args
);
} else {
message =
successful_records > 1
? __('Successfully updated {0} records out of {1}. Click on Export Errored Rows, fix the errors and import again.', message_args)
: __('Successfully updated {0} record out of {1}. Click on Export Errored Rows, fix the errors and import again.', message_args);
? __(
"Successfully updated {0} records out of {1}. Click on Export Errored Rows, fix the errors and import again.",
message_args
)
: __(
"Successfully updated {0} record out of {1}. Click on Export Errored Rows, fix the errors and import again.",
message_args
);
}
}
frm.dashboard.set_headline(message);
}
},
});
},
show_report_error_button(frm) {
if (frm.doc.status === 'Error') {
if (frm.doc.status === "Error") {
frappe.db
.get_list('Error Log', {
.get_list("Error Log", {
filters: { method: frm.doc.name },
fields: ['method', 'error'],
order_by: 'creation desc',
limit: 1
fields: ["method", "error"],
order_by: "creation desc",
limit: 1,
})
.then(result => {
.then((result) => {
if (result.length > 0) {
frm.add_custom_button('Report Error', () => {
frm.add_custom_button("Report Error", () => {
let fake_xhr = {
responseText: JSON.stringify({
exc: result[0].error
})
exc: result[0].error,
}),
};
frappe.request.report_error(fake_xhr, {});
});
@ -202,21 +207,19 @@ frappe.ui.form.on('Data Import', {
},
start_import(frm) {
frm
.call({
method: 'form_start_import',
args: { data_import: frm.doc.name },
btn: frm.page.btn_primary
})
.then(r => {
if (r.message === true) {
frm.disable_save();
}
});
frm.call({
method: "form_start_import",
args: { data_import: frm.doc.name },
btn: frm.page.btn_primary,
}).then((r) => {
if (r.message === true) {
frm.disable_save();
}
});
},
download_template(frm) {
frappe.require('data_import_tools.bundle.js', () => {
frappe.require("data_import_tools.bundle.js", () => {
frm.data_exporter = new frappe.data_import.DataExporter(
frm.doc.reference_doctype,
frm.doc.import_type
@ -225,127 +228,123 @@ frappe.ui.form.on('Data Import', {
},
reference_doctype(frm) {
frm.trigger('toggle_submit_after_import');
frm.trigger("toggle_submit_after_import");
},
toggle_submit_after_import(frm) {
frm.toggle_display('submit_after_import', false);
frm.toggle_display("submit_after_import", false);
let doctype = frm.doc.reference_doctype;
if (doctype) {
frappe.model.with_doctype(doctype, () => {
let meta = frappe.get_meta(doctype);
frm.toggle_display('submit_after_import', meta.is_submittable);
frm.toggle_display("submit_after_import", meta.is_submittable);
});
}
},
google_sheets_url(frm) {
if (!frm.is_dirty()) {
frm.trigger('import_file');
frm.trigger("import_file");
} else {
frm.trigger('update_primary_action');
frm.trigger("update_primary_action");
}
},
refresh_google_sheet(frm) {
frm.trigger('import_file');
frm.trigger("import_file");
},
import_file(frm) {
frm.toggle_display('section_import_preview', frm.has_import_file());
frm.toggle_display("section_import_preview", frm.has_import_file());
if (!frm.has_import_file()) {
frm.get_field('import_preview').$wrapper.empty();
frm.get_field("import_preview").$wrapper.empty();
return;
} else {
frm.trigger('update_primary_action');
frm.trigger("update_primary_action");
}
// load import preview
frm.get_field('import_preview').$wrapper.empty();
frm.get_field("import_preview").$wrapper.empty();
$('<span class="text-muted">')
.html(__('Loading import file...'))
.appendTo(frm.get_field('import_preview').$wrapper);
.html(__("Loading import file..."))
.appendTo(frm.get_field("import_preview").$wrapper);
frm
.call({
method: 'get_preview_from_template',
args: {
data_import: frm.doc.name,
import_file: frm.doc.import_file,
google_sheets_url: frm.doc.google_sheets_url
frm.call({
method: "get_preview_from_template",
args: {
data_import: frm.doc.name,
import_file: frm.doc.import_file,
google_sheets_url: frm.doc.google_sheets_url,
},
error_handlers: {
TimestampMismatchError() {
// ignore this error
},
error_handlers: {
TimestampMismatchError() {
// ignore this error
}
}
})
.then(r => {
let preview_data = r.message;
frm.events.show_import_preview(frm, preview_data);
frm.events.show_import_warnings(frm, preview_data);
});
},
}).then((r) => {
let preview_data = r.message;
frm.events.show_import_preview(frm, preview_data);
frm.events.show_import_warnings(frm, preview_data);
});
},
show_import_preview(frm, preview_data) {
let import_log = preview_data.import_log;
if (
frm.import_preview &&
frm.import_preview.doctype === frm.doc.reference_doctype
) {
if (frm.import_preview && frm.import_preview.doctype === frm.doc.reference_doctype) {
frm.import_preview.preview_data = preview_data;
frm.import_preview.import_log = import_log;
frm.import_preview.refresh();
return;
}
frappe.require('data_import_tools.bundle.js', () => {
frappe.require("data_import_tools.bundle.js", () => {
frm.import_preview = new frappe.data_import.ImportPreview({
wrapper: frm.get_field('import_preview').$wrapper,
wrapper: frm.get_field("import_preview").$wrapper,
doctype: frm.doc.reference_doctype,
preview_data,
import_log,
frm,
events: {
remap_column(changed_map) {
let template_options = JSON.parse(frm.doc.template_options || '{}');
template_options.column_to_field_map = template_options.column_to_field_map || {};
let template_options = JSON.parse(frm.doc.template_options || "{}");
template_options.column_to_field_map =
template_options.column_to_field_map || {};
Object.assign(template_options.column_to_field_map, changed_map);
frm.set_value('template_options', JSON.stringify(template_options));
frm.save().then(() => frm.trigger('import_file'));
}
}
frm.set_value("template_options", JSON.stringify(template_options));
frm.save().then(() => frm.trigger("import_file"));
},
},
});
});
},
export_errored_rows(frm) {
open_url_post(
'/api/method/frappe.core.doctype.data_import.data_import.download_errored_template',
"/api/method/frappe.core.doctype.data_import.data_import.download_errored_template",
{
data_import_name: frm.doc.name
data_import_name: frm.doc.name,
}
);
},
export_import_log(frm) {
open_url_post(
'/api/method/frappe.core.doctype.data_import.data_import.download_import_log',
"/api/method/frappe.core.doctype.data_import.data_import.download_import_log",
{
data_import_name: frm.doc.name
data_import_name: frm.doc.name,
}
);
},
show_import_warnings(frm, preview_data) {
let columns = preview_data.columns;
let warnings = JSON.parse(frm.doc.template_warnings || '[]');
let warnings = JSON.parse(frm.doc.template_warnings || "[]");
warnings = warnings.concat(preview_data.warnings || []);
frm.toggle_display('import_warnings_section', warnings.length > 0);
frm.toggle_display("import_warnings_section", warnings.length > 0);
if (warnings.length === 0) {
frm.get_field('import_warnings').$wrapper.html('');
frm.get_field("import_warnings").$wrapper.html("");
return;
}
@ -361,36 +360,38 @@ frappe.ui.form.on('Data Import', {
}
}
let html = '';
let html = "";
html += Object.keys(warnings_by_row)
.map(row_number => {
.map((row_number) => {
let message = warnings_by_row[row_number]
.map(w => {
.map((w) => {
if (w.field) {
let label =
w.field.label +
(w.field.parent !== frm.doc.reference_doctype
? ` (${w.field.parent})`
: '');
: "");
return `<li>${label}: ${w.message}</li>`;
}
return `<li>${w.message}</li>`;
})
.join('');
.join("");
return `
<div class="warning" data-row="${row_number}">
<h5 class="text-uppercase">${__('Row {0}', [row_number])}</h5>
<h5 class="text-uppercase">${__("Row {0}", [row_number])}</h5>
<div class="body"><ul>${message}</ul></div>
</div>
`;
})
.join('');
.join("");
html += other_warnings
.map(warning => {
let header = '';
.map((warning) => {
let header = "";
if (warning.col) {
let column_number = `<span class="text-uppercase">${__('Column {0}', [warning.col])}</span>`;
let column_number = `<span class="text-uppercase">${__("Column {0}", [
warning.col,
])}</span>`;
let column_header = columns[warning.col].header_title;
header = `${column_number} (${column_header})`;
}
@ -401,8 +402,8 @@ frappe.ui.form.on('Data Import', {
</div>
`;
})
.join('');
frm.get_field('import_warnings').$wrapper.html(`
.join("");
frm.get_field("import_warnings").$wrapper.html(`
<div class="row">
<div class="col-sm-10 warnings">${html}</div>
</div>
@ -410,62 +411,62 @@ frappe.ui.form.on('Data Import', {
},
show_failed_logs(frm) {
frm.trigger('show_import_log');
frm.trigger("show_import_log");
},
render_import_log(frm) {
frappe.call({
'method': 'frappe.client.get_list',
'args': {
'doctype': 'Data Import Log',
'filters': {
'data_import': frm.doc.name
method: "frappe.client.get_list",
args: {
doctype: "Data Import Log",
filters: {
data_import: frm.doc.name,
},
'fields': ['success', 'docname', 'messages', 'exception', 'row_indexes'],
'limit_page_length': 5000,
'order_by': 'log_index'
fields: ["success", "docname", "messages", "exception", "row_indexes"],
limit_page_length: 5000,
order_by: "log_index",
},
callback: function(r) {
callback: function (r) {
let logs = r.message;
if (logs.length === 0) return;
frm.toggle_display('import_log_section', true);
frm.toggle_display("import_log_section", true);
let rows = logs
.map(log => {
let html = '';
.map((log) => {
let html = "";
if (log.success) {
if (frm.doc.import_type === 'Insert New Records') {
html = __('Successfully imported {0}', [
if (frm.doc.import_type === "Insert New Records") {
html = __("Successfully imported {0}", [
`<span class="underline">${frappe.utils.get_form_link(
frm.doc.reference_doctype,
log.docname,
true
)}<span>`
)}<span>`,
]);
} else {
html = __('Successfully updated {0}', [
html = __("Successfully updated {0}", [
`<span class="underline">${frappe.utils.get_form_link(
frm.doc.reference_doctype,
log.docname,
true
)}<span>`
)}<span>`,
]);
}
} else {
let messages = (JSON.parse(log.messages || '[]'))
let messages = JSON.parse(log.messages || "[]")
.map(JSON.parse)
.map(m => {
let title = m.title ? `<strong>${m.title}</strong>` : '';
let message = m.message ? `<div>${m.message}</div>` : '';
.map((m) => {
let title = m.title ? `<strong>${m.title}</strong>` : "";
let message = m.message ? `<div>${m.message}</div>` : "";
return title + message;
})
.join('');
.join("");
let id = frappe.dom.get_unique_id();
html = `${messages}
<button class="btn btn-default btn-xs" type="button" data-toggle="collapse" data-target="#${id}" aria-expanded="false" aria-controls="${id}" style="margin-top: 15px;">
${__('Show Traceback')}
${__("Show Traceback")}
</button>
<div class="collapse" id="${id}" style="margin-top: 15px;">
<div class="well">
@ -473,15 +474,15 @@ frappe.ui.form.on('Data Import', {
</div>
</div>`;
}
let indicator_color = log.success ? 'green' : 'red';
let title = log.success ? __('Success') : __('Failure');
let indicator_color = log.success ? "green" : "red";
let title = log.success ? __("Success") : __("Failure");
if (frm.doc.show_failed_logs && log.success) {
return '';
return "";
}
return `<tr>
<td>${JSON.parse(log.row_indexes).join(', ')}</td>
<td>${JSON.parse(log.row_indexes).join(", ")}</td>
<td>
<div class="indicator ${indicator_color}">${title}</div>
</td>
@ -490,54 +491,54 @@ frappe.ui.form.on('Data Import', {
</td>
</tr>`;
})
.join('');
.join("");
if (!rows && frm.doc.show_failed_logs) {
rows = `<tr><td class="text-center text-muted" colspan=3>
${__('No failed logs')}
${__("No failed logs")}
</td></tr>`;
}
frm.get_field('import_log_preview').$wrapper.html(`
frm.get_field("import_log_preview").$wrapper.html(`
<table class="table table-bordered">
<tr class="text-muted">
<th width="10%">${__('Row Number')}</th>
<th width="10%">${__('Status')}</th>
<th width="80%">${__('Message')}</th>
<th width="10%">${__("Row Number")}</th>
<th width="10%">${__("Status")}</th>
<th width="80%">${__("Message")}</th>
</tr>
${rows}
</table>
`);
}
},
});
},
show_import_log(frm) {
frm.toggle_display('import_log_section', false);
frm.toggle_display("import_log_section", false);
if (frm.import_in_progress) {
return;
}
frappe.call({
'method': 'frappe.client.get_count',
'args': {
'doctype': 'Data Import Log',
'filters': {
'data_import': frm.doc.name
}
method: "frappe.client.get_count",
args: {
doctype: "Data Import Log",
filters: {
data_import: frm.doc.name,
},
},
'callback': function(r) {
callback: function (r) {
let count = r.message;
if (count < 5000) {
frm.trigger('render_import_log');
frm.trigger("render_import_log");
} else {
frm.toggle_display('import_log_section', false);
frm.add_custom_button(__('Export Import Log'), () =>
frm.trigger('export_import_log')
frm.toggle_display("import_log_section", false);
frm.add_custom_button(__("Export Import Log"), () =>
frm.trigger("export_import_log")
);
}
}
},
});
},
});

View File

@ -1,46 +1,44 @@
let imports_in_progress = [];
frappe.listview_settings['Data Import'] = {
frappe.listview_settings["Data Import"] = {
onload(listview) {
frappe.realtime.on('data_import_progress', data => {
frappe.realtime.on("data_import_progress", (data) => {
if (!imports_in_progress.includes(data.data_import)) {
imports_in_progress.push(data.data_import);
}
});
frappe.realtime.on('data_import_refresh', data => {
imports_in_progress = imports_in_progress.filter(
d => d !== data.data_import
);
frappe.realtime.on("data_import_refresh", (data) => {
imports_in_progress = imports_in_progress.filter((d) => d !== data.data_import);
listview.refresh();
});
},
get_indicator: function(doc) {
get_indicator: function (doc) {
var colors = {
'Pending': 'orange',
'Not Started': 'orange',
'Partial Success': 'orange',
'Success': 'green',
'In Progress': 'orange',
'Error': 'red'
Pending: "orange",
"Not Started": "orange",
"Partial Success": "orange",
Success: "green",
"In Progress": "orange",
Error: "red",
};
let status = doc.status;
if (imports_in_progress.includes(doc.name)) {
status = 'In Progress';
status = "In Progress";
}
if (status == 'Pending') {
status = 'Not Started';
if (status == "Pending") {
status = "Not Started";
}
return [__(status), colors[status], 'status,=,' + doc.status];
return [__(status), colors[status], "status,=," + doc.status];
},
formatters: {
import_type(value) {
return {
'Insert New Records': __('Insert'),
'Update Existing Records': __('Update')
"Insert New Records": __("Insert"),
"Update Existing Records": __("Update"),
}[value];
}
},
},
hide_name_column: true
hide_name_column: true,
};

Some files were not shown because too many files have changed in this diff Show More