I have been grappling with the concept of utilizing multiple page objects within a single method. I haven't been able to come up with a suitable approach for implementing this logic. For instance, consider the following methods in my page object named "usersTable":
get rolesAndStatusMenu() {
return cy.get("#menu- > .MuiPaper-root > .MuiMenu-list>li");
}
get usersPartialRow() {
return cy.get(".MuiTableBody-root>tr>td");
}
settings(options: string) {
return cy
.get(
"[style='position: fixed; z-index: 1300; inset: 0px;'] > .MuiPaper-root > .MuiList-root",
)
.contains(options);
}
menuButton(userId: string) {
return cy.get(`.user_${userId}>td>button`);
}
userRow(userId?: string) {
const userrow = ".MuiTableBody-root>tr";
if (userId === undefined) {
return cy.get(userrow);
}
return cy.get(userrow).get(`.user_${userId}`);
}
Previously, I utilized the userRow method in my test as shown below:
usersTable.userRow(userId).should("not.exist");
In addition, I used the userMenu and settings methods in this test:
usersTable.menuButton(userId).click();
usersTable.settings("Impersonate").click();
Now, I want to combine different methods in a single call, but I'm uncertain about how to achieve this. For example:
usersTable.userRow(userId).settings.menuButton.click()
usersTable.userRow(userId).settings.impersonate.click()
Is it possible to use methods in this manner? Any suggestions are welcome.
Update
I have another page object where I encapsulated the usersTable component, called usersPage:
import { UsersTable } from "../components/UsersTable ";
export class Users {
visit() {
return cy.visit("/users");
}
get headingText() {
return cy.get(".MuiTypography-h5");
}
get inviteUserBtn() {
return cy.get(".MuiGrid-root> .MuiButtonBase-root");
}
get inviteUserModal() {
return cy.get(".MuiDialogContent-root");
}
get usersTable() {
return new UsersTable();
}
}
My code now appears like this:
usersPage.usersTable.menuButton(userId).click();
usersPage.usersTable.settings("Impersonate").click();
usersPage.visit();
usersPage.usersTable.menuButton(userId).click();
usersPage.usersTable.settings("Delete").click();
usersPage.usersTable.userRow(userId).should("not.exist");
For example, I am considering creating a class inside UsersTable
:
export class UsersTable {
...
}
class userTableRow {
}
**and returning it in `UsersTable` or something like that ?**
Second Update
Now I have created a class within the UsersTable
file:
class UserRow {
userRow(userId?: string) {
const userrow = ".MuiTableBody-root>tr";
if (userId === undefined) {
return cy.get(userrow);
}
return cy.get(userrow).find(`.user_${userId}`);
}
get menuButton() {
return this.userRow(`>td>button`); //I am unsure if this line is correct;
}
get impersonate() {
return cy
.get(
"[style='position: fixed; z-index: 1300; inset: 0px;'] > .MuiPaper-root > .MuiList-root",
)
.contains("Impersonate");
}
get delete() {
return cy
.get(
"[style='position: fixed; z-index: 1300; inset: 0px;'] > .MuiPaper-root > .MuiList-root",
)
.contains("Delete");
}
}
To integrate this class returned
in the UsersTable
class:
userRow(userId?: string) {
const userrow = ".MuiTableBody-root>tr";
if (userId === undefined) {
return cy.get(userrow);
}
return new UserRow(userId); **// but got error, it says Expected 0 arguments, but got 1.**
}
If I utilize the following method in the comment section:
// get UserRow() {
// return new UserRow();
// }
I can access everything within the user but cannot use my test like this:
usersPage.usersTable.UserRow(userId).settings.menuButton.click()
or perhaps
usersPage.usersTable.UserRow.userRow(userId).settings.menuButton.click()
But I can use it like this:
usersPage.usersTable.UserRow.menuButton.click()
How can I define userId?: string
for UserRow
? The userId constantly varies and is obtained from an API within the test, making it impossible to define in advance.