chore: releaseversion-14
@@ -12,3 +12,4 @@ charset = utf-8 | |||
[{*.py,*.js,*.vue,*.css,*.scss,*.html}] | |||
indent_style = tab | |||
indent_size = 4 | |||
max_line_length = 99 |
@@ -25,3 +25,6 @@ c0c5b2ebdddbe8898ce2d5e5365f4931ff73b6bf | |||
# update python code to use 3.10 supported features | |||
81b37cb7d2160866afa2496873656afe53f0c145 | |||
# format JS files with pretter | |||
5d6b24f0b134fd897644086499745cd35428bc11 |
@@ -32,6 +32,23 @@ repos: | |||
- id: black | |||
additional_dependencies: ['click==8.0.4'] | |||
- repo: https://github.com/pre-commit/mirrors-prettier | |||
rev: v2.7.1 | |||
hooks: | |||
- id: prettier | |||
types_or: [javascript] | |||
# Ignore any files that might contain jinja / bundles | |||
exclude: | | |||
(?x)^( | |||
frappe/public/dist/.*| | |||
.*node_modules.*| | |||
.*boilerplate.*| | |||
frappe/www/website_script.js| | |||
frappe/templates/includes/.*| | |||
frappe/public/js/lib/.* | |||
)$ | |||
- repo: https://github.com/timothycrosley/isort | |||
rev: 5.9.1 | |||
hooks: | |||
@@ -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", | |||
], | |||
], | |||
}, | |||
@@ -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, | |||
}; |
@@ -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, | |||
}; |
@@ -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, | |||
}; |
@@ -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, | |||
}; |
@@ -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, | |||
}; |
@@ -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, | |||
}; |
@@ -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, | |||
}; |
@@ -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, | |||
}; |
@@ -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, | |||
}; |
@@ -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); | |||
}); | |||
}); | |||
}); | |||
@@ -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"); | |||
}); | |||
}); |
@@ -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"); | |||
}); | |||
}); | |||
}); |
@@ -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(); | |||
}); | |||
}); | |||
}); |
@@ -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(""); | |||
}); | |||
}); | |||
}); |
@@ -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"); | |||
}); | |||
}); | |||
}); |
@@ -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"); | |||
}); | |||
}); |
@@ -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() | |||
); | |||
}); | |||
}); | |||
}); | |||
}); |
@@ -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"); | |||
}); | |||
}); | |||
}); | |||
}); |
@@ -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"); | |||
}); | |||
}); | |||
}); |
@@ -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, | |||
}, | |||
{ | |||
label: "Document ID", | |||
fieldname: "doc_id", | |||
fieldtype: "Dynamic Link", | |||
get_options: () => { | |||
return "User"; | |||
}, | |||
in_list_view: 1, | |||
}, | |||
"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" | |||
); | |||
}); | |||
}); |
@@ -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", | |||
}, | |||
], | |||
}, | |||
]; | |||
} | |||
}); |
@@ -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"); | |||
}); | |||
}); | |||
}); |
@@ -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'); | |||
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.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'); | |||
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: "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.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'); | |||
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'); | |||
it("should route to form on arrow click", () => { | |||
get_dialog_with_link().as("dialog"); | |||
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.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.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', () => { | |||
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); | |||
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: "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.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.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"); | |||
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.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.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.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); | |||
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", | |||
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.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'); | |||
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'); | |||
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"); | |||
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); | |||
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", | |||
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.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'); | |||
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'); | |||
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"); | |||
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"); | |||
}); | |||
}); | |||
}); |
@@ -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", | |||
@@ -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(); | |||
@@ -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); | |||
}); | |||
}); |
@@ -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(); | |||
}); | |||
}); | |||
@@ -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( | |||
@@ -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"); | |||
@@ -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(); | |||
}); | |||
}); | |||
}); |
@@ -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"); | |||
}); | |||
}); |
@@ -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"); | |||
}); | |||
}); | |||
}); | |||
}); |
@@ -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); | |||
}); | |||
}); | |||
}); | |||
@@ -16,4 +16,4 @@ | |||
// cy.get('.indicator-pill').should('contain', 'Open').should('have.class', 'red'); | |||
// }); | |||
// }); | |||
// }); | |||
// }); |
@@ -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"); | |||
}); | |||
}); |
@@ -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); | |||
}); |
@@ -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"); | |||
}); | |||
}); |
@@ -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(); | |||
}); | |||
}); | |||
}); |
@@ -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"); | |||
}); | |||
}); |
@@ -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); | |||
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'); | |||
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"); | |||
}); | |||
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('#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('.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.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)'; | |||
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('@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 => { | |||
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.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("@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"); | |||
}); | |||
}); |
@@ -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"); | |||
}); | |||
}); | |||
}); |
@@ -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"); | |||
}); | |||
}); |
@@ -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); | |||
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(); | |||
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="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="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(); | |||
}); | |||
}); | |||
}); | |||
@@ -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"); | |||
}); | |||
}); | |||
}); |
@@ -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); | |||
}); | |||
}); |
@@ -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); | |||
// }); | |||
}); | |||
}); |
@@ -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); | |||
}); | |||
}); | |||
}); |
@@ -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'); | |||
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('.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('.frappe-control .label-area').contains('Show Labels').click(); | |||
cy.click_modal_primary_button('Save'); | |||
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('.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('@save-kanban'); | |||
cy.get('@open-cards').find('.kanban-card .kanban-card-doc').first().should('not.contain', 'ID:'); | |||
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.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(".modal-footer .btn-primary").last().click(); | |||
cy.get(".frappe-control .label-area").contains("Show Labels").click(); | |||
cy.click_modal_primary_button("Save"); | |||
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(".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("@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'); | |||
// }); | |||
}); | |||
}); |
@@ -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"); | |||
}); | |||
}); |
@@ -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"); | |||
}); | |||
}); | |||
}); |
@@ -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(); | |||
}); | |||
}); |
@@ -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")); | |||
}); | |||
}); |
@@ -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"); | |||
} | |||
}); | |||
}); | |||
}); | |||
}); |
@@ -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"); | |||
}); | |||
}); |
@@ -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(); | |||
}); | |||
}); | |||
}); |
@@ -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'); | |||
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('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 }); | |||
}); | |||
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(".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 }); | |||
}); | |||
}); | |||
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"); | |||
}); | |||
}); | |||
}); |
@@ -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"); | |||
}); | |||
}); |
@@ -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); | |||
}); | |||
}); | |||
@@ -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"); | |||
}); | |||
}); |
@@ -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"); | |||
}); | |||
}); | |||
}); |
@@ -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); | |||
}); |
@@ -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.go_to_list('ToDo'); | |||
cy.clear_filters() | |||
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.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"); | |||
}); | |||
}); |
@@ -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(); | |||
}); | |||
}); |
@@ -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"); | |||
}); | |||
}); | |||
}); | |||
}); |
@@ -1,256 +1,264 @@ | |||
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", () => { | |||
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/new"); | |||
cy.url().should('include', '/note/Note%201'); | |||
cy.request("/api/method/logout"); | |||
cy.visit("/note"); | |||
cy.visit('/note'); | |||
cy.url().should('include', '/note/Note%201'); | |||
}); | |||
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-table tbody tr[id="Note 1"] .list-col-checkbox input').click(); | |||
cy.get('.web-list-table tbody tr[id="Note 2"] .list-col-checkbox input').click(); | |||
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"); | |||
}); | |||
}); | |||
}); |
@@ -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"); | |||
}); | |||
}); | |||
}); |
@@ -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_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").realHover().find(".widget-control .filter-list").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"); | |||
}); | |||
}); | |||
}); |
@@ -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; | |||
}; | |||
}; |
@@ -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(); | |||
); | |||
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); | |||
} | |||
return cy.get(selector); | |||
}); | |||
); | |||
Cypress.Commands.add('awesomebar', text => { | |||
cy.get('#navbar-search').type(`${text}{downarrow}{enter}`, {delay: 700}); | |||
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(); | |||
}); |
@@ -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", | |||
}); |
@@ -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()}`); | |||
}); | |||
}); | |||
}); | |||
} |
@@ -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) => { | |||
@@ -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) { | |||
@@ -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, | |||
}; | |||
}); | |||
} | |||
}, | |||
}; |
@@ -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, | |||
}; | |||
} | |||
}, | |||
}; |
@@ -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, | |||
}; |
@@ -912,15 +912,26 @@ def only_has_select_perm(doctype, user=None, ignore_permissions=False): | |||
def has_permission( | |||
doctype=None, ptype="read", doc=None, user=None, verbose=False, throw=False, parent_doctype=None | |||
doctype=None, | |||
ptype="read", | |||
doc=None, | |||
user=None, | |||
verbose=False, | |||
throw=False, | |||
*, | |||
parent_doctype=None, | |||
): | |||
"""Raises `frappe.PermissionError` if not permitted. | |||
""" | |||
Returns True if the user has permission `ptype` for given `doctype` or `doc` | |||
Raises `frappe.PermissionError` if user isn't permitted and `throw` is truthy | |||
:param doctype: DocType for which permission is to be check. | |||
:param ptype: Permission type (`read`, `write`, `create`, `submit`, `cancel`, `amend`). Default: `read`. | |||
:param doc: [optional] Checks User permissions for given doc. | |||
:param user: [optional] Check for given user. Default: current user. | |||
:param parent_doctype: Required when checking permission for a child DocType (unless doc is specified).""" | |||
:param verbose: DEPRECATED, will be removed in a future release. | |||
:param parent_doctype: Required when checking permission for a child DocType (unless doc is specified). | |||
""" | |||
import frappe.permissions | |||
if not doctype and doc: | |||
@@ -930,7 +941,6 @@ def has_permission( | |||
doctype, | |||
ptype, | |||
doc=doc, | |||
verbose=verbose, | |||
user=user, | |||
raise_exception=throw, | |||
parent_doctype=parent_doctype, | |||
@@ -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) | |||
); | |||
} | |||
}, | |||
}); |
@@ -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(); | |||
}); | |||
@@ -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]; | |||
} | |||
}, | |||
}; |
@@ -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) { | |||
// } | |||
}); |
@@ -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", []); | |||
} | |||
}, | |||
}); |
@@ -19,7 +19,7 @@ from frappe.social.doctype.energy_point_log.energy_point_log import get_energy_p | |||
from frappe.social.doctype.energy_point_settings.energy_point_settings import ( | |||
is_energy_point_enabled, | |||
) | |||
from frappe.translate import get_lang_dict | |||
from frappe.translate import get_lang_dict, get_messages_for_boot | |||
from frappe.utils import add_user_info, cstr, get_time_zone | |||
from frappe.utils.change_log import get_versions | |||
from frappe.website.doctype.web_page_view.web_page_view import is_tracking_enabled | |||
@@ -248,18 +248,8 @@ def get_user_pages_or_reports(parent, cache=False): | |||
def load_translations(bootinfo): | |||
messages = frappe.get_lang_dict("boot") | |||
bootinfo["lang"] = frappe.lang | |||
# load translated report names | |||
for name in bootinfo.user.all_reports: | |||
messages[name] = frappe._(name) | |||
# only untranslated | |||
messages = {k: v for k, v in messages.items() if k != v} | |||
bootinfo["__messages"] = messages | |||
bootinfo["__messages"] = get_messages_for_boot() | |||
def get_user_info(): | |||
@@ -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); | |||
} | |||
} | |||
} | |||
} | |||
}, | |||
]); | |||
} | |||
}, | |||
}); |
@@ -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); | |||
}, | |||
}); | |||
} | |||
} | |||
}, | |||
}); |
@@ -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]); | |||
} | |||
); | |||
}); | |||
} | |||
} | |||
}) | |||
}, | |||
}); |
@@ -1,3 +1,3 @@ | |||
frappe.listview_settings['Contact'] = { | |||
frappe.listview_settings["Contact"] = { | |||
add_fields: ["image"], | |||
}; | |||
}; |
@@ -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 () {}, | |||
}); |
@@ -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 () {}, | |||
}); |
@@ -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; | |||
} | |||
} | |||
] | |||
} | |||
}, | |||
}, | |||
], | |||
}; |
@@ -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); | |||
} | |||
} | |||
}, | |||
}); |
@@ -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 () {}, | |||
}); |
@@ -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); | |||
}) | |||
}); | |||
}, | |||
}; |
@@ -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) { | |||
// } | |||
}); |
@@ -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(__("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(__("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")); | |||
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( | |||
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") | |||
); | |||
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")); | |||
}, | |||
}); | |||
}, | |||
}); |
@@ -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(); | |||
} | |||
}, | |||
}; |