Browse Source

test: upgrade cypress from v6 to v10

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
Ankush Menat 2 years ago
committed by Ankush Menat
parent
commit
de203c3a72
13 changed files with 66 additions and 140 deletions
  1. +23
    -0
      cypress.config.js
  2. +0
    -15
      cypress.json
  3. +1
    -0
      cypress/integration/control_float.js
  4. +5
    -9
      cypress/integration/form.js
  5. +0
    -13
      cypress/integration/kanban.js
  6. +6
    -3
      cypress/integration/list_view.js
  7. +2
    -0
      cypress/integration/list_view_settings.js
  8. +0
    -93
      cypress/integration/timeline_email.js
  9. +1
    -1
      cypress/integration/workspace_blocks.js
  10. +26
    -3
      cypress/support/commands.js
  11. +0
    -0
      cypress/support/e2e.js
  12. +1
    -1
      frappe/commands/utils.py
  13. +1
    -2
      frappe/tests/ui_test_helpers.py

+ 23
- 0
cypress.config.js View File

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

+ 0
- 15
cypress.json View File

@@ -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"]
}

+ 1
- 0
cypress/integration/control_float.js View File

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




+ 5
- 9
cypress/integration/form.js View File

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

+ 0
- 13
cypress/integration/kanban.js View File

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

+ 6
- 3
cypress/integration/list_view.js View File

@@ -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",


+ 2
- 0
cypress/integration/list_view_settings.js View File

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


+ 0
- 93
cypress/integration/timeline_email.js View File

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

+ 1
- 1
cypress/integration/workspace_blocks.js View File

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


+ 26
- 3
cypress/support/commands.js View File

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

cypress/support/index.js → cypress/support/e2e.js View File


+ 1
- 1
frappe/commands/utils.py View File

@@ -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",


+ 1
- 2
frappe/tests/ui_test_helpers.py View File

@@ -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"}


Loading…
Cancel
Save