@vibe/testkit
Version:
Vibe e2e testing toolkit
283 lines • 12.7 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { test } from "@playwright/test";
import { BaseElement } from "./BaseElement";
import { Button } from "./Button";
/**
* Class representing a Steps component.
* Extends the BaseElement class.
* Provides methods to interact with all Steps component functionality including navigation buttons,
* step indicators, and step content.
*/
export class Steps extends BaseElement {
/**
* Create a Steps element.
* @param {Page} page - The Playwright page object.
* @param {Locator} locator - The locator for the Steps element.
* @param {string} elementReportName - The name for reporting purposes.
*/
constructor(page, locator, elementReportName) {
super(page, locator, elementReportName);
this.backButton = new Button(page, this.locator.getByTestId("steps-backward-command"), "Steps back button");
this.nextButton = new Button(page, this.locator.getByTestId("steps-forward-command"), "Steps next button");
this.finishButton = new Button(page, this.locator.getByRole("button", { name: "Finish" }), "Steps finish button");
}
/**
* Click the back button to go to the previous step.
* @returns {Promise<void>}
*/
goToPreviousStep() {
return __awaiter(this, void 0, void 0, function* () {
yield test.step(`Go to previous step in ${this.elementReportName}`, () => __awaiter(this, void 0, void 0, function* () {
yield this.backButton.click();
}));
});
}
/**
* Click the next button to go to the next step.
* @returns {Promise<void>}
*/
goToNextStep() {
return __awaiter(this, void 0, void 0, function* () {
yield test.step(`Go to next step in ${this.elementReportName}`, () => __awaiter(this, void 0, void 0, function* () {
yield this.nextButton.click();
}));
});
}
/**
* Click the finish button to complete the steps.
* @returns {Promise<void>}
*/
finish() {
return __awaiter(this, void 0, void 0, function* () {
yield test.step(`Finish steps in ${this.elementReportName}`, () => __awaiter(this, void 0, void 0, function* () {
yield this.finishButton.click();
}));
});
}
/**
* Check if the back button is enabled.
* @returns {Promise<boolean>} True if the back button is enabled.
*/
isBackButtonEnabled() {
return __awaiter(this, void 0, void 0, function* () {
let isEnabled = false;
yield test.step(`Check if back button is enabled in ${this.elementReportName}`, () => __awaiter(this, void 0, void 0, function* () {
isEnabled = yield this.backButton.isEnabled();
}));
return isEnabled;
});
}
/**
* Check if the next button is enabled.
* @returns {Promise<boolean>} True if the next button is enabled.
*/
isNextButtonEnabled() {
return __awaiter(this, void 0, void 0, function* () {
let isEnabled = false;
yield test.step(`Check if next button is enabled in ${this.elementReportName}`, () => __awaiter(this, void 0, void 0, function* () {
isEnabled = yield this.nextButton.isEnabled();
}));
return isEnabled;
});
}
/**
* Check if the finish button is visible.
* @returns {Promise<boolean>} True if the finish button is visible.
*/
isFinishButtonVisible() {
return __awaiter(this, void 0, void 0, function* () {
let isVisible = false;
yield test.step(`Check if finish button is visible in ${this.elementReportName}`, () => __awaiter(this, void 0, void 0, function* () {
isVisible = yield this.finishButton.isVisible();
}));
return isVisible;
});
}
/**
* Get all step dots (for gallery type steps).
* @returns {Promise<Locator[]>} An array of step dot locators.
*/
getStepDots() {
return __awaiter(this, void 0, void 0, function* () {
let stepDots = [];
yield test.step(`Get all step dots in ${this.elementReportName}`, () => __awaiter(this, void 0, void 0, function* () {
const dotsContainer = this.locator.locator('[role="group"]');
stepDots = yield dotsContainer.locator("button").all();
}));
return stepDots;
});
}
/**
* Click on a specific step dot to navigate to that step.
* @param {number} stepIndex - The index of the step to navigate to (0-based).
* @returns {Promise<void>}
*/
clickStepDot(stepIndex) {
return __awaiter(this, void 0, void 0, function* () {
yield test.step(`Click step dot ${stepIndex} in ${this.elementReportName}`, () => __awaiter(this, void 0, void 0, function* () {
const stepDots = yield this.getStepDots();
if (stepIndex >= 0 && stepIndex < stepDots.length) {
yield stepDots[stepIndex].click();
}
else {
throw new Error(`Step index ${stepIndex} is out of range. Available steps: 0-${stepDots.length - 1}`);
}
}));
});
}
/**
* Get the current step index from the steps numbers header (for numbers type steps).
* @returns {Promise<number>} The current step index (0-based).
*/
getCurrentStepIndex() {
return __awaiter(this, void 0, void 0, function* () {
let currentStepIndex = 0;
yield test.step(`Get current step index from ${this.elementReportName}`, () => __awaiter(this, void 0, void 0, function* () {
const numbersText = yield this.locator
.locator("span")
.filter({ hasText: /\d+\s*\\\s*\d+/ })
.innerText();
const match = numbersText.match(/(\d+)\s*\\\s*(\d+)/);
if (match) {
currentStepIndex = parseInt(match[1]) - 1; // Convert to 0-based index
}
}));
return currentStepIndex;
});
}
/**
* Get the total number of steps from the steps numbers header (for numbers type steps).
* @returns {Promise<number>} The total number of steps.
*/
getTotalStepsCount() {
return __awaiter(this, void 0, void 0, function* () {
let totalSteps = 0;
yield test.step(`Get total steps count from ${this.elementReportName}`, () => __awaiter(this, void 0, void 0, function* () {
const numbersText = yield this.locator
.locator("span")
.filter({ hasText: /\d+\s*\\\s*\d+/ })
.innerText();
const match = numbersText.match(/(\d+)\s*\\\s*(\d+)/);
if (match) {
totalSteps = parseInt(match[2]);
}
}));
return totalSteps;
});
}
/**
* Check if a specific step dot is active (for gallery type steps).
* @param {number} stepIndex - The index of the step to check (0-based).
* @returns {Promise<boolean>} True if the step dot is active.
*/
isStepDotActive(stepIndex) {
return __awaiter(this, void 0, void 0, function* () {
let isActive = false;
yield test.step(`Check if step dot ${stepIndex} is active in ${this.elementReportName}`, () => __awaiter(this, void 0, void 0, function* () {
const stepDots = yield this.getStepDots();
if (stepIndex >= 0 && stepIndex < stepDots.length) {
const ariaCurrent = yield stepDots[stepIndex].getAttribute("aria-current");
isActive = ariaCurrent === "step" || ariaCurrent === "true";
}
}));
return isActive;
});
}
/**
* Get the active step dot index (for gallery type steps).
* @returns {Promise<number>} The index of the active step dot (-1 if none active).
*/
getActiveStepDotIndex() {
return __awaiter(this, void 0, void 0, function* () {
let activeIndex = -1;
yield test.step(`Get active step dot index in ${this.elementReportName}`, () => __awaiter(this, void 0, void 0, function* () {
const stepDots = yield this.getStepDots();
for (let i = 0; i < stepDots.length; i++) {
const ariaCurrent = yield stepDots[i].getAttribute("aria-current");
if (ariaCurrent === "step" || ariaCurrent === "true") {
activeIndex = i;
break;
}
}
}));
return activeIndex;
});
}
/**
* Get the current step content element.
* @returns {Promise<Locator>} The locator for the current step content.
*/
getCurrentStepContent() {
return __awaiter(this, void 0, void 0, function* () {
let stepContent = this.locator.locator("> *"); // Initialize with default value
yield test.step(`Get current step content in ${this.elementReportName}`, () => __awaiter(this, void 0, void 0, function* () {
// Step content is typically the direct child that's not the header
const stepsHeader = this.locator
.locator('.header, [data-testid*="steps-forward-command"], [data-testid*="steps-backward-command"]')
.first();
stepContent = this.locator.locator("> *").filter({ hasNot: stepsHeader });
}));
return stepContent;
});
}
/**
* Wait for the steps component to be fully loaded and interactive.
* @returns {Promise<void>}
*/
waitForStepsToLoad() {
return __awaiter(this, void 0, void 0, function* () {
yield test.step(`Wait for ${this.elementReportName} to load`, () => __awaiter(this, void 0, void 0, function* () {
yield this.waitForVisible();
// Wait for either step dots or numbers to be present
yield Promise.race([
this.locator.locator('[role="group"]').waitFor({ state: "visible" }),
this.locator
.locator("span")
.filter({ hasText: /\d+\s*\\\s*\d+/ })
.waitFor({ state: "visible" })
]);
}));
});
}
/**
* Navigate through all steps from beginning to end.
* @returns {Promise<void>}
*/
navigateToEnd() {
return __awaiter(this, void 0, void 0, function* () {
yield test.step(`Navigate through all steps to the end in ${this.elementReportName}`, () => __awaiter(this, void 0, void 0, function* () {
yield this.waitForStepsToLoad();
// Keep clicking next until we reach the end
while (yield this.isNextButtonEnabled()) {
yield this.goToNextStep();
yield this.page.waitForTimeout(100); // Small delay for step transition
}
}));
});
}
/**
* Navigate back to the first step.
* @returns {Promise<void>}
*/
navigateToBeginning() {
return __awaiter(this, void 0, void 0, function* () {
yield test.step(`Navigate back to the beginning in ${this.elementReportName}`, () => __awaiter(this, void 0, void 0, function* () {
yield this.waitForStepsToLoad();
// Keep clicking back until we reach the beginning
while (yield this.isBackButtonEnabled()) {
yield this.goToPreviousStep();
yield this.page.waitForTimeout(100); // Small delay for step transition
}
}));
});
}
}
//# sourceMappingURL=Steps.js.map