Project

General

Profile

Actions

action #163946

closed

coordination #163919: [epic] Create automation setup for testing Agama

Integrate Puppeteer script with the Page Object Model (POM)

Added by JERiveraMoya 5 months ago. Updated about 2 months ago.

Status:
Resolved
Priority:
High
Assignee:
Target version:
-
Start date:
2024-07-15
Due date:
% Done:

0%

Estimated time:

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

Bildschirmfoto_2024-08-30_10-36-26.png (79.1 KB) Bildschirmfoto_2024-08-30_10-36-26.png Screenshot of "Users" dialog rainerkoenig, 2024-08-30 08:57

Related issues 1 (0 open1 closed)

Related to qe-yam - action #163952: Run simple script to control an interactive installationResolvedjfernandez2024-07-15

Actions
Actions #1

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
Actions #2

Updated by JERiveraMoya 5 months ago

  • Description updated (diff)
Actions #3

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)
Actions #4

Updated by JERiveraMoya 4 months ago

  • Priority changed from Normal to High
Actions #5

Updated by rainerkoenig 4 months ago

  • Tags changed from qe-yam-jul-sprint, qe-yam-aug-sprint to qe-yam-aug-sprint
Actions #6

Updated by JERiveraMoya 3 months ago

  • Status changed from Workable to New
Actions #7

Updated by JERiveraMoya 3 months ago

  • Tags deleted (qe-yam-aug-sprint)
Actions #8

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.

Actions #9

Updated by rainerkoenig 3 months ago

  • Status changed from New to In Progress
  • Assignee set to rainerkoenig
Actions #10

Updated by JERiveraMoya 3 months ago

  • Tags set to qe-yam-aug-sprint
Actions #11

Updated by JERiveraMoya 3 months ago

  • Description updated (diff)
Actions #12

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.

Actions #13

Updated by JERiveraMoya 3 months ago

  • Tags changed from qe-yam-aug-sprint to qe-yam-sep-sprint
Actions #14

Updated by rainerkoenig 3 months ago

  • Related to action #163952: Run simple script to control an interactive installation added
Actions #15

Updated by rainerkoenig 3 months ago ยท Edited

Getting a bit mad at the users dialog.
Screenshot of 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>
Actions #17

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.

Actions #18

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.

Actions #19

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.

Actions #20

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.

Actions #21

Updated by JERiveraMoya 2 months ago

agreed to do some incremental changes in different PRs.

Actions #22

Updated by JERiveraMoya about 2 months ago

  • Status changed from In Progress to Resolved
Actions

Also available in: Atom PDF