action #163946
closedcoordination #163919: [epic] Create automation setup for testing Agama
Integrate Puppeteer script with the Page Object Model (POM)
0%
Description
Motivation¶
For reusability and maintenability, but refers to refresh best practice regarding this design pattern https://ray.run/blog/mastering-poms for an example with Playwright.
Acceptance criteria¶
- AC1: Break down the current script to use POM with Puppeteer in TypeScript.
Additional information¶
Starting point https://github.com/jknphy/agama-puppeteer/blob/main/tests/test_install.ts
Puppeteer doesn't offer specific documentation for POM, but you can check out the one for Playwright: https://playwright.dev/docs/pom
It will be needed somehow to export the new classes created for POM in similar fashion and establish our locators as properties of those classes, refers to https://www.typescriptlang.org/docs/ for finding the correct syntax in TypeScript.
Check out this presentation from QE Yam Workshop 2024 to avoid the use of inheritance with POMs, but I guess at this point we don't need composition.
Files
Updated by JERiveraMoya 5 months ago
- Subject changed from POM to Integrating Puppeter script with the Page Object Model (POM)
- Description updated (diff)
- Status changed from New to Workable
Updated by JERiveraMoya 5 months ago
- Subject changed from Integrating Puppeter script with the Page Object Model (POM) to Integrate Puppeteer script with the Page Object Model (POM)
Updated by rainerkoenig 4 months ago
- Tags changed from qe-yam-jul-sprint, qe-yam-aug-sprint to qe-yam-aug-sprint
Updated by JERiveraMoya 3 months ago
we can have something like this (tested that works):
pom/login-as-root-page.ts
import puppeteer, { Puppeteer, type Locator, type Page } from "puppeteer-core";
import { expect } from "chai";
export class LoginAsRootPage {
readonly page: Page;
readonly passwordInput: Locator<Element>;
readonly logInButton: Locator<Element>;
constructor(page: puppeteer.Page) {
this.page = page;
this.passwordInput = page.locator("input#password");
this.logInButton = page.locator("button[type='submit']");
}
async logIn(password: string) {
await this.passwordInput.fill(password);
await this.logInButton.click();
}
}
test.ts:
import { LoginAsRootPage } from "../pom/login-as-root-page.js";
...
it("allows logging in", async function () {
let loginAsRoot = new LoginAsRootPage(page);
loginAsRoot.logIn(agamaPassword);
});
Wondering if there is better way to declare those locators than Locator<Element>
, I'm not so familiar with the types in TS, let's investigate.
Updated by rainerkoenig 3 months ago
- Status changed from New to In Progress
- Assignee set to rainerkoenig
Updated by rainerkoenig 3 months ago
Progress notes: https://progress.opensuse.org/projects/qe-yast/wiki/Agama_and_Puppeteer_Need_To_Know
I've put my findings into the Wiki so that others can avoid doing the same steep learning curve.
Updated by JERiveraMoya 3 months ago
- Tags changed from qe-yam-aug-sprint to qe-yam-sep-sprint
Updated by rainerkoenig 3 months ago
- Related to action #163952: Run simple script to control an interactive installation added
Updated by rainerkoenig 3 months ago ยท Edited
Getting a bit mad at the users dialog.
Even if it looks all like buttons it isn't:
Define user now
is a link:
<a href="#/users/first" aria-disabled="false" class="pf-v5-c-button pf-m-primary" data-ouia-component-type="PF5/Button" data-ouia-safe="true" data-ouia-component-id="OUIA-Generated-Button-primary-1">Define a user now</a>
While Set a password
is a button:
<button aria-disabled="false" class="pf-v5-c-button pf-m-primary" type="button" data-ouia-component-type="PF5/Button" data-ouia-safe="true" data-ouia-component-id="OUIA-Generated-Button-primary-2">Set a password</button>
Updated by JERiveraMoya 3 months ago
Please update to this repo:
https://github.com/jknphy/agama-integration-test-webpack
Updated by JERiveraMoya 2 months ago
looks like at the end we could remove the code that use Promises and you could have it as you wanted at the beginning, but it is a hack and I haven't test it yet more than once, you could give it a try and automate this lines so you could develop more comfortable:
- systemctl restart agama.service
- F5 (puppeter can do that with .reload or something similar).
Having that at the begining, the default installation would be just a sequence of lines with readable methods to do stuff.
Updated by JERiveraMoya 2 months ago
- Tags changed from qe-yam-sep-sprint to qe-yam-oct-sprint
A series of PR with more granularity is expected in this ticket.
Updated by rainerkoenig 2 months ago
Iterating through the pages of a default installation.
The open question is if the defaut_installation.ts
should be "incremental", meaning containing all pages that were done so far or "differential", meaning to just replace that code snippet with the new page code.
The incremental approach would require either that PRs are merged quickly or that I branch from a branch, e.g.
- product_selection page
+ set root-password page
+ click on install page
Of course, I could do this easily and when product_selection_page PR is merged I rebase to main for the next branch. Sounds like a lot of git fun.
Updated by JERiveraMoya 2 months ago
sorry, I don't follow you, the default script contains blocks of code that contemplate two choices, we just need to put there one single POM in one single PR (for example, you can accumulate more than one, it is just an idea) to do the job of the choice that the user would find when running it for first time, so basically replacing each block, once merge nobody would notice your change, no rebase mess.
Updated by JERiveraMoya 2 months ago
agreed to do some incremental changes in different PRs.
Updated by JERiveraMoya about 2 months ago
- Status changed from In Progress to Resolved