@vibe/testkit
Version:
Vibe e2e testing toolkit
263 lines • 11.5 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 { pressKey } from "../utils/common-actions";
/**
* Class representing an EditableText element.
* Extends the BaseElement class.
*/
export class EditableText extends BaseElement {
/**
* Create an EditableText element.
* @param {Page} page - The Playwright page object.
* @param {Locator} locator - The locator for the EditableText element.
* @param {string} elementReportName - The name for reporting purposes.
*/
constructor(page, locator, elementReportName) {
super(page, locator, elementReportName);
}
/**
* Get the input element locator (visible in edit mode).
* @returns {Locator} The input element locator.
*/
getInputLocator() {
return this.getLocator().locator("input");
}
/**
* Get the textarea element locator (visible in edit mode for multiline).
* @returns {Locator} The textarea element locator.
*/
getTextareaLocator() {
return this.getLocator().locator("textarea");
}
/**
* Get the active input element (input or textarea based on multiline mode).
* @returns {Locator} The active input element locator.
*/
getActiveInputLocator() {
return this.getLocator().locator("input, textarea");
}
/**
* Enter edit mode by clicking on the component.
* @returns {Promise<void>}
*/
enterEditMode() {
return __awaiter(this, void 0, void 0, function* () {
yield test.step(`Enter edit mode for ${this.getElementReportName()}`, () => __awaiter(this, void 0, void 0, function* () {
if (!(yield this.isInEditMode())) {
yield this.click();
yield this.getActiveInputLocator().waitFor({ state: "visible", timeout: 5000 });
}
}));
});
}
/**
* Exit edit mode by pressing Enter key.
* @returns {Promise<void>}
*/
exitEditModeWithEnter() {
return __awaiter(this, void 0, void 0, function* () {
yield test.step(`Exit edit mode with Enter for ${this.getElementReportName()}`, () => __awaiter(this, void 0, void 0, function* () {
const isMultiline = yield this.getTextareaLocator().isVisible();
yield pressKey(this.getPage(), "Enter");
// For single-line input, wait for edit mode to exit
if (!isMultiline) {
yield this.getActiveInputLocator().waitFor({ state: "hidden", timeout: 5000 });
// Wait for view mode to be ready
yield this.getPage().waitForTimeout(50);
}
// For multiline, Enter doesn't exit edit mode
}));
});
}
/**
* Exit edit mode by pressing Escape key (cancels changes).
* @returns {Promise<void>}
*/
exitEditModeWithEscape() {
return __awaiter(this, void 0, void 0, function* () {
yield test.step(`Exit edit mode with Escape for ${this.getElementReportName()}`, () => __awaiter(this, void 0, void 0, function* () {
yield pressKey(this.getPage(), "Escape");
yield this.getActiveInputLocator().waitFor({ state: "hidden", timeout: 5000 });
// Wait for view mode to be ready
yield this.getPage().waitForTimeout(50);
}));
});
}
/**
* Exit edit mode by clicking outside the component.
* @returns {Promise<void>}
*/
exitEditModeWithBlur() {
return __awaiter(this, void 0, void 0, function* () {
yield test.step(`Exit edit mode with blur for ${this.getElementReportName()}`, () => __awaiter(this, void 0, void 0, function* () {
yield this.removeFocus();
yield this.getActiveInputLocator().waitFor({ state: "hidden", timeout: 5000 });
// Wait for view mode to be ready
yield this.getPage().waitForTimeout(50);
}));
});
}
/**
* Set the text value in the editable text component.
* Enters edit mode, clears existing text, types new text, and confirms with Enter.
* @param {string} text - The text to set.
* @returns {Promise<void>}
*/
setText(text) {
return __awaiter(this, void 0, void 0, function* () {
yield test.step(`Set text: "${text}" for ${this.getElementReportName()}`, () => __awaiter(this, void 0, void 0, function* () {
yield this.enterEditMode();
const input = this.getActiveInputLocator();
yield input.clear();
yield input.fill(text);
// Press Enter to exit (for single-line) or Tab+Escape for multiline
const isMultiline = yield this.getTextareaLocator().isVisible();
if (isMultiline) {
yield this.exitEditModeWithEscape();
}
else {
yield this.exitEditModeWithEnter();
}
}));
});
}
/**
* Clear the text and set new text value.
* @param {string} text - The text to set.
* @returns {Promise<void>}
*/
clearAndSetText(text) {
return __awaiter(this, void 0, void 0, function* () {
yield test.step(`Clear and set text: "${text}" for ${this.getElementReportName()}`, () => __awaiter(this, void 0, void 0, function* () {
yield this.enterEditMode();
const input = this.getActiveInputLocator();
yield input.clear();
yield input.fill(text);
// Press Enter to exit (for single-line) or Escape for multiline
const isMultiline = yield this.getTextareaLocator().isVisible();
if (isMultiline) {
yield this.exitEditModeWithEscape();
}
else {
yield this.exitEditModeWithEnter();
}
}));
});
}
/**
* Get the current text value of the editable text component.
* @returns {Promise<string>} The current text value.
*/
getText() {
return __awaiter(this, void 0, void 0, function* () {
return yield test.step(`Get text for ${this.getElementReportName()}`, () => __awaiter(this, void 0, void 0, function* () {
// If in edit mode, get value from input
if (yield this.isInEditMode()) {
return yield this.getActiveInputLocator().inputValue();
}
// If in view mode, get text from the typography element
return yield this.getLocator().innerText();
}));
});
}
/**
* Get the input value when in edit mode.
* @returns {Promise<string>} The input value.
*/
getInputValue() {
return __awaiter(this, void 0, void 0, function* () {
return yield test.step(`Get input value for ${this.getElementReportName()}`, () => __awaiter(this, void 0, void 0, function* () {
return yield this.getActiveInputLocator().inputValue();
}));
});
}
/**
* Check if the component is currently in edit mode.
* @returns {Promise<boolean>} True if in edit mode, false otherwise.
*/
isInEditMode() {
return __awaiter(this, void 0, void 0, function* () {
return yield test.step(`Check if ${this.getElementReportName()} is in edit mode`, () => __awaiter(this, void 0, void 0, function* () {
const inputVisible = yield this.getInputLocator().isVisible();
const textareaVisible = yield this.getTextareaLocator().isVisible();
return inputVisible || textareaVisible;
}));
});
}
/**
* Check if the component is in multiline mode.
* @returns {Promise<boolean>} True if in multiline mode, false otherwise.
*/
isMultiline() {
return __awaiter(this, void 0, void 0, function* () {
return yield test.step(`Check if ${this.getElementReportName()} is multiline`, () => __awaiter(this, void 0, void 0, function* () {
yield this.enterEditMode();
const isMultiline = yield this.getTextareaLocator().isVisible();
yield this.exitEditModeWithEscape();
return isMultiline;
}));
});
}
/**
* Check if the component is read-only.
* @returns {Promise<boolean>} True if read-only, false otherwise.
*/
isReadOnly() {
return __awaiter(this, void 0, void 0, function* () {
return yield test.step(`Check if ${this.getElementReportName()} is read-only`, () => __awaiter(this, void 0, void 0, function* () {
// Try to enter edit mode
yield this.click();
// Wait for either input to appear or confirm it doesn't
try {
yield this.getActiveInputLocator().waitFor({ state: "visible", timeout: 500 });
// If we got here, we entered edit mode - exit and return false
yield this.exitEditModeWithEscape();
return false;
}
catch (_a) {
// Input didn't appear, it's read-only
return true;
}
}));
});
}
/**
* Type text character by character (useful for testing IME or special input scenarios).
* @param {string} text - The text to type.
* @returns {Promise<void>}
*/
typeText(text) {
return __awaiter(this, void 0, void 0, function* () {
yield test.step(`Type text: "${text}" for ${this.getElementReportName()}`, () => __awaiter(this, void 0, void 0, function* () {
yield this.enterEditMode();
const input = this.getActiveInputLocator();
yield input.clear();
yield input.pressSequentially(text);
}));
});
}
/**
* Get the placeholder text.
* @returns {Promise<string>} The placeholder text.
*/
getPlaceholder() {
return __awaiter(this, void 0, void 0, function* () {
return yield test.step(`Get placeholder for ${this.getElementReportName()}`, () => __awaiter(this, void 0, void 0, function* () {
yield this.enterEditMode();
const placeholder = yield this.getActiveInputLocator().getAttribute("placeholder");
yield this.exitEditModeWithEscape();
return placeholder || "";
}));
});
}
}
//# sourceMappingURL=EditableText.js.map