Ver código fonte

test(UI): non-admin user for UI tests and misc fixes (backport #17995) (#18079)

* test(UI): use non-admin user for tests

(cherry picked from commit f07bc3b369)

# Conflicts:
#	.github/workflows/ui-tests.yml

* test: fix tests using admin account

(cherry picked from commit a6b341bd59)

# Conflicts:
#	cypress/integration/dashboard_links.js

* test: add test role to user

(cherry picked from commit 0896873c8a)

* 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>
version-14
mergify[bot] 2 anos atrás
committed by GitHub
pai
commit
38d15d38fa
Nenhuma chave conhecida encontrada para esta assinatura no banco de dados ID da chave GPG: 4AEE18F83AFDEB23
12 arquivos alterados com 84 adições e 39 exclusões
  1. +4
    -1
      .github/workflows/ui-tests.yml
  2. +1
    -0
      cypress.config.js
  3. +5
    -5
      cypress/integration/control_link.js
  4. +6
    -9
      cypress/integration/dashboard_links.js
  5. +2
    -2
      cypress/integration/login.js
  6. +1
    -6
      cypress/integration/sidebar.js
  7. +3
    -1
      cypress/integration/table_multiselect.js
  8. +2
    -2
      cypress/integration/timeline.js
  9. +11
    -5
      cypress/integration/web_form.js
  10. +1
    -1
      cypress/support/commands.js
  11. +35
    -0
      frappe/tests/ui_test_helpers.py
  12. +13
    -7
      frappe/workflow/doctype/workflow/test_workflow.py

+ 4
- 1
.github/workflows/ui-tests.yml Ver arquivo

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


+ 1
- 0
cypress.config.js Ver arquivo

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


+ 5
- 5
cypress/integration/control_link.js Ver arquivo

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


+ 6
- 9
cypress/integration/dashboard_links.js Ver arquivo

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


+ 2
- 2
cypress/integration/login.js Ver arquivo

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



+ 1
- 6
cypress/integration/sidebar.js Ver arquivo

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



+ 3
- 1
cypress/integration/table_multiselect.js Ver arquivo

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


+ 2
- 2
cypress/integration/timeline.js Ver arquivo

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


+ 11
- 5
cypress/integration/web_form.js Ver arquivo

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



+ 1
- 1
cypress/support/commands.js Ver arquivo

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


+ 35
- 0
frappe/tests/ui_test_helpers.py Ver arquivo

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

+ 13
- 7
frappe/workflow/doctype/workflow/test_workflow.py Ver arquivo

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


Carregando…
Cancelar
Salvar