chore: run cypress migrator
fix: specPattern should be an array
test: correct intercept URL
This is breaking change in cypress 7.0
test: make list view test rerunnable
test: redo undo tests and add compare doc
test: scroll to action button
chore: drop flaky tests
fix: remove scroll behaviour
fix: clear filters before running count test
test: input delay causes flake
(cherry picked from commit e397b27d29
)
version-14
@@ -0,0 +1,23 @@ | |||||
const { defineConfig } = require("cypress"); | |||||
module.exports = defineConfig({ | |||||
projectId: "92odwv", | |||||
adminPassword: "admin", | |||||
defaultCommandTimeout: 20000, | |||||
pageLoadTimeout: 15000, | |||||
video: true, | |||||
videoUploadOnPasses: false, | |||||
retries: { | |||||
runMode: 2, | |||||
openMode: 2, | |||||
}, | |||||
e2e: { | |||||
// We've imported your old cypress plugins here. | |||||
// You may want to clean this up later by importing these. | |||||
setupNodeEvents(on, config) { | |||||
return require("./cypress/plugins/index.js")(on, config); | |||||
}, | |||||
baseUrl: "http://test_site_ui:8000", | |||||
specPattern: ["./cypress/integration/*.js", "**/ui_test_*.js"], | |||||
}, | |||||
}); |
@@ -1,15 +0,0 @@ | |||||
{ | |||||
"baseUrl": "http://test_site_ui:8000", | |||||
"projectId": "92odwv", | |||||
"adminPassword": "admin", | |||||
"defaultCommandTimeout": 20000, | |||||
"pageLoadTimeout": 15000, | |||||
"video": true, | |||||
"videoUploadOnPasses": false, | |||||
"retries": { | |||||
"runMode": 2, | |||||
"openMode": 2 | |||||
}, | |||||
"integrationFolder": ".", | |||||
"testFiles": ["cypress/integration/*.js", "**/ui_test_*.js"] | |||||
} |
@@ -29,6 +29,7 @@ context("Control Float", () => { | |||||
}); | }); | ||||
x.values.forEach((d) => { | x.values.forEach((d) => { | ||||
cy.get_field("float_number", "Float").clear(); | cy.get_field("float_number", "Float").clear(); | ||||
cy.wait(200); | |||||
cy.fill_field("float_number", d.input, "Float").blur(); | 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); | ||||
@@ -132,9 +132,6 @@ context("Form", () => { | |||||
jump_to_field("Username"); | jump_to_field("Username"); | ||||
type_value("admin42"); | type_value("admin42"); | ||||
jump_to_field("Birth Date"); | |||||
type_value("12-31-01"); | |||||
jump_to_field("Send Welcome Email"); | jump_to_field("Send Welcome Email"); | ||||
cy.focused().uncheck(); | cy.focused().uncheck(); | ||||
@@ -155,16 +152,15 @@ context("Form", () => { | |||||
undo(); | undo(); | ||||
undo(); | undo(); | ||||
undo(); | undo(); | ||||
undo(); | |||||
redo(); | |||||
redo(); | redo(); | ||||
redo(); | 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.compare_document({ | |||||
username: "admin24", | |||||
email: "admin@example.com", | |||||
send_welcome_email: 0, | |||||
}); | |||||
}); | }); | ||||
}); | }); |
@@ -96,17 +96,4 @@ context("Kanban Board", () => { | |||||
.first() | .first() | ||||
.should("not.contain", "ID:"); | .should("not.contain", "ID:"); | ||||
}); | }); | ||||
// it('Drag todo', () => { | |||||
// cy.intercept({ | |||||
// method: 'POST', | |||||
// url: 'api/method/frappe.desk.doctype.kanban_board.kanban_board.update_order_for_single_card' | |||||
// }).as('drag-completed'); | |||||
// cy.get('.kanban-card-body') | |||||
// .contains('Test Kanban ToDo').first() | |||||
// .drag('[data-column-value="Closed"] .kanban-cards', { force: true }); | |||||
// cy.wait('@drag-completed'); | |||||
// }); | |||||
}); | }); |
@@ -10,10 +10,13 @@ context("List View", () => { | |||||
}); | }); | ||||
}); | }); | ||||
it("Keep checkbox checked after Refresh", () => { | |||||
it("Keep checkbox checked after Refresh", { scrollBehavior: false }, () => { | |||||
cy.go_to_list("ToDo"); | cy.go_to_list("ToDo"); | ||||
cy.clear_filters(); | cy.clear_filters(); | ||||
cy.get(".list-row-container .list-row-checkbox").click({ multiple: true, force: true }); | |||||
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.get(".actions-btn-group button").contains("Actions").should("be.visible"); | ||||
cy.intercept("/api/method/frappe.desk.reportview.get").as("list-refresh"); | cy.intercept("/api/method/frappe.desk.reportview.get").as("list-refresh"); | ||||
cy.wait(3000); // wait before you hit another refresh | cy.wait(3000); // wait before you hit another refresh | ||||
@@ -22,7 +25,7 @@ context("List View", () => { | |||||
cy.get(".list-row-container .list-row-checkbox:checked").should("be.visible"); | cy.get(".list-row-container .list-row-checkbox:checked").should("be.visible"); | ||||
}); | }); | ||||
it('enables "Actions" button', () => { | |||||
it('enables "Actions" button', { scrollBehavior: false }, () => { | |||||
const actions = [ | const actions = [ | ||||
"Approve", | "Approve", | ||||
"Reject", | "Reject", | ||||
@@ -5,12 +5,14 @@ context("List View Settings", () => { | |||||
}); | }); | ||||
it("Default settings", () => { | it("Default settings", () => { | ||||
cy.visit("/app/List/DocType/List"); | cy.visit("/app/List/DocType/List"); | ||||
cy.clear_filters(); | |||||
cy.get(".list-count").should("contain", "20 of"); | cy.get(".list-count").should("contain", "20 of"); | ||||
cy.get(".list-stats").should("contain", "Tags"); | 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.wait(300); | ||||
cy.visit("/app/List/DocType/List"); | cy.visit("/app/List/DocType/List"); | ||||
cy.clear_filters(); | |||||
cy.wait(300); | cy.wait(300); | ||||
cy.get(".list-count").should("contain", "20 of"); | cy.get(".list-count").should("contain", "20 of"); | ||||
cy.get(".menu-btn-group button").click(); | cy.get(".menu-btn-group button").click(); | ||||
@@ -1,93 +0,0 @@ | |||||
context("Timeline Email", () => { | |||||
before(() => { | |||||
cy.visit("/login"); | |||||
cy.login(); | |||||
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"); | |||||
cy.wait(500); | |||||
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"); | |||||
//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"); | |||||
//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(); | |||||
//Sending the email | |||||
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" | |||||
); | |||||
//To check if the attachment of email is shown in the timeline content | |||||
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(); | |||||
}); | |||||
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.wait(500); | |||||
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.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.wait(500); | |||||
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(); | |||||
//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(); | |||||
}); | |||||
}); |
@@ -68,7 +68,7 @@ context("Workspace Blocks", () => { | |||||
cy.intercept({ | cy.intercept({ | ||||
method: "GET", | method: "GET", | ||||
url: "api/method/frappe.desk.form.load.getdoctype", | |||||
url: "api/method/frappe.desk.form.load.getdoctype?**", | |||||
}).as("get_doctype"); | }).as("get_doctype"); | ||||
cy.visit("/app/tools"); | cy.visit("/app/tools"); | ||||
@@ -281,12 +281,12 @@ Cypress.Commands.add("get_open_dialog", () => { | |||||
}); | }); | ||||
Cypress.Commands.add("save", () => { | Cypress.Commands.add("save", () => { | ||||
cy.intercept("/api").as("api"); | |||||
cy.intercept("/api/method/frappe.desk.form.save.savedocs").as("save_call"); | |||||
cy.get(`button[data-label="Save"]:visible`).click({ scrollBehavior: false, force: true }); | cy.get(`button[data-label="Save"]:visible`).click({ scrollBehavior: false, force: true }); | ||||
cy.wait("@api"); | |||||
cy.wait("@save_call"); | |||||
}); | }); | ||||
Cypress.Commands.add("hide_dialog", () => { | Cypress.Commands.add("hide_dialog", () => { | ||||
cy.wait(300); | |||||
cy.wait(500); | |||||
cy.get_open_dialog().focus().find(".btn-modal-close").click(); | cy.get_open_dialog().focus().find(".btn-modal-close").click(); | ||||
cy.get(".modal:visible").should("not.exist"); | cy.get(".modal:visible").should("not.exist"); | ||||
}); | }); | ||||
@@ -459,3 +459,26 @@ Cypress.Commands.add("select_listview_row_checkbox", (row_no) => { | |||||
Cypress.Commands.add("click_form_section", (section_name) => { | Cypress.Commands.add("click_form_section", (section_name) => { | ||||
cy.get(".section-head").contains(section_name).click(); | cy.get(".section-head").contains(section_name).click(); | ||||
}); | }); | ||||
const compare_document = (expected, actual) => { | |||||
for (const prop in expected) { | |||||
if (expected[prop] instanceof Array) { | |||||
// recursively compare child documents. | |||||
expected[prop].forEach((item, idx) => { | |||||
compare_document(item, actual[prop][idx]); | |||||
}); | |||||
} else { | |||||
assert.equal(expected[prop], actual[prop], `${prop} should be equal.`); | |||||
} | |||||
} | |||||
}; | |||||
Cypress.Commands.add("compare_document", (expected_document) => { | |||||
cy.window() | |||||
.its("cur_frm") | |||||
.then((frm) => { | |||||
// Don't remove this, cypress can't magically wait for events it has no control over. | |||||
cy.wait(1000); | |||||
compare_document(expected_document, frm.doc); | |||||
}); | |||||
}); |
@@ -879,7 +879,7 @@ def run_ui_tests( | |||||
click.secho("Installing Cypress...", fg="yellow") | click.secho("Installing Cypress...", fg="yellow") | ||||
packages = " ".join( | packages = " ".join( | ||||
[ | [ | ||||
"cypress@^6", | |||||
"cypress@^10", | |||||
"cypress-file-upload@^5", | "cypress-file-upload@^5", | ||||
"@4tw/cypress-drag-drop@^2", | "@4tw/cypress-drag-drop@^2", | ||||
"cypress-real-events", | "cypress-real-events", | ||||
@@ -38,8 +38,7 @@ def create_if_not_exists(doc): | |||||
@frappe.whitelist() | @frappe.whitelist() | ||||
def create_todo_records(): | def create_todo_records(): | ||||
if frappe.get_all("ToDo", {"description": "this is first todo"}): | |||||
return | |||||
frappe.db.truncate("ToDo") | |||||
frappe.get_doc( | frappe.get_doc( | ||||
{"doctype": "ToDo", "date": add_to_date(now(), days=7), "description": "this is first todo"} | {"doctype": "ToDo", "date": add_to_date(now(), days=7), "description": "this is first todo"} | ||||