Apply repository-wide ESLint auto-fix formatting pass
Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
@@ -3,32 +3,32 @@
|
||||
// Authors:
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../support/intercept';
|
||||
import { loginWithFixtures } from "../support/intercept";
|
||||
|
||||
describe('Account Management', () => {
|
||||
describe("Account Management", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
});
|
||||
|
||||
it('displays user list on account admin page', () => {
|
||||
cy.visit('/account-admin');
|
||||
cy.wait('@getUsers');
|
||||
it("displays user list on account admin page", () => {
|
||||
cy.visit("/account-admin");
|
||||
cy.wait("@getUsers");
|
||||
// Should display users from fixture
|
||||
cy.contains('Test Admin').should('exist');
|
||||
cy.contains('Alice Wang').should('exist');
|
||||
cy.contains('Bob Chen').should('exist');
|
||||
cy.contains("Test Admin").should("exist");
|
||||
cy.contains("Alice Wang").should("exist");
|
||||
cy.contains("Bob Chen").should("exist");
|
||||
});
|
||||
|
||||
it('shows active/inactive status badges', () => {
|
||||
cy.visit('/account-admin');
|
||||
cy.wait('@getUsers');
|
||||
it("shows active/inactive status badges", () => {
|
||||
cy.visit("/account-admin");
|
||||
cy.wait("@getUsers");
|
||||
// The user list should show status indicators
|
||||
cy.contains('testadmin').should('exist');
|
||||
cy.contains("testadmin").should("exist");
|
||||
});
|
||||
|
||||
it('navigates to my-account page', () => {
|
||||
cy.visit('/my-account');
|
||||
cy.wait('@getMyAccount');
|
||||
cy.url().should('include', '/my-account');
|
||||
it("navigates to my-account page", () => {
|
||||
cy.visit("/my-account");
|
||||
cy.wait("@getMyAccount");
|
||||
cy.url().should("include", "/my-account");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,55 +4,61 @@
|
||||
// cindy.chang@dsp.im (Cindy Chang), 2024/07/03
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../../support/intercept';
|
||||
import { loginWithFixtures } from "../../support/intercept";
|
||||
|
||||
const MSG_ACCOUNT_NOT_UNIQUE = 'Account has already been registered.';
|
||||
const MSG_ACCOUNT_NOT_UNIQUE = "Account has already been registered.";
|
||||
|
||||
describe('Account duplication check.', () => {
|
||||
describe("Account duplication check.", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/account-admin');
|
||||
cy.wait('@getUsers');
|
||||
cy.visit("/account-admin");
|
||||
cy.wait("@getUsers");
|
||||
});
|
||||
|
||||
it('When an account already exists, show error message on confirm.', () => {
|
||||
const testAccountName = '000000';
|
||||
it("When an account already exists, show error message on confirm.", () => {
|
||||
const testAccountName = "000000";
|
||||
|
||||
// First creation: account doesn't exist yet
|
||||
cy.intercept('GET', '/api/users/000000', {
|
||||
cy.intercept("GET", "/api/users/000000", {
|
||||
statusCode: 404,
|
||||
body: { detail: 'Not found' },
|
||||
}).as('checkNewUser');
|
||||
body: { detail: "Not found" },
|
||||
}).as("checkNewUser");
|
||||
|
||||
cy.contains('button', 'Create New').should('be.visible').click();
|
||||
cy.get('#input_account_field').type(testAccountName);
|
||||
cy.get('#input_name_field').type(testAccountName);
|
||||
cy.get('#input_first_pwd').type(testAccountName);
|
||||
cy.get('.checkbox-and-text').first().find('div').first().click();
|
||||
cy.contains("button", "Create New").should("be.visible").click();
|
||||
cy.get("#input_account_field").type(testAccountName);
|
||||
cy.get("#input_name_field").type(testAccountName);
|
||||
cy.get("#input_first_pwd").type(testAccountName);
|
||||
cy.get(".checkbox-and-text").first().find("div").first().click();
|
||||
|
||||
cy.contains('button', 'Confirm')
|
||||
.should('be.visible')
|
||||
.and('be.enabled')
|
||||
cy.contains("button", "Confirm")
|
||||
.should("be.visible")
|
||||
.and("be.enabled")
|
||||
.click();
|
||||
cy.wait('@postUser');
|
||||
cy.contains('Account added').should('be.visible');
|
||||
cy.wait("@postUser");
|
||||
cy.contains("Account added").should("be.visible");
|
||||
|
||||
// Second creation: now account exists — override to return 200
|
||||
cy.intercept('GET', '/api/users/000000', {
|
||||
cy.intercept("GET", "/api/users/000000", {
|
||||
statusCode: 200,
|
||||
body: { username: '000000', name: '000000', is_admin: false, is_active: true, roles: [] },
|
||||
}).as('checkExistingUser');
|
||||
body: {
|
||||
username: "000000",
|
||||
name: "000000",
|
||||
is_admin: false,
|
||||
is_active: true,
|
||||
roles: [],
|
||||
},
|
||||
}).as("checkExistingUser");
|
||||
|
||||
cy.contains('button', 'Create New').should('be.visible').click();
|
||||
cy.get('#input_account_field').type(testAccountName);
|
||||
cy.get('#input_name_field').type(testAccountName);
|
||||
cy.get('#input_first_pwd').type(testAccountName);
|
||||
cy.get('.checkbox-and-text').first().find('div').first().click();
|
||||
cy.contains("button", "Create New").should("be.visible").click();
|
||||
cy.get("#input_account_field").type(testAccountName);
|
||||
cy.get("#input_name_field").type(testAccountName);
|
||||
cy.get("#input_first_pwd").type(testAccountName);
|
||||
cy.get(".checkbox-and-text").first().find("div").first().click();
|
||||
|
||||
cy.contains('button', 'Confirm')
|
||||
.should('be.visible')
|
||||
.and('be.enabled')
|
||||
cy.contains("button", "Confirm")
|
||||
.should("be.visible")
|
||||
.and("be.enabled")
|
||||
.click();
|
||||
cy.contains(MSG_ACCOUNT_NOT_UNIQUE).should('be.visible');
|
||||
cy.contains(MSG_ACCOUNT_NOT_UNIQUE).should("be.visible");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,33 +4,33 @@
|
||||
// cindy.chang@dsp.im (Cindy Chang), 2024/07/02
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../../support/intercept';
|
||||
import { loginWithFixtures } from "../../support/intercept";
|
||||
|
||||
describe('Password validation on create account.', () => {
|
||||
describe("Password validation on create account.", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/account-admin');
|
||||
cy.wait('@getUsers');
|
||||
cy.visit("/account-admin");
|
||||
cy.wait("@getUsers");
|
||||
});
|
||||
|
||||
it('When password is too short, confirm button stays disabled.', () => {
|
||||
cy.contains('button', 'Create New').should('be.visible').click();
|
||||
it("When password is too short, confirm button stays disabled.", () => {
|
||||
cy.contains("button", "Create New").should("be.visible").click();
|
||||
|
||||
cy.get('#input_account_field').type('unit-test-0001');
|
||||
cy.get('#input_name_field').type('unit-test-0001');
|
||||
cy.get("#input_account_field").type("unit-test-0001");
|
||||
cy.get("#input_name_field").type("unit-test-0001");
|
||||
// Password shorter than 6 characters
|
||||
cy.get('#input_first_pwd').type('aaa');
|
||||
cy.get("#input_first_pwd").type("aaa");
|
||||
|
||||
cy.contains('button', 'Confirm').should('be.disabled');
|
||||
cy.contains("button", "Confirm").should("be.disabled");
|
||||
});
|
||||
|
||||
it('When password meets minimum length, confirm button enables.', () => {
|
||||
cy.contains('button', 'Create New').should('be.visible').click();
|
||||
it("When password meets minimum length, confirm button enables.", () => {
|
||||
cy.contains("button", "Create New").should("be.visible").click();
|
||||
|
||||
cy.get('#input_account_field').type('unit-test-0001');
|
||||
cy.get('#input_name_field').type('unit-test-0001');
|
||||
cy.get('#input_first_pwd').type('aaaaaa');
|
||||
cy.get("#input_account_field").type("unit-test-0001");
|
||||
cy.get("#input_name_field").type("unit-test-0001");
|
||||
cy.get("#input_first_pwd").type("aaaaaa");
|
||||
|
||||
cy.contains('button', 'Confirm').should('be.enabled');
|
||||
cy.contains("button", "Confirm").should("be.enabled");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,39 +4,39 @@
|
||||
// cindy.chang@dsp.im (Cindy Chang), 2024/07/02
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../../support/intercept';
|
||||
import { loginWithFixtures } from "../../support/intercept";
|
||||
|
||||
describe('Create an Account', () => {
|
||||
describe("Create an Account", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
// Override: new usernames should return 404 (account doesn't exist yet)
|
||||
cy.intercept('GET', '/api/users/unit-test-*', {
|
||||
cy.intercept("GET", "/api/users/unit-test-*", {
|
||||
statusCode: 404,
|
||||
body: { detail: 'Not found' },
|
||||
}).as('checkNewUser');
|
||||
cy.visit('/account-admin');
|
||||
cy.wait('@getUsers');
|
||||
body: { detail: "Not found" },
|
||||
}).as("checkNewUser");
|
||||
cy.visit("/account-admin");
|
||||
cy.wait("@getUsers");
|
||||
});
|
||||
|
||||
it('Create a new account with admin role; should show saved message.', () => {
|
||||
cy.contains('button', 'Create New').should('be.visible').click();
|
||||
it("Create a new account with admin role; should show saved message.", () => {
|
||||
cy.contains("button", "Create New").should("be.visible").click();
|
||||
|
||||
cy.get('#input_account_field').type('unit-test-0001');
|
||||
cy.get('#input_name_field').type('unit-test-0001');
|
||||
cy.get('#input_first_pwd').type('aaaaaa');
|
||||
cy.get('.checkbox-and-text').first().find('div').first().click();
|
||||
cy.get("#input_account_field").type("unit-test-0001");
|
||||
cy.get("#input_name_field").type("unit-test-0001");
|
||||
cy.get("#input_first_pwd").type("aaaaaa");
|
||||
cy.get(".checkbox-and-text").first().find("div").first().click();
|
||||
|
||||
cy.contains('button', 'Confirm')
|
||||
.should('be.visible')
|
||||
.and('be.enabled')
|
||||
cy.contains("button", "Confirm")
|
||||
.should("be.visible")
|
||||
.and("be.enabled")
|
||||
.click();
|
||||
cy.wait('@postUser');
|
||||
cy.contains('Account added').should('be.visible');
|
||||
cy.wait("@postUser");
|
||||
cy.contains("Account added").should("be.visible");
|
||||
});
|
||||
|
||||
it('Confirm button is disabled when required fields are empty.', () => {
|
||||
cy.contains('button', 'Create New').should('be.visible').click();
|
||||
cy.get('#input_account_field').type('test');
|
||||
cy.contains('button', 'Confirm').should('be.disabled');
|
||||
it("Confirm button is disabled when required fields are empty.", () => {
|
||||
cy.contains("button", "Create New").should("be.visible").click();
|
||||
cy.get("#input_account_field").type("test");
|
||||
cy.contains("button", "Confirm").should("be.disabled");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,27 +4,27 @@
|
||||
// cindy.chang@dsp.im (Cindy Chang), 2024/07/03
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../../support/intercept';
|
||||
import { loginWithFixtures } from "../../support/intercept";
|
||||
|
||||
describe('Delete an Account', () => {
|
||||
describe("Delete an Account", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/account-admin');
|
||||
cy.wait('@getUsers');
|
||||
cy.visit("/account-admin");
|
||||
cy.wait("@getUsers");
|
||||
});
|
||||
|
||||
it('Delete button opens confirmation modal and deletes on confirm.', () => {
|
||||
cy.get('img.delete-account').first().click();
|
||||
cy.contains('ARE YOU SURE TO DELETE').should('be.visible');
|
||||
cy.get('#sure_to_delete_acct_btn').click();
|
||||
cy.wait('@deleteUser');
|
||||
cy.contains('Account deleted').should('be.visible');
|
||||
it("Delete button opens confirmation modal and deletes on confirm.", () => {
|
||||
cy.get("img.delete-account").first().click();
|
||||
cy.contains("ARE YOU SURE TO DELETE").should("be.visible");
|
||||
cy.get("#sure_to_delete_acct_btn").click();
|
||||
cy.wait("@deleteUser");
|
||||
cy.contains("Account deleted").should("be.visible");
|
||||
});
|
||||
|
||||
it('Cancel button closes the delete confirmation modal.', () => {
|
||||
cy.get('img.delete-account').first().click();
|
||||
cy.contains('ARE YOU SURE TO DELETE').should('be.visible');
|
||||
cy.get('#calcel_delete_acct_btn').click();
|
||||
cy.contains('ARE YOU SURE TO DELETE').should('not.exist');
|
||||
it("Cancel button closes the delete confirmation modal.", () => {
|
||||
cy.get("img.delete-account").first().click();
|
||||
cy.contains("ARE YOU SURE TO DELETE").should("be.visible");
|
||||
cy.get("#calcel_delete_acct_btn").click();
|
||||
cy.contains("ARE YOU SURE TO DELETE").should("not.exist");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,30 +4,30 @@
|
||||
// cindy.chang@dsp.im (Cindy Chang), 2024/07/03
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../../support/intercept';
|
||||
import { loginWithFixtures } from "../../support/intercept";
|
||||
|
||||
const MODAL_TITLE_ACCOUNT_EDIT = 'Account Edit';
|
||||
const MSG_ACCOUNT_EDITED = 'Saved';
|
||||
const MODAL_TITLE_ACCOUNT_EDIT = "Account Edit";
|
||||
const MSG_ACCOUNT_EDITED = "Saved";
|
||||
|
||||
describe('Edit an account', () => {
|
||||
describe("Edit an account", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/account-admin');
|
||||
cy.wait('@getUsers');
|
||||
cy.visit("/account-admin");
|
||||
cy.wait("@getUsers");
|
||||
});
|
||||
|
||||
it('Edit an account; modify name and see saved message.', () => {
|
||||
cy.get('.btn-edit').first().click();
|
||||
cy.wait('@getUserDetail');
|
||||
it("Edit an account; modify name and see saved message.", () => {
|
||||
cy.get(".btn-edit").first().click();
|
||||
cy.wait("@getUserDetail");
|
||||
|
||||
cy.contains('h1', MODAL_TITLE_ACCOUNT_EDIT).should('exist');
|
||||
cy.get('#input_name_field').clear().type('Updated Name');
|
||||
cy.contains("h1", MODAL_TITLE_ACCOUNT_EDIT).should("exist");
|
||||
cy.get("#input_name_field").clear().type("Updated Name");
|
||||
|
||||
cy.contains('button', 'Confirm')
|
||||
.should('be.visible')
|
||||
.and('be.enabled')
|
||||
cy.contains("button", "Confirm")
|
||||
.should("be.visible")
|
||||
.and("be.enabled")
|
||||
.click();
|
||||
cy.wait('@putUser');
|
||||
cy.contains(MSG_ACCOUNT_EDITED).should('be.visible');
|
||||
cy.wait("@putUser");
|
||||
cy.contains(MSG_ACCOUNT_EDITED).should("be.visible");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,94 +3,94 @@
|
||||
// Authors:
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../support/intercept';
|
||||
import { loginWithFixtures } from "../support/intercept";
|
||||
|
||||
describe('Account Management CRUD', () => {
|
||||
describe("Account Management CRUD", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/account-admin');
|
||||
cy.wait('@getUsers');
|
||||
cy.visit("/account-admin");
|
||||
cy.wait("@getUsers");
|
||||
});
|
||||
|
||||
it('shows Create New button', () => {
|
||||
cy.get('#create_new_acct_btn').should('exist');
|
||||
cy.get('#create_new_acct_btn').should('contain', 'Create New');
|
||||
it("shows Create New button", () => {
|
||||
cy.get("#create_new_acct_btn").should("exist");
|
||||
cy.get("#create_new_acct_btn").should("contain", "Create New");
|
||||
});
|
||||
|
||||
it('opens create new account modal', () => {
|
||||
cy.get('#create_new_acct_btn').click();
|
||||
cy.get('#modal_container').should('be.visible');
|
||||
cy.get('#modal_account_edit_or_create_new').should('be.visible');
|
||||
it("opens create new account modal", () => {
|
||||
cy.get("#create_new_acct_btn").click();
|
||||
cy.get("#modal_container").should("be.visible");
|
||||
cy.get("#modal_account_edit_or_create_new").should("be.visible");
|
||||
// Should show account, name, password fields
|
||||
cy.get('#input_account_field').should('exist');
|
||||
cy.get('#input_name_field').should('exist');
|
||||
cy.get('#input_first_pwd').should('exist');
|
||||
cy.get("#input_account_field").should("exist");
|
||||
cy.get("#input_name_field").should("exist");
|
||||
cy.get("#input_first_pwd").should("exist");
|
||||
});
|
||||
|
||||
it('create account confirm is disabled when fields are empty', () => {
|
||||
cy.get('#create_new_acct_btn').click();
|
||||
cy.get('.confirm-btn').should('be.disabled');
|
||||
it("create account confirm is disabled when fields are empty", () => {
|
||||
cy.get("#create_new_acct_btn").click();
|
||||
cy.get(".confirm-btn").should("be.disabled");
|
||||
});
|
||||
|
||||
it('create account confirm enables when fields are filled', () => {
|
||||
cy.get('#create_new_acct_btn').click();
|
||||
cy.get('#input_account_field').type('newuser');
|
||||
cy.get('#input_name_field').type('New User');
|
||||
cy.get('#input_first_pwd').type('password1234');
|
||||
cy.get('.confirm-btn').should('not.be.disabled');
|
||||
it("create account confirm enables when fields are filled", () => {
|
||||
cy.get("#create_new_acct_btn").click();
|
||||
cy.get("#input_account_field").type("newuser");
|
||||
cy.get("#input_name_field").type("New User");
|
||||
cy.get("#input_first_pwd").type("password1234");
|
||||
cy.get(".confirm-btn").should("not.be.disabled");
|
||||
});
|
||||
|
||||
it('cancel button closes the modal', () => {
|
||||
cy.get('#create_new_acct_btn').click();
|
||||
cy.get('#modal_container').should('be.visible');
|
||||
cy.get('.cancel-btn').click();
|
||||
cy.get('#modal_container').should('not.exist');
|
||||
it("cancel button closes the modal", () => {
|
||||
cy.get("#create_new_acct_btn").click();
|
||||
cy.get("#modal_container").should("be.visible");
|
||||
cy.get(".cancel-btn").click();
|
||||
cy.get("#modal_container").should("not.exist");
|
||||
});
|
||||
|
||||
it('close (X) button closes the modal', () => {
|
||||
cy.get('#create_new_acct_btn').click();
|
||||
cy.get('#modal_container').should('be.visible');
|
||||
it("close (X) button closes the modal", () => {
|
||||
cy.get("#create_new_acct_btn").click();
|
||||
cy.get("#modal_container").should("be.visible");
|
||||
cy.get('img[alt="X"]').click();
|
||||
cy.get('#modal_container').should('not.exist');
|
||||
cy.get("#modal_container").should("not.exist");
|
||||
});
|
||||
|
||||
it('double-click username opens account info modal', () => {
|
||||
it("double-click username opens account info modal", () => {
|
||||
// Double-click on the first account username
|
||||
cy.get('.account-cell').first().dblclick();
|
||||
cy.get('#modal_container').should('be.visible');
|
||||
cy.get(".account-cell").first().dblclick();
|
||||
cy.get("#modal_container").should("be.visible");
|
||||
});
|
||||
|
||||
it('delete button opens delete confirmation modal', () => {
|
||||
it("delete button opens delete confirmation modal", () => {
|
||||
// Click the delete icon for a non-current user
|
||||
cy.get('.delete-account').first().click();
|
||||
cy.get('#modal_container').should('be.visible');
|
||||
cy.get('#modal_delete_acct_alert').should('be.visible');
|
||||
cy.get(".delete-account").first().click();
|
||||
cy.get("#modal_container").should("be.visible");
|
||||
cy.get("#modal_delete_acct_alert").should("be.visible");
|
||||
});
|
||||
|
||||
it('delete modal has Yes and No buttons', () => {
|
||||
cy.get('.delete-account').first().click();
|
||||
cy.get('#calcel_delete_acct_btn').should('exist');
|
||||
cy.get('#sure_to_delete_acct_btn').should('exist');
|
||||
it("delete modal has Yes and No buttons", () => {
|
||||
cy.get(".delete-account").first().click();
|
||||
cy.get("#calcel_delete_acct_btn").should("exist");
|
||||
cy.get("#sure_to_delete_acct_btn").should("exist");
|
||||
});
|
||||
|
||||
it('delete modal No button closes the modal', () => {
|
||||
cy.get('.delete-account').first().click();
|
||||
cy.get('#calcel_delete_acct_btn').click();
|
||||
cy.get('#modal_container').should('not.exist');
|
||||
it("delete modal No button closes the modal", () => {
|
||||
cy.get(".delete-account").first().click();
|
||||
cy.get("#calcel_delete_acct_btn").click();
|
||||
cy.get("#modal_container").should("not.exist");
|
||||
});
|
||||
|
||||
it('shows checkboxes for Set as Admin and Activate in create modal', () => {
|
||||
cy.get('#create_new_acct_btn').click();
|
||||
cy.get('#account_create_checkboxes_section').should('be.visible');
|
||||
cy.contains('Set as admin.').should('exist');
|
||||
cy.contains('Activate now.').should('exist');
|
||||
it("shows checkboxes for Set as Admin and Activate in create modal", () => {
|
||||
cy.get("#create_new_acct_btn").click();
|
||||
cy.get("#account_create_checkboxes_section").should("be.visible");
|
||||
cy.contains("Set as admin.").should("exist");
|
||||
cy.contains("Activate now.").should("exist");
|
||||
});
|
||||
|
||||
it('search bar filters user list', () => {
|
||||
it("search bar filters user list", () => {
|
||||
// Search filters by username, not display name
|
||||
cy.get('#input_search').type('user1');
|
||||
cy.get("#input_search").type("user1");
|
||||
cy.get('img[alt="search"]').click();
|
||||
// Should only show user1 (Alice Wang)
|
||||
cy.contains('user1').should('exist');
|
||||
cy.contains("user1").should("exist");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,38 +3,38 @@
|
||||
// Authors:
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../support/intercept';
|
||||
import { loginWithFixtures } from "../support/intercept";
|
||||
|
||||
describe('Account Info Modal', () => {
|
||||
describe("Account Info Modal", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/account-admin');
|
||||
cy.wait('@getUsers');
|
||||
cy.visit("/account-admin");
|
||||
cy.wait("@getUsers");
|
||||
});
|
||||
|
||||
it('double-click username opens info modal with user data', () => {
|
||||
cy.get('.account-cell').first().dblclick();
|
||||
cy.get('#modal_container').should('be.visible');
|
||||
cy.get('#acct_info_user_name').should('exist');
|
||||
it("double-click username opens info modal with user data", () => {
|
||||
cy.get(".account-cell").first().dblclick();
|
||||
cy.get("#modal_container").should("be.visible");
|
||||
cy.get("#acct_info_user_name").should("exist");
|
||||
});
|
||||
|
||||
it('info modal shows Account Information header', () => {
|
||||
cy.get('.account-cell').first().dblclick();
|
||||
cy.get('#modal_container').should('be.visible');
|
||||
cy.contains('Account Information').should('exist');
|
||||
it("info modal shows Account Information header", () => {
|
||||
cy.get(".account-cell").first().dblclick();
|
||||
cy.get("#modal_container").should("be.visible");
|
||||
cy.contains("Account Information").should("exist");
|
||||
});
|
||||
|
||||
it('info modal shows account visit info', () => {
|
||||
cy.get('.account-cell').first().dblclick();
|
||||
cy.get('#modal_container').should('be.visible');
|
||||
cy.get('#account_visit_info').should('exist');
|
||||
cy.get('#account_visit_info').should('contain', 'Account:');
|
||||
it("info modal shows account visit info", () => {
|
||||
cy.get(".account-cell").first().dblclick();
|
||||
cy.get("#modal_container").should("be.visible");
|
||||
cy.get("#account_visit_info").should("exist");
|
||||
cy.get("#account_visit_info").should("contain", "Account:");
|
||||
});
|
||||
|
||||
it('info modal can be closed via X button', () => {
|
||||
cy.get('.account-cell').first().dblclick();
|
||||
cy.get('#modal_container').should('be.visible');
|
||||
it("info modal can be closed via X button", () => {
|
||||
cy.get(".account-cell").first().dblclick();
|
||||
cy.get("#modal_container").should("be.visible");
|
||||
cy.get('img[alt="X"]').click();
|
||||
cy.get('#modal_container').should('not.exist');
|
||||
cy.get("#modal_container").should("not.exist");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,78 +5,86 @@
|
||||
// cindy.chang@dsp.im (Cindy Chang), 2024/05/30
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../support/intercept';
|
||||
import { loginWithFixtures } from "../support/intercept";
|
||||
|
||||
describe('Compare', () => {
|
||||
describe("Compare", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/files');
|
||||
cy.wait('@getFiles');
|
||||
cy.contains('li', 'COMPARE').click();
|
||||
cy.visit("/files");
|
||||
cy.wait("@getFiles");
|
||||
cy.contains("li", "COMPARE").click();
|
||||
});
|
||||
|
||||
it('Compare dropdown sorting options', () => {
|
||||
it("Compare dropdown sorting options", () => {
|
||||
const expectedOptions = [
|
||||
'By File Name (A to Z)', 'By File Name (Z to A)',
|
||||
'By Dependency (A to Z)', 'By Dependency (Z to A)',
|
||||
'By File Type (A to Z)', 'By File Type (Z to A)',
|
||||
'By Last Update (A to Z)', 'By Last Update (Z to A)',
|
||||
"By File Name (A to Z)",
|
||||
"By File Name (Z to A)",
|
||||
"By Dependency (A to Z)",
|
||||
"By Dependency (Z to A)",
|
||||
"By File Type (A to Z)",
|
||||
"By File Type (Z to A)",
|
||||
"By Last Update (A to Z)",
|
||||
"By Last Update (Z to A)",
|
||||
];
|
||||
|
||||
cy.get('.p-select').click();
|
||||
cy.get('.p-select-list')
|
||||
.find('.p-select-option')
|
||||
.then($options => {
|
||||
cy.get(".p-select").click();
|
||||
cy.get(".p-select-list")
|
||||
.find(".p-select-option")
|
||||
.then(($options) => {
|
||||
const actualOptions = $options
|
||||
.map((index, elem) => Cypress.$(elem).find('.p-select-option-label').text())
|
||||
.map((index, elem) =>
|
||||
Cypress.$(elem).find(".p-select-option-label").text(),
|
||||
)
|
||||
.get();
|
||||
expect(actualOptions).to.deep.equal(expectedOptions);
|
||||
});
|
||||
});
|
||||
|
||||
it('Grid cards are rendered for compare file selection', () => {
|
||||
cy.get('#compareGridCards').find('li').should('have.length.greaterThan', 0);
|
||||
it("Grid cards are rendered for compare file selection", () => {
|
||||
cy.get("#compareGridCards").find("li").should("have.length.greaterThan", 0);
|
||||
});
|
||||
|
||||
it('Compare button is disabled until two files are dragged', () => {
|
||||
cy.contains('button', 'Compare').should('be.disabled');
|
||||
cy.get('#compareFile0').drag('#primaryDragCard');
|
||||
cy.get('#compareFile1').drag('#secondaryDragCard');
|
||||
cy.contains('button', 'Compare').should('be.enabled');
|
||||
it("Compare button is disabled until two files are dragged", () => {
|
||||
cy.contains("button", "Compare").should("be.disabled");
|
||||
cy.get("#compareFile0").drag("#primaryDragCard");
|
||||
cy.get("#compareFile1").drag("#secondaryDragCard");
|
||||
cy.contains("button", "Compare").should("be.enabled");
|
||||
});
|
||||
|
||||
it('Enter Compare dashboard and see charts', () => {
|
||||
cy.get('#compareFile0').drag('#primaryDragCard');
|
||||
cy.get('#compareFile1').drag('#secondaryDragCard');
|
||||
cy.contains('button', 'Compare').click();
|
||||
cy.wait('@getCompare');
|
||||
cy.url().should('include', 'compare');
|
||||
it("Enter Compare dashboard and see charts", () => {
|
||||
cy.get("#compareFile0").drag("#primaryDragCard");
|
||||
cy.get("#compareFile1").drag("#secondaryDragCard");
|
||||
cy.contains("button", "Compare").click();
|
||||
cy.wait("@getCompare");
|
||||
cy.url().should("include", "compare");
|
||||
|
||||
// Assert chart title spans are visible
|
||||
cy.contains('span', 'Average Cycle Time').should('exist');
|
||||
cy.contains('span', 'Cycle Efficiency').should('exist');
|
||||
cy.contains('span', 'Average Processing Time').should('exist');
|
||||
cy.contains('span', 'Average Processing Time by Activity').should('exist');
|
||||
cy.contains('span', 'Average Waiting Time').should('exist');
|
||||
cy.contains('span', 'Average Waiting Time between Activity').should('exist');
|
||||
cy.contains("span", "Average Cycle Time").should("exist");
|
||||
cy.contains("span", "Cycle Efficiency").should("exist");
|
||||
cy.contains("span", "Average Processing Time").should("exist");
|
||||
cy.contains("span", "Average Processing Time by Activity").should("exist");
|
||||
cy.contains("span", "Average Waiting Time").should("exist");
|
||||
cy.contains("span", "Average Waiting Time between Activity").should(
|
||||
"exist",
|
||||
);
|
||||
});
|
||||
|
||||
it('Compare State button exists on dashboard', () => {
|
||||
cy.get('#compareFile0').drag('#primaryDragCard');
|
||||
cy.get('#compareFile1').drag('#secondaryDragCard');
|
||||
cy.contains('button', 'Compare').click();
|
||||
cy.wait('@getCompare');
|
||||
it("Compare State button exists on dashboard", () => {
|
||||
cy.get("#compareFile0").drag("#primaryDragCard");
|
||||
cy.get("#compareFile1").drag("#secondaryDragCard");
|
||||
cy.contains("button", "Compare").click();
|
||||
cy.wait("@getCompare");
|
||||
|
||||
cy.get('#compareState').should('exist').and('be.visible');
|
||||
cy.get("#compareState").should("exist").and("be.visible");
|
||||
});
|
||||
|
||||
it('Sidebar shows time usage and frequency sections', () => {
|
||||
cy.get('#compareFile0').drag('#primaryDragCard');
|
||||
cy.get('#compareFile1').drag('#secondaryDragCard');
|
||||
cy.contains('button', 'Compare').click();
|
||||
cy.wait('@getCompare');
|
||||
it("Sidebar shows time usage and frequency sections", () => {
|
||||
cy.get("#compareFile0").drag("#primaryDragCard");
|
||||
cy.get("#compareFile1").drag("#secondaryDragCard");
|
||||
cy.contains("button", "Compare").click();
|
||||
cy.wait("@getCompare");
|
||||
|
||||
cy.get('aside').should('exist');
|
||||
cy.get('aside li').should('have.length.greaterThan', 0);
|
||||
cy.get("aside").should("exist");
|
||||
cy.get("aside li").should("have.length.greaterThan", 0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,53 +3,53 @@
|
||||
// Authors:
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../support/intercept';
|
||||
import { loginWithFixtures } from "../support/intercept";
|
||||
|
||||
describe('Discover Conformance Page', () => {
|
||||
describe("Discover Conformance Page", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/discover/log/297310264/conformance');
|
||||
cy.wait('@getLogCheckParams');
|
||||
cy.visit("/discover/log/297310264/conformance");
|
||||
cy.wait("@getLogCheckParams");
|
||||
});
|
||||
|
||||
it('page loads and loading overlay disappears', () => {
|
||||
cy.get('.z-\\[9999\\]', { timeout: 10000 }).should('not.exist');
|
||||
it("page loads and loading overlay disappears", () => {
|
||||
cy.get(".z-\\[9999\\]", { timeout: 10000 }).should("not.exist");
|
||||
});
|
||||
|
||||
it('displays Rule Settings sidebar', () => {
|
||||
cy.get('.z-\\[9999\\]', { timeout: 10000 }).should('not.exist');
|
||||
cy.contains('Rule Settings').should('be.visible');
|
||||
it("displays Rule Settings sidebar", () => {
|
||||
cy.get(".z-\\[9999\\]", { timeout: 10000 }).should("not.exist");
|
||||
cy.contains("Rule Settings").should("be.visible");
|
||||
});
|
||||
|
||||
it('displays Conformance Checking Results heading', () => {
|
||||
cy.get('.z-\\[9999\\]', { timeout: 10000 }).should('not.exist');
|
||||
cy.contains('Conformance Checking Results').should('be.visible');
|
||||
it("displays Conformance Checking Results heading", () => {
|
||||
cy.get(".z-\\[9999\\]", { timeout: 10000 }).should("not.exist");
|
||||
cy.contains("Conformance Checking Results").should("be.visible");
|
||||
});
|
||||
|
||||
it('displays rule type radio options', () => {
|
||||
cy.get('.z-\\[9999\\]', { timeout: 10000 }).should('not.exist');
|
||||
cy.contains('Have activity').should('be.visible');
|
||||
cy.contains('Activity sequence').should('be.visible');
|
||||
cy.contains('Activity duration').should('be.visible');
|
||||
cy.contains('Processing time').should('be.visible');
|
||||
cy.contains('Waiting time').should('be.visible');
|
||||
cy.contains('Cycle time').should('be.visible');
|
||||
it("displays rule type radio options", () => {
|
||||
cy.get(".z-\\[9999\\]", { timeout: 10000 }).should("not.exist");
|
||||
cy.contains("Have activity").should("be.visible");
|
||||
cy.contains("Activity sequence").should("be.visible");
|
||||
cy.contains("Activity duration").should("be.visible");
|
||||
cy.contains("Processing time").should("be.visible");
|
||||
cy.contains("Waiting time").should("be.visible");
|
||||
cy.contains("Cycle time").should("be.visible");
|
||||
});
|
||||
|
||||
it('displays Clear and Apply buttons', () => {
|
||||
cy.get('.z-\\[9999\\]', { timeout: 10000 }).should('not.exist');
|
||||
cy.contains('button', 'Clear').should('be.visible');
|
||||
cy.contains('button', 'Apply').should('exist');
|
||||
it("displays Clear and Apply buttons", () => {
|
||||
cy.get(".z-\\[9999\\]", { timeout: 10000 }).should("not.exist");
|
||||
cy.contains("button", "Clear").should("be.visible");
|
||||
cy.contains("button", "Apply").should("exist");
|
||||
});
|
||||
|
||||
it('displays Activity list area', () => {
|
||||
cy.get('.z-\\[9999\\]', { timeout: 10000 }).should('not.exist');
|
||||
cy.contains('Activity list').should('be.visible');
|
||||
it("displays Activity list area", () => {
|
||||
cy.get(".z-\\[9999\\]", { timeout: 10000 }).should("not.exist");
|
||||
cy.contains("Activity list").should("be.visible");
|
||||
});
|
||||
|
||||
it('displays default placeholder values in results', () => {
|
||||
cy.get('.z-\\[9999\\]', { timeout: 10000 }).should('not.exist');
|
||||
cy.contains('Conformance Rate').should('be.visible');
|
||||
cy.contains('Cases').should('be.visible');
|
||||
it("displays default placeholder values in results", () => {
|
||||
cy.get(".z-\\[9999\\]", { timeout: 10000 }).should("not.exist");
|
||||
cy.contains("Conformance Rate").should("be.visible");
|
||||
cy.contains("Cases").should("be.visible");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,49 +3,55 @@
|
||||
// Authors:
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../support/intercept';
|
||||
import { loginWithFixtures } from "../support/intercept";
|
||||
|
||||
describe('Discover Map Page', () => {
|
||||
describe("Discover Map Page", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
// Suppress Cytoscape rendering errors in headless mode
|
||||
cy.on('uncaught:exception', () => false);
|
||||
cy.visit('/discover/log/297310264/map');
|
||||
cy.wait('@getDiscover');
|
||||
cy.on("uncaught:exception", () => false);
|
||||
cy.visit("/discover/log/297310264/map");
|
||||
cy.wait("@getDiscover");
|
||||
});
|
||||
|
||||
it('page loads and cytoscape container exists', () => {
|
||||
cy.get('#cy').should('exist');
|
||||
it("page loads and cytoscape container exists", () => {
|
||||
cy.get("#cy").should("exist");
|
||||
});
|
||||
|
||||
it('displays left sidebar buttons', () => {
|
||||
it("displays left sidebar buttons", () => {
|
||||
// Visualization Setting, Filter, Traces buttons
|
||||
cy.get('.material-symbols-outlined').contains('track_changes').should('exist');
|
||||
cy.get('.material-symbols-outlined').contains('tornado').should('exist');
|
||||
cy.get('.material-symbols-outlined').contains('rebase').should('exist');
|
||||
cy.get(".material-symbols-outlined")
|
||||
.contains("track_changes")
|
||||
.should("exist");
|
||||
cy.get(".material-symbols-outlined").contains("tornado").should("exist");
|
||||
cy.get(".material-symbols-outlined").contains("rebase").should("exist");
|
||||
});
|
||||
|
||||
it('displays right sidebar Summary button', () => {
|
||||
cy.get('#sidebar_state').should('exist');
|
||||
cy.get('#iconState').should('exist');
|
||||
it("displays right sidebar Summary button", () => {
|
||||
cy.get("#sidebar_state").should("exist");
|
||||
cy.get("#iconState").should("exist");
|
||||
});
|
||||
|
||||
it('clicking Visualization Setting button toggles sidebar', () => {
|
||||
it("clicking Visualization Setting button toggles sidebar", () => {
|
||||
// Click the track_changes icon (Visualization Setting)
|
||||
cy.contains('span.material-symbols-outlined', 'track_changes').parent('li').click();
|
||||
cy.contains("span.material-symbols-outlined", "track_changes")
|
||||
.parent("li")
|
||||
.click();
|
||||
// SidebarView should open
|
||||
cy.contains('Visualization Setting').should('be.visible');
|
||||
cy.contains("Visualization Setting").should("be.visible");
|
||||
});
|
||||
|
||||
it('clicking Summary button toggles sidebar', () => {
|
||||
cy.get('#iconState').click();
|
||||
it("clicking Summary button toggles sidebar", () => {
|
||||
cy.get("#iconState").click();
|
||||
// SidebarState should open with insights/stats
|
||||
cy.contains('Summary').should('be.visible');
|
||||
cy.contains("Summary").should("be.visible");
|
||||
});
|
||||
|
||||
it('clicking Traces button toggles sidebar', () => {
|
||||
cy.contains('span.material-symbols-outlined', 'rebase').parent('li').click();
|
||||
it("clicking Traces button toggles sidebar", () => {
|
||||
cy.contains("span.material-symbols-outlined", "rebase")
|
||||
.parent("li")
|
||||
.click();
|
||||
// SidebarTraces should open
|
||||
cy.contains('Traces').should('be.visible');
|
||||
cy.contains("Traces").should("be.visible");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,64 +3,64 @@
|
||||
// Authors:
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../support/intercept';
|
||||
import { loginWithFixtures } from "../support/intercept";
|
||||
|
||||
describe('Discover Performance Page', () => {
|
||||
describe("Discover Performance Page", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/discover/log/297310264/performance');
|
||||
cy.wait('@getPerformance');
|
||||
cy.visit("/discover/log/297310264/performance");
|
||||
cy.wait("@getPerformance");
|
||||
});
|
||||
|
||||
it('page loads and loading overlay disappears', () => {
|
||||
it("page loads and loading overlay disappears", () => {
|
||||
// Loading overlay should not be visible after data loads
|
||||
cy.get('.z-\\[9999\\]', { timeout: 10000 }).should('not.exist');
|
||||
cy.get(".z-\\[9999\\]", { timeout: 10000 }).should("not.exist");
|
||||
});
|
||||
|
||||
it('displays Time Usage sidebar section', () => {
|
||||
cy.get('.z-\\[9999\\]', { timeout: 10000 }).should('not.exist');
|
||||
cy.contains('Time Usage').should('be.visible');
|
||||
it("displays Time Usage sidebar section", () => {
|
||||
cy.get(".z-\\[9999\\]", { timeout: 10000 }).should("not.exist");
|
||||
cy.contains("Time Usage").should("be.visible");
|
||||
});
|
||||
|
||||
it('displays Frequency sidebar section', () => {
|
||||
cy.get('.z-\\[9999\\]', { timeout: 10000 }).should('not.exist');
|
||||
cy.contains('Frequency').should('be.visible');
|
||||
it("displays Frequency sidebar section", () => {
|
||||
cy.get(".z-\\[9999\\]", { timeout: 10000 }).should("not.exist");
|
||||
cy.contains("Frequency").should("be.visible");
|
||||
});
|
||||
|
||||
it('displays sidebar navigation items', () => {
|
||||
cy.get('.z-\\[9999\\]', { timeout: 10000 }).should('not.exist');
|
||||
cy.contains('Cycle Time & Efficiency').should('be.visible');
|
||||
cy.contains('Processing Time').should('be.visible');
|
||||
cy.contains('Waiting Time').should('be.visible');
|
||||
cy.contains('Number of Cases').should('be.visible');
|
||||
it("displays sidebar navigation items", () => {
|
||||
cy.get(".z-\\[9999\\]", { timeout: 10000 }).should("not.exist");
|
||||
cy.contains("Cycle Time & Efficiency").should("be.visible");
|
||||
cy.contains("Processing Time").should("be.visible");
|
||||
cy.contains("Waiting Time").should("be.visible");
|
||||
cy.contains("Number of Cases").should("be.visible");
|
||||
});
|
||||
|
||||
it('displays chart titles', () => {
|
||||
cy.get('.z-\\[9999\\]', { timeout: 10000 }).should('not.exist');
|
||||
cy.contains('Average Cycle Time').should('be.visible');
|
||||
cy.contains('Cycle Efficiency').should('be.visible');
|
||||
cy.contains('Average Processing Time').should('be.visible');
|
||||
cy.contains('Average Processing Time by Activity').should('be.visible');
|
||||
cy.contains('Average Waiting Time').should('be.visible');
|
||||
it("displays chart titles", () => {
|
||||
cy.get(".z-\\[9999\\]", { timeout: 10000 }).should("not.exist");
|
||||
cy.contains("Average Cycle Time").should("be.visible");
|
||||
cy.contains("Cycle Efficiency").should("be.visible");
|
||||
cy.contains("Average Processing Time").should("be.visible");
|
||||
cy.contains("Average Processing Time by Activity").should("be.visible");
|
||||
cy.contains("Average Waiting Time").should("be.visible");
|
||||
});
|
||||
|
||||
it('displays frequency chart titles', () => {
|
||||
cy.get('.z-\\[9999\\]', { timeout: 10000 }).should('not.exist');
|
||||
cy.contains('New Cases').should('be.visible');
|
||||
cy.contains('Number of Cases by Activity').should('be.visible');
|
||||
it("displays frequency chart titles", () => {
|
||||
cy.get(".z-\\[9999\\]", { timeout: 10000 }).should("not.exist");
|
||||
cy.contains("New Cases").should("be.visible");
|
||||
cy.contains("Number of Cases by Activity").should("be.visible");
|
||||
});
|
||||
|
||||
it('renders canvas elements for charts', () => {
|
||||
cy.get('.z-\\[9999\\]', { timeout: 10000 }).should('not.exist');
|
||||
it("renders canvas elements for charts", () => {
|
||||
cy.get(".z-\\[9999\\]", { timeout: 10000 }).should("not.exist");
|
||||
// Chart.js renders into canvas elements
|
||||
cy.get('canvas').should('have.length.at.least', 5);
|
||||
cy.get("canvas").should("have.length.at.least", 5);
|
||||
});
|
||||
|
||||
it('sidebar navigation scrolls to section', () => {
|
||||
cy.get('.z-\\[9999\\]', { timeout: 10000 }).should('not.exist');
|
||||
it("sidebar navigation scrolls to section", () => {
|
||||
cy.get(".z-\\[9999\\]", { timeout: 10000 }).should("not.exist");
|
||||
// Click on "Waiting Time" in sidebar
|
||||
cy.contains('li', 'Waiting Time').click();
|
||||
cy.contains("li", "Waiting Time").click();
|
||||
// The Waiting Time section should be in view
|
||||
cy.get('#waitingTime').should('exist');
|
||||
cy.get("#waitingTime").should("exist");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,94 +3,94 @@
|
||||
// Authors:
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../support/intercept';
|
||||
import { loginWithFixtures } from "../support/intercept";
|
||||
|
||||
describe('Discover Tab Navigation', () => {
|
||||
describe("Discover Tab Navigation", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
// Suppress Cytoscape rendering errors in headless mode
|
||||
cy.on('uncaught:exception', () => false);
|
||||
cy.on("uncaught:exception", () => false);
|
||||
});
|
||||
|
||||
describe('navigating from Map page', () => {
|
||||
describe("navigating from Map page", () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/discover/log/297310264/map');
|
||||
cy.wait('@getDiscover');
|
||||
cy.visit("/discover/log/297310264/map");
|
||||
cy.wait("@getDiscover");
|
||||
});
|
||||
|
||||
it('shows DISCOVER heading and MAP/CONFORMANCE/PERFORMANCE tabs', () => {
|
||||
cy.get('#nav_bar').contains('DISCOVER').should('be.visible');
|
||||
cy.get('.nav-item').should('have.length', 3);
|
||||
cy.get('.nav-item').eq(0).should('contain', 'MAP');
|
||||
cy.get('.nav-item').eq(1).should('contain', 'CONFORMANCE');
|
||||
cy.get('.nav-item').eq(2).should('contain', 'PERFORMANCE');
|
||||
it("shows DISCOVER heading and MAP/CONFORMANCE/PERFORMANCE tabs", () => {
|
||||
cy.get("#nav_bar").contains("DISCOVER").should("be.visible");
|
||||
cy.get(".nav-item").should("have.length", 3);
|
||||
cy.get(".nav-item").eq(0).should("contain", "MAP");
|
||||
cy.get(".nav-item").eq(1).should("contain", "CONFORMANCE");
|
||||
cy.get(".nav-item").eq(2).should("contain", "PERFORMANCE");
|
||||
});
|
||||
|
||||
it('clicking PERFORMANCE tab navigates to performance page', () => {
|
||||
cy.get('.nav-item').contains('PERFORMANCE').click();
|
||||
cy.url().should('include', '/performance');
|
||||
cy.wait('@getPerformance');
|
||||
cy.get('.z-\\[9999\\]', { timeout: 10000 }).should('not.exist');
|
||||
cy.contains('Time Usage').should('be.visible');
|
||||
it("clicking PERFORMANCE tab navigates to performance page", () => {
|
||||
cy.get(".nav-item").contains("PERFORMANCE").click();
|
||||
cy.url().should("include", "/performance");
|
||||
cy.wait("@getPerformance");
|
||||
cy.get(".z-\\[9999\\]", { timeout: 10000 }).should("not.exist");
|
||||
cy.contains("Time Usage").should("be.visible");
|
||||
});
|
||||
|
||||
it('clicking CONFORMANCE tab navigates to conformance page', () => {
|
||||
cy.get('.nav-item').contains('CONFORMANCE').click();
|
||||
cy.url().should('include', '/conformance');
|
||||
cy.wait('@getLogCheckParams');
|
||||
cy.get('.z-\\[9999\\]', { timeout: 10000 }).should('not.exist');
|
||||
cy.contains('Rule Settings').should('be.visible');
|
||||
it("clicking CONFORMANCE tab navigates to conformance page", () => {
|
||||
cy.get(".nav-item").contains("CONFORMANCE").click();
|
||||
cy.url().should("include", "/conformance");
|
||||
cy.wait("@getLogCheckParams");
|
||||
cy.get(".z-\\[9999\\]", { timeout: 10000 }).should("not.exist");
|
||||
cy.contains("Rule Settings").should("be.visible");
|
||||
});
|
||||
|
||||
it('shows back arrow to return to Files', () => {
|
||||
cy.get('#backPage').should('exist');
|
||||
cy.get('#backPage').should('have.attr', 'href', '/files');
|
||||
it("shows back arrow to return to Files", () => {
|
||||
cy.get("#backPage").should("exist");
|
||||
cy.get("#backPage").should("have.attr", "href", "/files");
|
||||
});
|
||||
});
|
||||
|
||||
describe('navigating from Performance page', () => {
|
||||
describe("navigating from Performance page", () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/discover/log/297310264/performance');
|
||||
cy.wait('@getPerformance');
|
||||
cy.get('.z-\\[9999\\]', { timeout: 10000 }).should('not.exist');
|
||||
cy.visit("/discover/log/297310264/performance");
|
||||
cy.wait("@getPerformance");
|
||||
cy.get(".z-\\[9999\\]", { timeout: 10000 }).should("not.exist");
|
||||
});
|
||||
|
||||
it('clicking MAP tab navigates to map page', () => {
|
||||
cy.get('.nav-item').contains('MAP').click();
|
||||
cy.url().should('include', '/map');
|
||||
cy.wait('@getDiscover');
|
||||
cy.get('#cy').should('exist');
|
||||
it("clicking MAP tab navigates to map page", () => {
|
||||
cy.get(".nav-item").contains("MAP").click();
|
||||
cy.url().should("include", "/map");
|
||||
cy.wait("@getDiscover");
|
||||
cy.get("#cy").should("exist");
|
||||
});
|
||||
|
||||
it('clicking CONFORMANCE tab navigates to conformance page', () => {
|
||||
cy.get('.nav-item').contains('CONFORMANCE').click();
|
||||
cy.url().should('include', '/conformance');
|
||||
cy.wait('@getLogCheckParams');
|
||||
cy.get('.z-\\[9999\\]', { timeout: 10000 }).should('not.exist');
|
||||
cy.contains('Rule Settings').should('be.visible');
|
||||
it("clicking CONFORMANCE tab navigates to conformance page", () => {
|
||||
cy.get(".nav-item").contains("CONFORMANCE").click();
|
||||
cy.url().should("include", "/conformance");
|
||||
cy.wait("@getLogCheckParams");
|
||||
cy.get(".z-\\[9999\\]", { timeout: 10000 }).should("not.exist");
|
||||
cy.contains("Rule Settings").should("be.visible");
|
||||
});
|
||||
});
|
||||
|
||||
describe('navigating from Conformance page', () => {
|
||||
describe("navigating from Conformance page", () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/discover/log/297310264/conformance');
|
||||
cy.wait('@getLogCheckParams');
|
||||
cy.get('.z-\\[9999\\]', { timeout: 10000 }).should('not.exist');
|
||||
cy.visit("/discover/log/297310264/conformance");
|
||||
cy.wait("@getLogCheckParams");
|
||||
cy.get(".z-\\[9999\\]", { timeout: 10000 }).should("not.exist");
|
||||
});
|
||||
|
||||
it('clicking MAP tab navigates to map page', () => {
|
||||
cy.get('.nav-item').contains('MAP').click();
|
||||
cy.url().should('include', '/map');
|
||||
cy.wait('@getDiscover');
|
||||
cy.get('#cy').should('exist');
|
||||
it("clicking MAP tab navigates to map page", () => {
|
||||
cy.get(".nav-item").contains("MAP").click();
|
||||
cy.url().should("include", "/map");
|
||||
cy.wait("@getDiscover");
|
||||
cy.get("#cy").should("exist");
|
||||
});
|
||||
|
||||
it('clicking PERFORMANCE tab navigates to performance page', () => {
|
||||
cy.get('.nav-item').contains('PERFORMANCE').click();
|
||||
cy.url().should('include', '/performance');
|
||||
cy.wait('@getPerformance');
|
||||
cy.get('.z-\\[9999\\]', { timeout: 10000 }).should('not.exist');
|
||||
cy.contains('Time Usage').should('be.visible');
|
||||
it("clicking PERFORMANCE tab navigates to performance page", () => {
|
||||
cy.get(".nav-item").contains("PERFORMANCE").click();
|
||||
cy.url().should("include", "/performance");
|
||||
cy.wait("@getPerformance");
|
||||
cy.get(".z-\\[9999\\]", { timeout: 10000 }).should("not.exist");
|
||||
cy.contains("Time Usage").should("be.visible");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,92 +3,92 @@
|
||||
// Authors:
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../support/intercept';
|
||||
import { loginWithFixtures } from "../support/intercept";
|
||||
|
||||
describe('Edge Cases', () => {
|
||||
describe('Empty states', () => {
|
||||
it('files page handles empty file list', () => {
|
||||
describe("Edge Cases", () => {
|
||||
describe("Empty states", () => {
|
||||
it("files page handles empty file list", () => {
|
||||
loginWithFixtures();
|
||||
// Override files intercept with empty array
|
||||
cy.intercept('GET', '/api/files', {
|
||||
cy.intercept("GET", "/api/files", {
|
||||
statusCode: 200,
|
||||
body: [],
|
||||
}).as('getEmptyFiles');
|
||||
cy.visit('/files');
|
||||
cy.wait('@getEmptyFiles');
|
||||
}).as("getEmptyFiles");
|
||||
cy.visit("/files");
|
||||
cy.wait("@getEmptyFiles");
|
||||
// Table should exist but have no file data
|
||||
cy.get('table').should('exist');
|
||||
cy.contains('sample-process.xes').should('not.exist');
|
||||
cy.get("table").should("exist");
|
||||
cy.contains("sample-process.xes").should("not.exist");
|
||||
});
|
||||
|
||||
it('account admin handles empty user list', () => {
|
||||
it("account admin handles empty user list", () => {
|
||||
loginWithFixtures();
|
||||
cy.intercept('GET', '/api/users', {
|
||||
cy.intercept("GET", "/api/users", {
|
||||
statusCode: 200,
|
||||
body: [],
|
||||
}).as('getEmptyUsers');
|
||||
cy.visit('/account-admin');
|
||||
cy.wait('@getEmptyUsers');
|
||||
}).as("getEmptyUsers");
|
||||
cy.visit("/account-admin");
|
||||
cy.wait("@getEmptyUsers");
|
||||
// Create New button should still work
|
||||
cy.get('#create_new_acct_btn').should('exist');
|
||||
cy.get("#create_new_acct_btn").should("exist");
|
||||
});
|
||||
});
|
||||
|
||||
describe('Authentication guard', () => {
|
||||
it('unauthenticated user is redirected to login', () => {
|
||||
describe("Authentication guard", () => {
|
||||
it("unauthenticated user is redirected to login", () => {
|
||||
// No loginWithFixtures - not logged in
|
||||
cy.visit('/files');
|
||||
cy.url().should('include', '/login');
|
||||
cy.visit("/files");
|
||||
cy.url().should("include", "/login");
|
||||
});
|
||||
|
||||
it('unauthenticated user cannot access account-admin', () => {
|
||||
cy.visit('/account-admin');
|
||||
cy.url().should('include', '/login');
|
||||
it("unauthenticated user cannot access account-admin", () => {
|
||||
cy.visit("/account-admin");
|
||||
cy.url().should("include", "/login");
|
||||
});
|
||||
|
||||
it('unauthenticated user cannot access my-account', () => {
|
||||
cy.visit('/my-account');
|
||||
cy.url().should('include', '/login');
|
||||
it("unauthenticated user cannot access my-account", () => {
|
||||
cy.visit("/my-account");
|
||||
cy.url().should("include", "/login");
|
||||
});
|
||||
});
|
||||
|
||||
describe('Login validation', () => {
|
||||
it('shows error on failed login', () => {
|
||||
cy.intercept('POST', '/api/oauth/token', {
|
||||
describe("Login validation", () => {
|
||||
it("shows error on failed login", () => {
|
||||
cy.intercept("POST", "/api/oauth/token", {
|
||||
statusCode: 401,
|
||||
body: { detail: 'Invalid credentials' },
|
||||
}).as('failedLogin');
|
||||
cy.visit('/login');
|
||||
cy.get('#account').type('wrong');
|
||||
cy.get('#password').type('wrong');
|
||||
cy.get('form').submit();
|
||||
cy.wait('@failedLogin');
|
||||
body: { detail: "Invalid credentials" },
|
||||
}).as("failedLogin");
|
||||
cy.visit("/login");
|
||||
cy.get("#account").type("wrong");
|
||||
cy.get("#password").type("wrong");
|
||||
cy.get("form").submit();
|
||||
cy.wait("@failedLogin");
|
||||
// Should stay on login page
|
||||
cy.url().should('include', '/login');
|
||||
cy.url().should("include", "/login");
|
||||
});
|
||||
});
|
||||
|
||||
describe('Account creation validation', () => {
|
||||
describe("Account creation validation", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/account-admin');
|
||||
cy.wait('@getUsers');
|
||||
cy.get('#create_new_acct_btn').click();
|
||||
cy.visit("/account-admin");
|
||||
cy.wait("@getUsers");
|
||||
cy.get("#create_new_acct_btn").click();
|
||||
});
|
||||
|
||||
it('confirm stays disabled with only account field filled', () => {
|
||||
cy.get('#input_account_field').type('newuser');
|
||||
cy.get('.confirm-btn').should('be.disabled');
|
||||
it("confirm stays disabled with only account field filled", () => {
|
||||
cy.get("#input_account_field").type("newuser");
|
||||
cy.get(".confirm-btn").should("be.disabled");
|
||||
});
|
||||
|
||||
it('confirm stays disabled with only name field filled', () => {
|
||||
cy.get('#input_name_field').type('New User');
|
||||
cy.get('.confirm-btn').should('be.disabled');
|
||||
it("confirm stays disabled with only name field filled", () => {
|
||||
cy.get("#input_name_field").type("New User");
|
||||
cy.get(".confirm-btn").should("be.disabled");
|
||||
});
|
||||
|
||||
it('confirm stays disabled with only password field filled', () => {
|
||||
cy.get('#input_first_pwd').type('password1234');
|
||||
cy.get('.confirm-btn').should('be.disabled');
|
||||
it("confirm stays disabled with only password field filled", () => {
|
||||
cy.get("#input_first_pwd").type("password1234");
|
||||
cy.get(".confirm-btn").should("be.disabled");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,72 +3,72 @@
|
||||
// Authors:
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../support/intercept';
|
||||
import { loginWithFixtures } from "../support/intercept";
|
||||
|
||||
describe('File Operations', () => {
|
||||
describe("File Operations", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/files');
|
||||
cy.wait('@getFiles');
|
||||
cy.visit("/files");
|
||||
cy.wait("@getFiles");
|
||||
});
|
||||
|
||||
it('file list table has sortable columns', () => {
|
||||
it("file list table has sortable columns", () => {
|
||||
// Check that table headers exist with expected columns
|
||||
cy.get('table').within(() => {
|
||||
cy.contains('th', 'Name').should('exist');
|
||||
cy.contains('th', 'Dependency').should('exist');
|
||||
cy.contains('th', 'File Type').should('exist');
|
||||
cy.contains('th', 'Owner').should('exist');
|
||||
cy.contains('th', 'Last Update').should('exist');
|
||||
cy.get("table").within(() => {
|
||||
cy.contains("th", "Name").should("exist");
|
||||
cy.contains("th", "Dependency").should("exist");
|
||||
cy.contains("th", "File Type").should("exist");
|
||||
cy.contains("th", "Owner").should("exist");
|
||||
cy.contains("th", "Last Update").should("exist");
|
||||
});
|
||||
});
|
||||
|
||||
it('clicking column header sorts the table', () => {
|
||||
it("clicking column header sorts the table", () => {
|
||||
// Click "Name" header to sort
|
||||
cy.contains('th', 'Name').click();
|
||||
cy.contains("th", "Name").click();
|
||||
// After sorting, table should still have data
|
||||
cy.get('table tbody tr').should('have.length.greaterThan', 0);
|
||||
cy.get("table tbody tr").should("have.length.greaterThan", 0);
|
||||
});
|
||||
|
||||
it('table rows show file data from fixture', () => {
|
||||
cy.get('table tbody').within(() => {
|
||||
cy.contains('sample-process.xes').should('exist');
|
||||
cy.contains('filtered-sample').should('exist');
|
||||
cy.contains('production-log.csv').should('exist');
|
||||
it("table rows show file data from fixture", () => {
|
||||
cy.get("table tbody").within(() => {
|
||||
cy.contains("sample-process.xes").should("exist");
|
||||
cy.contains("filtered-sample").should("exist");
|
||||
cy.contains("production-log.csv").should("exist");
|
||||
});
|
||||
});
|
||||
|
||||
it('table shows owner names', () => {
|
||||
cy.get('table tbody').within(() => {
|
||||
cy.contains('Test Admin').should('exist');
|
||||
cy.contains('Alice Wang').should('exist');
|
||||
it("table shows owner names", () => {
|
||||
cy.get("table tbody").within(() => {
|
||||
cy.contains("Test Admin").should("exist");
|
||||
cy.contains("Alice Wang").should("exist");
|
||||
});
|
||||
});
|
||||
|
||||
it('table shows file types', () => {
|
||||
cy.get('table tbody').within(() => {
|
||||
cy.contains('log').should('exist');
|
||||
it("table shows file types", () => {
|
||||
cy.get("table tbody").within(() => {
|
||||
cy.contains("log").should("exist");
|
||||
});
|
||||
});
|
||||
|
||||
it('right-click on file row shows context menu', () => {
|
||||
it("right-click on file row shows context menu", () => {
|
||||
// PrimeVue DataTable with contextmenu
|
||||
cy.get('table tbody tr').first().rightclick();
|
||||
cy.get("table tbody tr").first().rightclick();
|
||||
// Context menu behavior depends on implementation
|
||||
// Just verify the right-click doesn't break anything
|
||||
cy.get('table tbody tr').should('have.length.greaterThan', 0);
|
||||
cy.get("table tbody tr").should("have.length.greaterThan", 0);
|
||||
});
|
||||
|
||||
it('grid view shows file cards', () => {
|
||||
it("grid view shows file cards", () => {
|
||||
// Switch to grid view
|
||||
cy.get('svg').parent('li.cursor-pointer').last().click();
|
||||
cy.get("svg").parent("li.cursor-pointer").last().click();
|
||||
// Grid cards should be visible
|
||||
cy.get('li[title]').should('have.length.greaterThan', 0);
|
||||
cy.get("li[title]").should("have.length.greaterThan", 0);
|
||||
});
|
||||
|
||||
it('Import button opens upload modal', () => {
|
||||
cy.get('#import_btn').click();
|
||||
it("Import button opens upload modal", () => {
|
||||
cy.get("#import_btn").click();
|
||||
// Upload modal should appear
|
||||
cy.get('#import_btn').should('exist');
|
||||
cy.get("#import_btn").should("exist");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,58 +3,58 @@
|
||||
// Authors:
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../support/intercept';
|
||||
import { loginWithFixtures } from "../support/intercept";
|
||||
|
||||
describe('Files Page', () => {
|
||||
describe("Files Page", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/files');
|
||||
cy.visit("/files");
|
||||
});
|
||||
|
||||
it('displays the file list after login', () => {
|
||||
cy.wait('@getFiles');
|
||||
cy.contains('h2', 'All Files').should('exist');
|
||||
it("displays the file list after login", () => {
|
||||
cy.wait("@getFiles");
|
||||
cy.contains("h2", "All Files").should("exist");
|
||||
// Should display file names from fixture
|
||||
cy.contains('sample-process.xes').should('exist');
|
||||
cy.contains('filtered-sample').should('exist');
|
||||
cy.contains('production-log.csv').should('exist');
|
||||
cy.contains("sample-process.xes").should("exist");
|
||||
cy.contains("filtered-sample").should("exist");
|
||||
cy.contains("production-log.csv").should("exist");
|
||||
});
|
||||
|
||||
it('shows Recently Used section', () => {
|
||||
cy.wait('@getFiles');
|
||||
cy.contains('h2', 'Recently Used').should('exist');
|
||||
it("shows Recently Used section", () => {
|
||||
cy.wait("@getFiles");
|
||||
cy.contains("h2", "Recently Used").should("exist");
|
||||
});
|
||||
|
||||
it('switches to DISCOVER tab', () => {
|
||||
cy.wait('@getFiles');
|
||||
cy.contains('.nav-item', 'DISCOVER').click();
|
||||
it("switches to DISCOVER tab", () => {
|
||||
cy.wait("@getFiles");
|
||||
cy.contains(".nav-item", "DISCOVER").click();
|
||||
// DISCOVER tab shows filtered file types
|
||||
cy.contains('h2', 'All Files').should('exist');
|
||||
cy.contains("h2", "All Files").should("exist");
|
||||
});
|
||||
|
||||
it('switches to COMPARE tab and shows drag zones', () => {
|
||||
cy.wait('@getFiles');
|
||||
cy.contains('.nav-item', 'COMPARE').click();
|
||||
cy.contains('Performance Comparison').should('exist');
|
||||
cy.contains('Drag and drop a file here').should('exist');
|
||||
it("switches to COMPARE tab and shows drag zones", () => {
|
||||
cy.wait("@getFiles");
|
||||
cy.contains(".nav-item", "COMPARE").click();
|
||||
cy.contains("Performance Comparison").should("exist");
|
||||
cy.contains("Drag and drop a file here").should("exist");
|
||||
});
|
||||
|
||||
it('shows Import button on FILES tab', () => {
|
||||
cy.wait('@getFiles');
|
||||
cy.get('#import_btn').should('contain', 'Import');
|
||||
it("shows Import button on FILES tab", () => {
|
||||
cy.wait("@getFiles");
|
||||
cy.get("#import_btn").should("contain", "Import");
|
||||
});
|
||||
|
||||
it('can switch between list and grid view', () => {
|
||||
cy.wait('@getFiles');
|
||||
it("can switch between list and grid view", () => {
|
||||
cy.wait("@getFiles");
|
||||
// DataTable (list view) should be visible by default
|
||||
cy.get('table').should('exist');
|
||||
cy.get("table").should("exist");
|
||||
});
|
||||
|
||||
it('double-click file navigates to discover page', () => {
|
||||
cy.wait('@getFiles');
|
||||
it("double-click file navigates to discover page", () => {
|
||||
cy.wait("@getFiles");
|
||||
// Double-click the first file row in the table
|
||||
// The actual route depends on file type (log→map, log-check→conformance, etc.)
|
||||
cy.get('table tbody tr').first().dblclick();
|
||||
cy.url().should('include', '/discover');
|
||||
cy.get("table tbody tr").first().dblclick();
|
||||
cy.url().should("include", "/discover");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,47 +3,47 @@
|
||||
// Authors:
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../support/intercept';
|
||||
import { loginWithFixtures } from "../support/intercept";
|
||||
|
||||
describe('Files Page - COMPARE Tab', () => {
|
||||
describe("Files Page - COMPARE Tab", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/files');
|
||||
cy.wait('@getFiles');
|
||||
cy.visit("/files");
|
||||
cy.wait("@getFiles");
|
||||
// Switch to COMPARE tab
|
||||
cy.contains('li', 'COMPARE').click();
|
||||
cy.contains("li", "COMPARE").click();
|
||||
});
|
||||
|
||||
it('shows Performance Comparison heading', () => {
|
||||
cy.contains('h2', 'Performance Comparison').should('be.visible');
|
||||
it("shows Performance Comparison heading", () => {
|
||||
cy.contains("h2", "Performance Comparison").should("be.visible");
|
||||
});
|
||||
|
||||
it('shows two drag-and-drop slots', () => {
|
||||
cy.get('#primaryDragCard').should('exist');
|
||||
cy.get('#secondaryDragCard').should('exist');
|
||||
it("shows two drag-and-drop slots", () => {
|
||||
cy.get("#primaryDragCard").should("exist");
|
||||
cy.get("#secondaryDragCard").should("exist");
|
||||
});
|
||||
|
||||
it('drag slots show placeholder text', () => {
|
||||
cy.get('#primaryDragCard').should('contain', 'Drag and drop a file here');
|
||||
cy.get('#secondaryDragCard').should('contain', 'Drag and drop a file here');
|
||||
it("drag slots show placeholder text", () => {
|
||||
cy.get("#primaryDragCard").should("contain", "Drag and drop a file here");
|
||||
cy.get("#secondaryDragCard").should("contain", "Drag and drop a file here");
|
||||
});
|
||||
|
||||
it('Compare button is disabled when no files are dragged', () => {
|
||||
cy.contains('button', 'Compare').should('be.disabled');
|
||||
it("Compare button is disabled when no files are dragged", () => {
|
||||
cy.contains("button", "Compare").should("be.disabled");
|
||||
});
|
||||
|
||||
it('shows sorting dropdown', () => {
|
||||
cy.get('.p-select').should('exist');
|
||||
it("shows sorting dropdown", () => {
|
||||
cy.get(".p-select").should("exist");
|
||||
});
|
||||
|
||||
it('grid cards display file names', () => {
|
||||
cy.get('#compareGridCards').should('exist');
|
||||
cy.get('#compareGridCards li').should('have.length.greaterThan', 0);
|
||||
it("grid cards display file names", () => {
|
||||
cy.get("#compareGridCards").should("exist");
|
||||
cy.get("#compareGridCards li").should("have.length.greaterThan", 0);
|
||||
});
|
||||
|
||||
it('clicking sorting dropdown shows sort options', () => {
|
||||
cy.get('.p-select').click();
|
||||
cy.get('.p-select-list').should('be.visible');
|
||||
cy.contains('.p-select-option', 'By File Name').should('exist');
|
||||
it("clicking sorting dropdown shows sort options", () => {
|
||||
cy.get(".p-select").click();
|
||||
cy.get(".p-select-list").should("be.visible");
|
||||
cy.contains(".p-select-option", "By File Name").should("exist");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,72 +3,72 @@
|
||||
// Authors:
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../support/intercept';
|
||||
import { loginWithFixtures } from "../support/intercept";
|
||||
|
||||
describe('Files to Discover Entry Flow', () => {
|
||||
describe("Files to Discover Entry Flow", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
// Suppress Cytoscape rendering errors in headless mode
|
||||
cy.on('uncaught:exception', () => false);
|
||||
cy.visit('/files');
|
||||
cy.wait('@getFiles');
|
||||
cy.on("uncaught:exception", () => false);
|
||||
cy.visit("/files");
|
||||
cy.wait("@getFiles");
|
||||
});
|
||||
|
||||
describe('double-click table row to enter Discover', () => {
|
||||
it('double-click log file navigates to Map page', () => {
|
||||
describe("double-click table row to enter Discover", () => {
|
||||
it("double-click log file navigates to Map page", () => {
|
||||
// Target the Name column (has class .fileName) to avoid matching Dependency column
|
||||
cy.contains('td.fileName', 'sample-process.xes').parent('tr').dblclick();
|
||||
cy.url().should('include', '/discover/log/1/map');
|
||||
cy.wait('@getDiscover');
|
||||
cy.get('#cy').should('exist');
|
||||
cy.contains("td.fileName", "sample-process.xes").parent("tr").dblclick();
|
||||
cy.url().should("include", "/discover/log/1/map");
|
||||
cy.wait("@getDiscover");
|
||||
cy.get("#cy").should("exist");
|
||||
});
|
||||
|
||||
it('double-click filter file navigates to Map page', () => {
|
||||
cy.contains('td.fileName', 'filtered-sample').parent('tr').dblclick();
|
||||
cy.url().should('include', '/discover/filter/10/map');
|
||||
cy.wait('@getFilterDiscover');
|
||||
cy.get('#cy').should('exist');
|
||||
it("double-click filter file navigates to Map page", () => {
|
||||
cy.contains("td.fileName", "filtered-sample").parent("tr").dblclick();
|
||||
cy.url().should("include", "/discover/filter/10/map");
|
||||
cy.wait("@getFilterDiscover");
|
||||
cy.get("#cy").should("exist");
|
||||
});
|
||||
});
|
||||
|
||||
describe('double-click grid card to enter Discover', () => {
|
||||
describe("double-click grid card to enter Discover", () => {
|
||||
beforeEach(() => {
|
||||
// Switch to grid view
|
||||
cy.get('svg').parent('li.cursor-pointer').last().click();
|
||||
cy.get("svg").parent("li.cursor-pointer").last().click();
|
||||
});
|
||||
|
||||
it('double-click log file grid card navigates to Map page', () => {
|
||||
it("double-click log file grid card navigates to Map page", () => {
|
||||
// Use last() to target the All Files grid section (not Recently Used)
|
||||
cy.get('li[title="sample-process.xes"]').last().dblclick();
|
||||
cy.url().should('include', '/discover/log/1/map');
|
||||
cy.wait('@getDiscover');
|
||||
cy.get('#cy').should('exist');
|
||||
cy.url().should("include", "/discover/log/1/map");
|
||||
cy.wait("@getDiscover");
|
||||
cy.get("#cy").should("exist");
|
||||
});
|
||||
});
|
||||
|
||||
describe('DISCOVER tab filters files', () => {
|
||||
it('clicking DISCOVER tab shows only Log, Filter, and Rule files', () => {
|
||||
cy.get('.nav-item').contains('DISCOVER').click();
|
||||
cy.contains('td.fileName', 'sample-process.xes').should('exist');
|
||||
cy.contains('td.fileName', 'filtered-sample').should('exist');
|
||||
cy.contains('td.fileName', 'conformance-check-1').should('exist');
|
||||
describe("DISCOVER tab filters files", () => {
|
||||
it("clicking DISCOVER tab shows only Log, Filter, and Rule files", () => {
|
||||
cy.get(".nav-item").contains("DISCOVER").click();
|
||||
cy.contains("td.fileName", "sample-process.xes").should("exist");
|
||||
cy.contains("td.fileName", "filtered-sample").should("exist");
|
||||
cy.contains("td.fileName", "conformance-check-1").should("exist");
|
||||
});
|
||||
});
|
||||
|
||||
describe('Navbar state after entering Discover', () => {
|
||||
it('shows DISCOVER heading and tabs after entering from Files', () => {
|
||||
cy.contains('td.fileName', 'sample-process.xes').parent('tr').dblclick();
|
||||
cy.url().should('include', '/discover/');
|
||||
cy.get('#nav_bar').contains('DISCOVER').should('be.visible');
|
||||
cy.get('.nav-item').contains('MAP').should('exist');
|
||||
cy.get('.nav-item').contains('CONFORMANCE').should('exist');
|
||||
cy.get('.nav-item').contains('PERFORMANCE').should('exist');
|
||||
describe("Navbar state after entering Discover", () => {
|
||||
it("shows DISCOVER heading and tabs after entering from Files", () => {
|
||||
cy.contains("td.fileName", "sample-process.xes").parent("tr").dblclick();
|
||||
cy.url().should("include", "/discover/");
|
||||
cy.get("#nav_bar").contains("DISCOVER").should("be.visible");
|
||||
cy.get(".nav-item").contains("MAP").should("exist");
|
||||
cy.get(".nav-item").contains("CONFORMANCE").should("exist");
|
||||
cy.get(".nav-item").contains("PERFORMANCE").should("exist");
|
||||
});
|
||||
|
||||
it('shows back arrow pointing to /files', () => {
|
||||
cy.contains('td.fileName', 'sample-process.xes').parent('tr').dblclick();
|
||||
cy.url().should('include', '/discover/');
|
||||
cy.get('#backPage').should('have.attr', 'href', '/files');
|
||||
it("shows back arrow pointing to /files", () => {
|
||||
cy.contains("td.fileName", "sample-process.xes").parent("tr").dblclick();
|
||||
cy.url().should("include", "/discover/");
|
||||
cy.get("#backPage").should("have.attr", "href", "/files");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,74 +3,74 @@
|
||||
// Authors:
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { setupApiIntercepts, loginWithFixtures } from '../support/intercept';
|
||||
import { setupApiIntercepts, loginWithFixtures } from "../support/intercept";
|
||||
|
||||
describe('Login Flow', () => {
|
||||
describe("Login Flow", () => {
|
||||
beforeEach(() => {
|
||||
setupApiIntercepts();
|
||||
});
|
||||
|
||||
it('renders the login form', () => {
|
||||
cy.visit('/login');
|
||||
cy.get('h2').should('contain', 'LOGIN');
|
||||
cy.get('#account').should('exist');
|
||||
cy.get('#password').should('exist');
|
||||
cy.get('#login_btn_main_btn').should('be.disabled');
|
||||
it("renders the login form", () => {
|
||||
cy.visit("/login");
|
||||
cy.get("h2").should("contain", "LOGIN");
|
||||
cy.get("#account").should("exist");
|
||||
cy.get("#password").should("exist");
|
||||
cy.get("#login_btn_main_btn").should("be.disabled");
|
||||
});
|
||||
|
||||
it('login button is disabled when fields are empty', () => {
|
||||
cy.visit('/login');
|
||||
cy.get('#login_btn_main_btn').should('be.disabled');
|
||||
it("login button is disabled when fields are empty", () => {
|
||||
cy.visit("/login");
|
||||
cy.get("#login_btn_main_btn").should("be.disabled");
|
||||
|
||||
// Only username filled — still disabled
|
||||
cy.get('#account').type('testuser');
|
||||
cy.get('#login_btn_main_btn').should('be.disabled');
|
||||
cy.get("#account").type("testuser");
|
||||
cy.get("#login_btn_main_btn").should("be.disabled");
|
||||
});
|
||||
|
||||
it('login button enables when both fields are filled', () => {
|
||||
cy.visit('/login');
|
||||
cy.get('#account').type('testadmin');
|
||||
cy.get('#password').type('password123');
|
||||
cy.get('#login_btn_main_btn').should('not.be.disabled');
|
||||
it("login button enables when both fields are filled", () => {
|
||||
cy.visit("/login");
|
||||
cy.get("#account").type("testadmin");
|
||||
cy.get("#password").type("password123");
|
||||
cy.get("#login_btn_main_btn").should("not.be.disabled");
|
||||
});
|
||||
|
||||
it('successful login redirects to /files', () => {
|
||||
cy.visit('/login');
|
||||
cy.get('#account').type('testadmin');
|
||||
cy.get('#password').type('password123');
|
||||
cy.get('#login_btn_main_btn').click();
|
||||
it("successful login redirects to /files", () => {
|
||||
cy.visit("/login");
|
||||
cy.get("#account").type("testadmin");
|
||||
cy.get("#password").type("password123");
|
||||
cy.get("#login_btn_main_btn").click();
|
||||
|
||||
cy.wait('@postToken');
|
||||
cy.url().should('include', '/files');
|
||||
cy.wait("@postToken");
|
||||
cy.url().should("include", "/files");
|
||||
});
|
||||
|
||||
it('failed login shows error message', () => {
|
||||
it("failed login shows error message", () => {
|
||||
// Override the token intercept to return 401
|
||||
cy.intercept('POST', '/api/oauth/token', {
|
||||
cy.intercept("POST", "/api/oauth/token", {
|
||||
statusCode: 401,
|
||||
body: { detail: 'Incorrect username or password' },
|
||||
}).as('postTokenFail');
|
||||
body: { detail: "Incorrect username or password" },
|
||||
}).as("postTokenFail");
|
||||
|
||||
cy.visit('/login');
|
||||
cy.get('#account').type('wronguser');
|
||||
cy.get('#password').type('wrongpass');
|
||||
cy.get('#login_btn_main_btn').click();
|
||||
cy.visit("/login");
|
||||
cy.get("#account").type("wronguser");
|
||||
cy.get("#password").type("wrongpass");
|
||||
cy.get("#login_btn_main_btn").click();
|
||||
|
||||
cy.wait('@postTokenFail');
|
||||
cy.contains('Incorrect account or password').should('be.visible');
|
||||
cy.wait("@postTokenFail");
|
||||
cy.contains("Incorrect account or password").should("be.visible");
|
||||
});
|
||||
|
||||
it('toggles password visibility', () => {
|
||||
cy.visit('/login');
|
||||
cy.get('#password').type('secret123');
|
||||
cy.get('#password').should('have.attr', 'type', 'password');
|
||||
it("toggles password visibility", () => {
|
||||
cy.visit("/login");
|
||||
cy.get("#password").type("secret123");
|
||||
cy.get("#password").should("have.attr", "type", "password");
|
||||
|
||||
// Click the eye icon to show password
|
||||
cy.get('label[for="passwordt"] span.cursor-pointer').click();
|
||||
cy.get('#password').should('have.attr', 'type', 'text');
|
||||
cy.get("#password").should("have.attr", "type", "text");
|
||||
|
||||
// Click again to hide
|
||||
cy.get('label[for="passwordt"] span.cursor-pointer').click();
|
||||
cy.get('#password').should('have.attr', 'type', 'password');
|
||||
cy.get("#password").should("have.attr", "type", "password");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,65 +3,65 @@
|
||||
// Authors:
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../support/intercept';
|
||||
import { loginWithFixtures } from "../support/intercept";
|
||||
|
||||
describe('Logout Flow', () => {
|
||||
describe("Logout Flow", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
});
|
||||
|
||||
it('shows account menu when head icon is clicked', () => {
|
||||
cy.visit('/files');
|
||||
cy.wait('@getFiles');
|
||||
it("shows account menu when head icon is clicked", () => {
|
||||
cy.visit("/files");
|
||||
cy.wait("@getFiles");
|
||||
|
||||
// Click the head icon to open account menu
|
||||
cy.get('#acct_mgmt_button').click();
|
||||
cy.get('#account_menu').should('be.visible');
|
||||
cy.get('#greeting').should('contain', 'Test Admin');
|
||||
cy.get("#acct_mgmt_button").click();
|
||||
cy.get("#account_menu").should("be.visible");
|
||||
cy.get("#greeting").should("contain", "Test Admin");
|
||||
});
|
||||
|
||||
it('account menu shows admin management link for admin user', () => {
|
||||
cy.visit('/files');
|
||||
cy.wait('@getFiles');
|
||||
it("account menu shows admin management link for admin user", () => {
|
||||
cy.visit("/files");
|
||||
cy.wait("@getFiles");
|
||||
|
||||
cy.get('#acct_mgmt_button').click();
|
||||
cy.get('#account_menu').should('be.visible');
|
||||
cy.get("#acct_mgmt_button").click();
|
||||
cy.get("#account_menu").should("be.visible");
|
||||
// Admin user should see account management option
|
||||
cy.get('#btn_acct_mgmt').should('exist');
|
||||
cy.get("#btn_acct_mgmt").should("exist");
|
||||
});
|
||||
|
||||
it('account menu has logout button', () => {
|
||||
cy.visit('/files');
|
||||
cy.wait('@getFiles');
|
||||
it("account menu has logout button", () => {
|
||||
cy.visit("/files");
|
||||
cy.wait("@getFiles");
|
||||
|
||||
cy.get('#acct_mgmt_button').click();
|
||||
cy.get('#btn_logout_in_menu').should('exist');
|
||||
cy.get("#acct_mgmt_button").click();
|
||||
cy.get("#btn_logout_in_menu").should("exist");
|
||||
});
|
||||
|
||||
it('clicking My Account navigates to /my-account', () => {
|
||||
cy.visit('/files');
|
||||
cy.wait('@getFiles');
|
||||
it("clicking My Account navigates to /my-account", () => {
|
||||
cy.visit("/files");
|
||||
cy.wait("@getFiles");
|
||||
|
||||
cy.get('#acct_mgmt_button').click();
|
||||
cy.get('#btn_mang_ur_acct').click();
|
||||
cy.url().should('include', '/my-account');
|
||||
cy.get("#acct_mgmt_button").click();
|
||||
cy.get("#btn_mang_ur_acct").click();
|
||||
cy.url().should("include", "/my-account");
|
||||
});
|
||||
|
||||
it('clicking Account Management navigates to /account-admin', () => {
|
||||
cy.visit('/files');
|
||||
cy.wait('@getFiles');
|
||||
it("clicking Account Management navigates to /account-admin", () => {
|
||||
cy.visit("/files");
|
||||
cy.wait("@getFiles");
|
||||
|
||||
cy.get('#acct_mgmt_button').click();
|
||||
cy.get('#btn_acct_mgmt').click();
|
||||
cy.url().should('include', '/account-admin');
|
||||
cy.get("#acct_mgmt_button").click();
|
||||
cy.get("#btn_acct_mgmt").click();
|
||||
cy.url().should("include", "/account-admin");
|
||||
});
|
||||
|
||||
it('logout redirects to login page', () => {
|
||||
cy.visit('/files');
|
||||
cy.wait('@getFiles');
|
||||
it("logout redirects to login page", () => {
|
||||
cy.visit("/files");
|
||||
cy.wait("@getFiles");
|
||||
|
||||
cy.get('#acct_mgmt_button').click();
|
||||
cy.get('#btn_logout_in_menu').click();
|
||||
cy.url().should('include', '/login');
|
||||
cy.get("#acct_mgmt_button").click();
|
||||
cy.get("#btn_logout_in_menu").click();
|
||||
cy.url().should("include", "/login");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,71 +3,71 @@
|
||||
// Authors:
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../support/intercept';
|
||||
import { loginWithFixtures } from "../support/intercept";
|
||||
|
||||
describe('My Account Page', () => {
|
||||
describe("My Account Page", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/my-account');
|
||||
cy.wait('@getUserDetail');
|
||||
cy.visit("/my-account");
|
||||
cy.wait("@getUserDetail");
|
||||
});
|
||||
|
||||
it('displays user name heading', () => {
|
||||
cy.get('#general_acct_info_user_name').should('exist');
|
||||
cy.get('#general_acct_info_user_name').should('contain', 'Test Admin');
|
||||
it("displays user name heading", () => {
|
||||
cy.get("#general_acct_info_user_name").should("exist");
|
||||
cy.get("#general_acct_info_user_name").should("contain", "Test Admin");
|
||||
});
|
||||
|
||||
it('shows Admin badge for admin user', () => {
|
||||
cy.contains('Admin').should('exist');
|
||||
it("shows Admin badge for admin user", () => {
|
||||
cy.contains("Admin").should("exist");
|
||||
});
|
||||
|
||||
it('shows visit count info', () => {
|
||||
cy.get('#general_account_visit_info').should('exist');
|
||||
cy.get('#general_account_visit_info').should('contain', 'Total visits');
|
||||
it("shows visit count info", () => {
|
||||
cy.get("#general_account_visit_info").should("exist");
|
||||
cy.get("#general_account_visit_info").should("contain", "Total visits");
|
||||
});
|
||||
|
||||
it('displays account username (read-only)', () => {
|
||||
cy.contains('Test Admin').should('exist');
|
||||
it("displays account username (read-only)", () => {
|
||||
cy.contains("Test Admin").should("exist");
|
||||
});
|
||||
|
||||
it('shows Edit button for name field', () => {
|
||||
cy.contains('button', 'Edit').should('exist');
|
||||
it("shows Edit button for name field", () => {
|
||||
cy.contains("button", "Edit").should("exist");
|
||||
});
|
||||
|
||||
it('clicking Edit shows input field and Save/Cancel buttons', () => {
|
||||
cy.contains('button', 'Edit').first().click();
|
||||
cy.get('#input_name_field').should('exist');
|
||||
cy.contains('button', 'Save').should('exist');
|
||||
cy.contains('button', 'Cancel').should('exist');
|
||||
it("clicking Edit shows input field and Save/Cancel buttons", () => {
|
||||
cy.contains("button", "Edit").first().click();
|
||||
cy.get("#input_name_field").should("exist");
|
||||
cy.contains("button", "Save").should("exist");
|
||||
cy.contains("button", "Cancel").should("exist");
|
||||
});
|
||||
|
||||
it('clicking Cancel reverts name field to read-only', () => {
|
||||
cy.contains('button', 'Edit').first().click();
|
||||
cy.get('#input_name_field').should('exist');
|
||||
cy.contains('button', 'Cancel').click();
|
||||
cy.get('#input_name_field').should('not.exist');
|
||||
it("clicking Cancel reverts name field to read-only", () => {
|
||||
cy.contains("button", "Edit").first().click();
|
||||
cy.get("#input_name_field").should("exist");
|
||||
cy.contains("button", "Cancel").click();
|
||||
cy.get("#input_name_field").should("not.exist");
|
||||
});
|
||||
|
||||
it('shows Reset button for password field', () => {
|
||||
cy.contains('button', 'Reset').should('exist');
|
||||
it("shows Reset button for password field", () => {
|
||||
cy.contains("button", "Reset").should("exist");
|
||||
});
|
||||
|
||||
it('clicking Reset shows password input and Save/Cancel', () => {
|
||||
cy.contains('button', 'Reset').click();
|
||||
cy.get('input[type="password"]').should('exist');
|
||||
cy.contains('button', 'Save').should('exist');
|
||||
cy.contains('button', 'Cancel').should('exist');
|
||||
it("clicking Reset shows password input and Save/Cancel", () => {
|
||||
cy.contains("button", "Reset").click();
|
||||
cy.get('input[type="password"]').should("exist");
|
||||
cy.contains("button", "Save").should("exist");
|
||||
cy.contains("button", "Cancel").should("exist");
|
||||
});
|
||||
|
||||
it('clicking Cancel on password field hides the input', () => {
|
||||
cy.contains('button', 'Reset').click();
|
||||
cy.get('input[type="password"]').should('exist');
|
||||
it("clicking Cancel on password field hides the input", () => {
|
||||
cy.contains("button", "Reset").click();
|
||||
cy.get('input[type="password"]').should("exist");
|
||||
// The Cancel button for password is the second one
|
||||
cy.get('.cancel-btn').click();
|
||||
cy.get('input[type="password"]').should('not.exist');
|
||||
cy.get(".cancel-btn").click();
|
||||
cy.get('input[type="password"]').should("not.exist");
|
||||
});
|
||||
|
||||
it('shows Session section', () => {
|
||||
cy.contains('Session').should('exist');
|
||||
it("shows Session section", () => {
|
||||
cy.contains("Session").should("exist");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,60 +3,60 @@
|
||||
// Authors:
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures, setupApiIntercepts } from '../support/intercept';
|
||||
import { loginWithFixtures, setupApiIntercepts } from "../support/intercept";
|
||||
|
||||
describe('Navigation and Routing', () => {
|
||||
it('redirects / to /files when logged in', () => {
|
||||
describe("Navigation and Routing", () => {
|
||||
it("redirects / to /files when logged in", () => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/');
|
||||
cy.url().should('include', '/files');
|
||||
cy.visit("/");
|
||||
cy.url().should("include", "/files");
|
||||
});
|
||||
|
||||
it('shows 404 page for unknown routes', () => {
|
||||
it("shows 404 page for unknown routes", () => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/nonexistent-page');
|
||||
cy.contains('404').should('exist');
|
||||
cy.visit("/nonexistent-page");
|
||||
cy.contains("404").should("exist");
|
||||
});
|
||||
|
||||
it('navbar shows correct view name', () => {
|
||||
it("navbar shows correct view name", () => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/files');
|
||||
cy.wait('@getFiles');
|
||||
cy.get('#nav_bar').should('exist');
|
||||
cy.get('#nav_bar h2').should('contain', 'FILES');
|
||||
cy.visit("/files");
|
||||
cy.wait("@getFiles");
|
||||
cy.get("#nav_bar").should("exist");
|
||||
cy.get("#nav_bar h2").should("contain", "FILES");
|
||||
});
|
||||
|
||||
it('navbar shows back arrow on non-files pages', () => {
|
||||
it("navbar shows back arrow on non-files pages", () => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/discover/log/1/map');
|
||||
cy.visit("/discover/log/1/map");
|
||||
// Back arrow should be visible on discover pages
|
||||
cy.get('#backPage').should('exist');
|
||||
cy.get("#backPage").should("exist");
|
||||
});
|
||||
|
||||
it('navbar tabs are clickable on discover page', () => {
|
||||
it("navbar tabs are clickable on discover page", () => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/discover/log/1/map');
|
||||
cy.visit("/discover/log/1/map");
|
||||
// Discover navbar should show MAP, CONFORMANCE, PERFORMANCE tabs
|
||||
cy.contains('.nav-item', 'MAP').should('exist');
|
||||
cy.contains('.nav-item', 'CONFORMANCE').should('exist');
|
||||
cy.contains('.nav-item', 'PERFORMANCE').should('exist');
|
||||
cy.contains(".nav-item", "MAP").should("exist");
|
||||
cy.contains(".nav-item", "CONFORMANCE").should("exist");
|
||||
cy.contains(".nav-item", "PERFORMANCE").should("exist");
|
||||
|
||||
// Click CONFORMANCE tab
|
||||
cy.contains('.nav-item', 'CONFORMANCE').click();
|
||||
cy.url().should('include', '/conformance');
|
||||
cy.contains(".nav-item", "CONFORMANCE").click();
|
||||
cy.url().should("include", "/conformance");
|
||||
|
||||
// Click PERFORMANCE tab
|
||||
cy.contains('.nav-item', 'PERFORMANCE').click();
|
||||
cy.url().should('include', '/performance');
|
||||
cy.contains(".nav-item", "PERFORMANCE").click();
|
||||
cy.url().should("include", "/performance");
|
||||
|
||||
// Click MAP tab to go back
|
||||
cy.contains('.nav-item', 'MAP').click();
|
||||
cy.url().should('include', '/map');
|
||||
cy.contains(".nav-item", "MAP").click();
|
||||
cy.url().should("include", "/map");
|
||||
});
|
||||
|
||||
it('login page is accessible at /login', () => {
|
||||
it("login page is accessible at /login", () => {
|
||||
setupApiIntercepts();
|
||||
cy.visit('/login');
|
||||
cy.get('h2').should('contain', 'LOGIN');
|
||||
cy.visit("/login");
|
||||
cy.get("h2").should("contain", "LOGIN");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,36 +3,38 @@
|
||||
// Authors:
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../support/intercept';
|
||||
import { loginWithFixtures } from "../support/intercept";
|
||||
|
||||
describe('404 Not Found Page', () => {
|
||||
describe("404 Not Found Page", () => {
|
||||
beforeEach(() => {
|
||||
// Suppress Navbar error on 404 page (route.matched[1] is null)
|
||||
cy.on('uncaught:exception', () => false);
|
||||
cy.on("uncaught:exception", () => false);
|
||||
});
|
||||
|
||||
it('displays 404 page for non-existent route', () => {
|
||||
it("displays 404 page for non-existent route", () => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/this-page-does-not-exist');
|
||||
cy.contains('404').should('be.visible');
|
||||
cy.contains('The page you are looking for does not exist.').should('be.visible');
|
||||
cy.visit("/this-page-does-not-exist");
|
||||
cy.contains("404").should("be.visible");
|
||||
cy.contains("The page you are looking for does not exist.").should(
|
||||
"be.visible",
|
||||
);
|
||||
});
|
||||
|
||||
it('has a link back to Files page', () => {
|
||||
it("has a link back to Files page", () => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/some/random/path');
|
||||
cy.contains('a', 'Go to Files')
|
||||
.should('be.visible')
|
||||
.should('have.attr', 'href', '/files');
|
||||
cy.visit("/some/random/path");
|
||||
cy.contains("a", "Go to Files")
|
||||
.should("be.visible")
|
||||
.should("have.attr", "href", "/files");
|
||||
});
|
||||
|
||||
it('displays 404 for unauthenticated user on invalid route', () => {
|
||||
cy.visit('/not-a-real-page');
|
||||
it("displays 404 for unauthenticated user on invalid route", () => {
|
||||
cy.visit("/not-a-real-page");
|
||||
cy.url().then((url) => {
|
||||
if (url.includes('/login')) {
|
||||
cy.url().should('include', '/login');
|
||||
if (url.includes("/login")) {
|
||||
cy.url().should("include", "/login");
|
||||
} else {
|
||||
cy.contains('404').should('be.visible');
|
||||
cy.contains("404").should("be.visible");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,35 +4,35 @@
|
||||
// cindy.chang@dsp.im (Cindy Chang), 2024/06/03
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../support/intercept';
|
||||
import { loginWithFixtures } from "../support/intercept";
|
||||
|
||||
describe('Discover page navigation tabs', () => {
|
||||
describe("Discover page navigation tabs", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/files');
|
||||
cy.wait('@getFiles');
|
||||
cy.visit("/files");
|
||||
cy.wait("@getFiles");
|
||||
});
|
||||
|
||||
it('Double-clicking a log file enters the MAP page.', () => {
|
||||
cy.contains('td.fileName', 'sample-process.xes').dblclick();
|
||||
cy.url().should('include', 'map');
|
||||
it("Double-clicking a log file enters the MAP page.", () => {
|
||||
cy.contains("td.fileName", "sample-process.xes").dblclick();
|
||||
cy.url().should("include", "map");
|
||||
// MAP tab should exist in the navbar
|
||||
cy.contains('.nav-item', 'MAP').should('exist');
|
||||
cy.contains(".nav-item", "MAP").should("exist");
|
||||
});
|
||||
|
||||
it('Clicking CONFORMANCE tab switches active page.', () => {
|
||||
cy.contains('td.fileName', 'sample-process.xes').dblclick();
|
||||
cy.url().should('include', 'map');
|
||||
cy.contains('.nav-item', 'CONFORMANCE').click();
|
||||
cy.url().should('include', 'conformance');
|
||||
cy.contains('.nav-item', 'CONFORMANCE').should('have.class', 'active');
|
||||
it("Clicking CONFORMANCE tab switches active page.", () => {
|
||||
cy.contains("td.fileName", "sample-process.xes").dblclick();
|
||||
cy.url().should("include", "map");
|
||||
cy.contains(".nav-item", "CONFORMANCE").click();
|
||||
cy.url().should("include", "conformance");
|
||||
cy.contains(".nav-item", "CONFORMANCE").should("have.class", "active");
|
||||
});
|
||||
|
||||
it('Clicking PERFORMANCE tab switches active page.', () => {
|
||||
cy.contains('td.fileName', 'sample-process.xes').dblclick();
|
||||
cy.url().should('include', 'map');
|
||||
cy.contains('.nav-item', 'PERFORMANCE').click();
|
||||
cy.url().should('include', 'performance');
|
||||
cy.contains('.nav-item', 'PERFORMANCE').should('have.class', 'active');
|
||||
it("Clicking PERFORMANCE tab switches active page.", () => {
|
||||
cy.contains("td.fileName", "sample-process.xes").dblclick();
|
||||
cy.url().should("include", "map");
|
||||
cy.contains(".nav-item", "PERFORMANCE").click();
|
||||
cy.url().should("include", "performance");
|
||||
cy.contains(".nav-item", "PERFORMANCE").should("have.class", "active");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,54 +4,55 @@
|
||||
// cindy.chang@dsp.im (Cindy Chang), 2024/06/11
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { setupApiIntercepts } from '../support/intercept';
|
||||
import { setupApiIntercepts } from "../support/intercept";
|
||||
|
||||
describe('Paste URL login redirect', () => {
|
||||
it('After login with return-to param, redirects to the remembered page', () => {
|
||||
describe("Paste URL login redirect", () => {
|
||||
it("After login with return-to param, redirects to the remembered page", () => {
|
||||
setupApiIntercepts();
|
||||
|
||||
// Visit login page with a return-to query param (base64-encoded URL)
|
||||
const targetUrl = 'http://localhost:4173/discover/conformance/log/1/conformance';
|
||||
const targetUrl =
|
||||
"http://localhost:4173/discover/conformance/log/1/conformance";
|
||||
const encodedUrl = btoa(targetUrl);
|
||||
cy.visit(`/login?return-to=${encodedUrl}`);
|
||||
|
||||
// Fill in login form
|
||||
cy.get('#account').type('testadmin');
|
||||
cy.get('#password').type('password123');
|
||||
cy.get('form').submit();
|
||||
cy.wait('@postToken');
|
||||
cy.get("#account").type("testadmin");
|
||||
cy.get("#password").type("password123");
|
||||
cy.get("form").submit();
|
||||
cy.wait("@postToken");
|
||||
|
||||
// After login, the app should attempt to redirect to the return-to URL.
|
||||
// Since window.location.href is used (not router.push), we verify the
|
||||
// login form disappears and the token cookie is set.
|
||||
cy.getCookie('luciaToken').should('exist');
|
||||
cy.getCookie("luciaToken").should("exist");
|
||||
});
|
||||
|
||||
it('Login without return-to param redirects to /files', () => {
|
||||
it("Login without return-to param redirects to /files", () => {
|
||||
setupApiIntercepts();
|
||||
cy.visit('/login');
|
||||
cy.visit("/login");
|
||||
|
||||
cy.get('#account').type('testadmin');
|
||||
cy.get('#password').type('password123');
|
||||
cy.get('form').submit();
|
||||
cy.wait('@postToken');
|
||||
cy.get("#account").type("testadmin");
|
||||
cy.get("#password").type("password123");
|
||||
cy.get("form").submit();
|
||||
cy.wait("@postToken");
|
||||
|
||||
cy.url().should('include', '/files');
|
||||
cy.url().should("include", "/files");
|
||||
});
|
||||
|
||||
it('Unauthenticated user cannot access inner pages', () => {
|
||||
it("Unauthenticated user cannot access inner pages", () => {
|
||||
setupApiIntercepts();
|
||||
// Override my-account to return 401 (simulate logged-out state)
|
||||
cy.intercept('GET', '/api/my-account', {
|
||||
cy.intercept("GET", "/api/my-account", {
|
||||
statusCode: 401,
|
||||
body: { detail: 'Not authenticated' },
|
||||
}).as('getMyAccountUnauth');
|
||||
body: { detail: "Not authenticated" },
|
||||
}).as("getMyAccountUnauth");
|
||||
|
||||
cy.visit('/files');
|
||||
cy.visit("/files");
|
||||
|
||||
// Should be redirected to login page
|
||||
cy.url().should('include', '/login');
|
||||
cy.get('#account').should('exist');
|
||||
cy.get('#password').should('exist');
|
||||
cy.url().should("include", "/login");
|
||||
cy.get("#account").should("exist");
|
||||
cy.get("#password").should("exist");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,113 +3,113 @@
|
||||
// Authors:
|
||||
// imacat.yang@dsp.im (imacat), 2026/03/05
|
||||
|
||||
import { loginWithFixtures } from '../support/intercept';
|
||||
import { loginWithFixtures } from "../support/intercept";
|
||||
|
||||
describe('SweetAlert2 Modals', () => {
|
||||
describe('File Context Menu - Rename', () => {
|
||||
describe("SweetAlert2 Modals", () => {
|
||||
describe("File Context Menu - Rename", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/files');
|
||||
cy.wait('@getFiles');
|
||||
cy.visit("/files");
|
||||
cy.wait("@getFiles");
|
||||
});
|
||||
|
||||
it('right-click on table row shows context menu with Rename', () => {
|
||||
cy.get('table tbody tr').first().rightclick();
|
||||
cy.contains('Rename').should('be.visible');
|
||||
it("right-click on table row shows context menu with Rename", () => {
|
||||
cy.get("table tbody tr").first().rightclick();
|
||||
cy.contains("Rename").should("be.visible");
|
||||
});
|
||||
|
||||
it('right-click context menu shows Download option', () => {
|
||||
cy.get('table tbody tr').first().rightclick();
|
||||
cy.contains('Download').should('be.visible');
|
||||
it("right-click context menu shows Download option", () => {
|
||||
cy.get("table tbody tr").first().rightclick();
|
||||
cy.contains("Download").should("be.visible");
|
||||
});
|
||||
|
||||
it('right-click context menu shows Delete option', () => {
|
||||
cy.get('table tbody tr').first().rightclick();
|
||||
cy.contains('Delete').should('be.visible');
|
||||
it("right-click context menu shows Delete option", () => {
|
||||
cy.get("table tbody tr").first().rightclick();
|
||||
cy.contains("Delete").should("be.visible");
|
||||
});
|
||||
|
||||
it('clicking Rename opens SweetAlert rename dialog', () => {
|
||||
cy.get('table tbody tr').first().rightclick();
|
||||
cy.contains('Rename').click();
|
||||
it("clicking Rename opens SweetAlert rename dialog", () => {
|
||||
cy.get("table tbody tr").first().rightclick();
|
||||
cy.contains("Rename").click();
|
||||
// SweetAlert popup should appear with RENAME title
|
||||
cy.get('.swal2-popup').should('be.visible');
|
||||
cy.get('.swal2-title').should('contain', 'RENAME');
|
||||
cy.get('.swal2-input').should('exist');
|
||||
cy.get(".swal2-popup").should("be.visible");
|
||||
cy.get(".swal2-title").should("contain", "RENAME");
|
||||
cy.get(".swal2-input").should("exist");
|
||||
});
|
||||
|
||||
it('rename dialog has pre-filled file name', () => {
|
||||
cy.get('table tbody tr').first().rightclick();
|
||||
cy.contains('Rename').click();
|
||||
cy.get('.swal2-input').should('not.have.value', '');
|
||||
it("rename dialog has pre-filled file name", () => {
|
||||
cy.get("table tbody tr").first().rightclick();
|
||||
cy.contains("Rename").click();
|
||||
cy.get(".swal2-input").should("not.have.value", "");
|
||||
});
|
||||
|
||||
it('rename dialog can be cancelled', () => {
|
||||
cy.get('table tbody tr').first().rightclick();
|
||||
cy.contains('Rename').click();
|
||||
cy.get('.swal2-popup').should('be.visible');
|
||||
cy.get('.swal2-cancel').click();
|
||||
cy.get('.swal2-popup').should('not.exist');
|
||||
it("rename dialog can be cancelled", () => {
|
||||
cy.get("table tbody tr").first().rightclick();
|
||||
cy.contains("Rename").click();
|
||||
cy.get(".swal2-popup").should("be.visible");
|
||||
cy.get(".swal2-cancel").click();
|
||||
cy.get(".swal2-popup").should("not.exist");
|
||||
});
|
||||
|
||||
it('clicking Delete opens SweetAlert delete confirmation', () => {
|
||||
cy.get('table tbody tr').first().rightclick();
|
||||
cy.contains('Delete').click();
|
||||
it("clicking Delete opens SweetAlert delete confirmation", () => {
|
||||
cy.get("table tbody tr").first().rightclick();
|
||||
cy.contains("Delete").click();
|
||||
// SweetAlert popup should appear with CONFIRM DELETION
|
||||
cy.get('.swal2-popup').should('be.visible');
|
||||
cy.get('.swal2-title').should('contain', 'CONFIRM DELETION');
|
||||
cy.get(".swal2-popup").should("be.visible");
|
||||
cy.get(".swal2-title").should("contain", "CONFIRM DELETION");
|
||||
});
|
||||
|
||||
it('delete confirmation shows file name', () => {
|
||||
cy.get('table tbody tr').first().rightclick();
|
||||
cy.contains('Delete').click();
|
||||
cy.get('.swal2-popup').should('be.visible');
|
||||
cy.get('.swal2-html-container').should('contain', 'delete');
|
||||
it("delete confirmation shows file name", () => {
|
||||
cy.get("table tbody tr").first().rightclick();
|
||||
cy.contains("Delete").click();
|
||||
cy.get(".swal2-popup").should("be.visible");
|
||||
cy.get(".swal2-html-container").should("contain", "delete");
|
||||
});
|
||||
|
||||
it('delete confirmation can be cancelled', () => {
|
||||
cy.get('table tbody tr').first().rightclick();
|
||||
cy.contains('Delete').click();
|
||||
cy.get('.swal2-popup').should('be.visible');
|
||||
cy.get('.swal2-cancel').click();
|
||||
cy.get('.swal2-popup').should('not.exist');
|
||||
it("delete confirmation can be cancelled", () => {
|
||||
cy.get("table tbody tr").first().rightclick();
|
||||
cy.contains("Delete").click();
|
||||
cy.get(".swal2-popup").should("be.visible");
|
||||
cy.get(".swal2-cancel").click();
|
||||
cy.get(".swal2-popup").should("not.exist");
|
||||
});
|
||||
});
|
||||
|
||||
describe('File Context Menu on Grid View', () => {
|
||||
describe("File Context Menu on Grid View", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/files');
|
||||
cy.wait('@getFiles');
|
||||
cy.visit("/files");
|
||||
cy.wait("@getFiles");
|
||||
// Switch to grid view
|
||||
cy.get('svg').parent('li.cursor-pointer').last().click();
|
||||
cy.get("svg").parent("li.cursor-pointer").last().click();
|
||||
});
|
||||
|
||||
it('right-click on grid card shows context menu', () => {
|
||||
cy.get('li[title]').first().rightclick();
|
||||
cy.contains('Rename').should('be.visible');
|
||||
cy.contains('Delete').should('be.visible');
|
||||
it("right-click on grid card shows context menu", () => {
|
||||
cy.get("li[title]").first().rightclick();
|
||||
cy.contains("Rename").should("be.visible");
|
||||
cy.contains("Delete").should("be.visible");
|
||||
});
|
||||
|
||||
it('grid card rename opens SweetAlert dialog', () => {
|
||||
cy.get('li[title]').first().rightclick();
|
||||
cy.contains('Rename').click();
|
||||
cy.get('.swal2-popup').should('be.visible');
|
||||
cy.get('.swal2-title').should('contain', 'RENAME');
|
||||
it("grid card rename opens SweetAlert dialog", () => {
|
||||
cy.get("li[title]").first().rightclick();
|
||||
cy.contains("Rename").click();
|
||||
cy.get(".swal2-popup").should("be.visible");
|
||||
cy.get(".swal2-title").should("contain", "RENAME");
|
||||
});
|
||||
});
|
||||
|
||||
describe('Account Delete Confirmation', () => {
|
||||
describe("Account Delete Confirmation", () => {
|
||||
beforeEach(() => {
|
||||
loginWithFixtures();
|
||||
cy.visit('/account-admin');
|
||||
cy.wait('@getUsers');
|
||||
cy.visit("/account-admin");
|
||||
cy.wait("@getUsers");
|
||||
});
|
||||
|
||||
it('delete confirmation Yes button triggers delete API', () => {
|
||||
cy.get('.delete-account').first().click();
|
||||
cy.get('#modal_container').should('be.visible');
|
||||
cy.get('#sure_to_delete_acct_btn').click();
|
||||
cy.wait('@deleteUser');
|
||||
it("delete confirmation Yes button triggers delete API", () => {
|
||||
cy.get(".delete-account").first().click();
|
||||
cy.get("#modal_container").should("be.visible");
|
||||
cy.get("#sure_to_delete_acct_btn").click();
|
||||
cy.wait("@deleteUser");
|
||||
// Modal should close after deletion
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user