* test(UI): use non-admin user for tests (cherry picked from commitversion-14f07bc3b369
) # Conflicts: # .github/workflows/ui-tests.yml * test: fix tests using admin account (cherry picked from commita6b341bd59
) # Conflicts: # cypress/integration/dashboard_links.js * test: add test role to user (cherry picked from commit0896873c8a
) * chore: conflicts * test: fix broken test Not sure why there's test on doctype "created by". Makes no sense. Co-authored-by: Ankush Menat <ankush@frappe.io>
@@ -137,7 +137,10 @@ jobs: | |||
- name: Site Setup | |||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||
run: cd ~/frappe-bench/ && bench --site test_site execute frappe.utils.install.complete_setup_wizard | |||
run: | | |||
cd ~/frappe-bench/ | |||
bench --site test_site execute frappe.utils.install.complete_setup_wizard | |||
bench --site test_site execute frappe.tests.ui_test_helpers.create_test_user | |||
- name: UI Tests | |||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||
@@ -3,6 +3,7 @@ const { defineConfig } = require("cypress"); | |||
module.exports = defineConfig({ | |||
projectId: "92odwv", | |||
adminPassword: "admin", | |||
testUser: "frappe@example.com", | |||
defaultCommandTimeout: 20000, | |||
pageLoadTimeout: 15000, | |||
video: true, | |||
@@ -177,14 +177,14 @@ context("Control 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.get("@input").type(cy.config("testUser"), { delay: 100 }).blur(); | |||
cy.wait("@validate_link"); | |||
cy.get(".frappe-control[data-fieldname=assigned_by_full_name] .control-value").should( | |||
"contain", | |||
"Administrator" | |||
"Frappe" | |||
); | |||
cy.window().its("cur_frm.doc.assigned_by").should("eq", "Administrator"); | |||
cy.window().its("cur_frm.doc.assigned_by").should("eq", cy.config("testUser")); | |||
// invalid input | |||
cy.get("@input").clear().type("invalid input", { delay: 100 }).blur(); | |||
@@ -198,10 +198,10 @@ context("Control Link", () => { | |||
// set valid value again | |||
cy.get("@input").clear().focus(); | |||
cy.wait("@search_link"); | |||
cy.get("@input").type("Administrator", { delay: 100 }).blur(); | |||
cy.get("@input").type(cy.config("testUser"), { 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", cy.config("testUser")); | |||
// clear input | |||
cy.get("@input").clear().blur(); | |||
@@ -8,7 +8,7 @@ const child_table_doctype_name = child_table_doctype.name; | |||
context("Dashboard links", () => { | |||
before(() => { | |||
cy.visit("/login"); | |||
cy.login(); | |||
cy.login("Administrator"); | |||
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); | |||
@@ -27,8 +27,7 @@ context("Dashboard links", () => { | |||
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.config("testUser")}`); | |||
//To check if initially the dashboard contains only the "Contact" link and there is no counter | |||
cy.get('[data-doctype="Contact"]').should("contain", "Contact"); | |||
@@ -40,11 +39,10 @@ context("Dashboard links", () => { | |||
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.visit(`/app/user/${cy.config("testUser")}`); | |||
//To check if the counter for contact doc is "1" after adding the contact | |||
cy.get('[data-doctype="Contact"] > .count').should("contain", "1"); | |||
//To check if the counter for contact doc is "2" after adding additional contact | |||
cy.get('[data-doctype="Contact"] > .count').should("contain", "2"); | |||
cy.get('[data-doctype="Contact"]').contains("Contact").click(); | |||
//Deleting the newly created contact | |||
@@ -62,8 +60,7 @@ context("Dashboard links", () => { | |||
}); | |||
it("Report link in dashboard", () => { | |||
cy.visit("/app/user"); | |||
cy.visit("/app/user/Administrator"); | |||
cy.visit(`/app/user/${cy.config("testUser")}`); | |||
cy.get('[data-doctype="Contact"]').should("contain", "Contact"); | |||
cy.findByText("Connections"); | |||
cy.window() | |||
@@ -32,7 +32,7 @@ context("Login", () => { | |||
it("logs in using correct credentials", () => { | |||
cy.get("#login_email").type("Administrator"); | |||
cy.get("#login_password").type(Cypress.config("adminPassword")); | |||
cy.get("#login_password").type(Cypress.env("adminPassword")); | |||
cy.findByRole("button", { name: "Login" }).click(); | |||
cy.location("pathname").should("eq", "/app"); | |||
@@ -56,7 +56,7 @@ context("Login", () => { | |||
); | |||
cy.get("#login_email").type("Administrator"); | |||
cy.get("#login_password").type(Cypress.config("adminPassword")); | |||
cy.get("#login_password").type(Cypress.env("adminPassword")); | |||
cy.findByRole("button", { name: "Login" }).click(); | |||
@@ -38,11 +38,6 @@ context("Sidebar", () => { | |||
//To check if no filter is available in "Assigned To" dropdown | |||
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"); | |||
//Assigning a doctype to a user | |||
cy.visit("/app/doctype/ToDo"); | |||
cy.get(".form-assignments > .flex > .text-muted").click(); | |||
@@ -72,7 +67,7 @@ context("Sidebar", () => { | |||
cy.get(".condition").should("have.value", "like"); | |||
cy.get(".filter-field > .form-group > .input-with-feedback").should( | |||
"have.value", | |||
"%Administrator%" | |||
`%${cy.config("testUser")}%` | |||
); | |||
cy.click_filter_button(); | |||
@@ -13,7 +13,9 @@ context("Table MultiSelect", () => { | |||
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("@input").type("test@erpnext", { delay: 100 }); | |||
cy.wait(500); | |||
cy.get("@input").type("{enter}"); | |||
cy.get( | |||
'.frappe-control[data-fieldname="users"] .form-control .tb-selected-value .btn-link-to-form' | |||
).as("selected-value"); | |||
@@ -72,14 +72,14 @@ context("Timeline", () => { | |||
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(".timeline-content").should("contain", "Frappe 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", "Frappe cancelled this document"); | |||
//Deleting the document | |||
cy.visit("/app/custom-submittable-doctype"); | |||
@@ -1,6 +1,13 @@ | |||
context("Web Form", () => { | |||
before(() => { | |||
cy.login(); | |||
cy.login("Administrator"); | |||
cy.visit("/app/"); | |||
return cy | |||
.window() | |||
.its("frappe") | |||
.then((frappe) => { | |||
return frappe.xcall("frappe.tests.ui_test_helpers.clear_notes"); | |||
}); | |||
}); | |||
it("Create Web Form", () => { | |||
@@ -42,7 +49,7 @@ context("Web Form", () => { | |||
}); | |||
it("Login Required", () => { | |||
cy.login(); | |||
cy.login("Administrator"); | |||
cy.visit("/app/web-form/note"); | |||
cy.findByRole("tab", { name: "Settings" }).click(); | |||
@@ -51,7 +58,6 @@ context("Web Form", () => { | |||
cy.save(); | |||
cy.visit("/note"); | |||
cy.url().should("include", "/note/Note%201"); | |||
cy.call("logout"); | |||
@@ -62,7 +68,7 @@ context("Web Form", () => { | |||
}); | |||
it("Show List", () => { | |||
cy.login(); | |||
cy.login("Administrator"); | |||
cy.visit("/app/web-form/note"); | |||
cy.findByRole("tab", { name: "Settings" }).click(); | |||
@@ -156,7 +162,7 @@ context("Web Form", () => { | |||
}); | |||
it("Read Only", () => { | |||
cy.login(); | |||
cy.login("Administrator"); | |||
cy.visit("/note"); | |||
cy.url().should("include", "/note/list"); | |||
@@ -29,7 +29,7 @@ import "cypress-real-events/support"; | |||
Cypress.Commands.add("login", (email, password) => { | |||
if (!email) { | |||
email = "Administrator"; | |||
email = Cypress.config("testUser") || "Administrator"; | |||
} | |||
if (!password) { | |||
password = Cypress.env("adminPassword"); | |||
@@ -2,6 +2,8 @@ import frappe | |||
from frappe import _ | |||
from frappe.utils import add_to_date, now | |||
UI_TEST_USER = "frappe@example.com" | |||
@frappe.whitelist() | |||
def create_if_not_exists(doc): | |||
@@ -54,6 +56,15 @@ def create_todo_records(): | |||
).insert() | |||
@frappe.whitelist() | |||
def clear_notes(): | |||
if not frappe.local.dev_server: | |||
frappe.throw(_("Not allowed"), frappe.PermissionError) | |||
for note in frappe.get_all("Note", pluck="name"): | |||
frappe.delete_doc("Note", note, force=True) | |||
@frappe.whitelist() | |||
def create_communication_record(): | |||
doc = frappe.get_doc( | |||
@@ -396,3 +407,27 @@ def create_blog_post(): | |||
).insert(ignore_if_duplicate=True) | |||
return doc | |||
def create_test_user(): | |||
if frappe.db.exists("User", UI_TEST_USER): | |||
return | |||
user = frappe.new_doc("User") | |||
user.email = UI_TEST_USER | |||
user.first_name = "Frappe" | |||
user.new_password = frappe.local.conf.admin_password | |||
user.send_welcome_email = 0 | |||
user.time_zone = "Asia/Kolkata" | |||
user.flags.ignore_password_policy = True | |||
user.insert(ignore_if_duplicate=True) | |||
user.reload() | |||
blocked_roles = {"Administrator", "Guest", "All"} | |||
all_roles = set(frappe.get_all("Role", pluck="name")) | |||
for role in all_roles - blocked_roles: | |||
user.append("roles", {"role": role}) | |||
user.save() |
@@ -2,7 +2,6 @@ | |||
# License: MIT. See LICENSE | |||
import frappe | |||
from frappe.model.workflow import ( | |||
WorkflowPermissionError, | |||
WorkflowTransitionError, | |||
apply_workflow, | |||
get_common_transition_actions, | |||
@@ -191,11 +190,18 @@ class TestWorkflow(FrappeTestCase): | |||
def create_todo_workflow(): | |||
from frappe.tests.ui_test_helpers import UI_TEST_USER | |||
if frappe.db.exists("Workflow", "Test ToDo"): | |||
frappe.delete_doc("Workflow", "Test ToDo") | |||
if not frappe.db.exists("Role", "Test Approver"): | |||
frappe.get_doc(dict(doctype="Role", role_name="Test Approver")).insert(ignore_if_duplicate=True) | |||
TEST_ROLE = "Test Approver" | |||
if not frappe.db.exists("Role", TEST_ROLE): | |||
frappe.get_doc(dict(doctype="Role", role_name=TEST_ROLE)).insert(ignore_if_duplicate=True) | |||
if frappe.db.exists("User", UI_TEST_USER): | |||
frappe.get_doc("User", UI_TEST_USER).add_roles(TEST_ROLE) | |||
workflow = frappe.new_doc("Workflow") | |||
workflow.workflow_name = "Test ToDo" | |||
workflow.document_type = "ToDo" | |||
@@ -205,16 +211,16 @@ def create_todo_workflow(): | |||
workflow.append("states", dict(state="Pending", allow_edit="All")) | |||
workflow.append( | |||
"states", | |||
dict(state="Approved", allow_edit="Test Approver", update_field="status", update_value="Closed"), | |||
dict(state="Approved", allow_edit=TEST_ROLE, update_field="status", update_value="Closed"), | |||
) | |||
workflow.append("states", dict(state="Rejected", allow_edit="Test Approver")) | |||
workflow.append("states", dict(state="Rejected", allow_edit=TEST_ROLE)) | |||
workflow.append( | |||
"transitions", | |||
dict( | |||
state="Pending", | |||
action="Approve", | |||
next_state="Approved", | |||
allowed="Test Approver", | |||
allowed=TEST_ROLE, | |||
allow_self_approval=1, | |||
), | |||
) | |||
@@ -224,7 +230,7 @@ def create_todo_workflow(): | |||
state="Pending", | |||
action="Reject", | |||
next_state="Rejected", | |||
allowed="Test Approver", | |||
allowed=TEST_ROLE, | |||
allow_self_approval=1, | |||
), | |||
) | |||