|
|
|
import { expect, Locator, Page } from '@playwright/test';
|
|
|
|
import { UITypes } from 'nocodb-sdk';
|
|
|
|
import BasePage from '../../Base';
|
|
|
|
import { getTextExcludeIconText } from '../../../tests/utils/general';
|
|
|
|
import { CellPageObject } from '../common/Cell';
|
|
|
|
|
|
|
|
export class SurveyFormPage extends BasePage {
|
|
|
|
readonly cell: CellPageObject;
|
|
|
|
|
|
|
|
readonly formHeading: Locator;
|
|
|
|
readonly formSubHeading: Locator;
|
|
|
|
readonly fillFormButton: Locator;
|
|
|
|
readonly submitConfirmationButton: Locator;
|
|
|
|
readonly submitButton: Locator;
|
|
|
|
readonly nextButton: Locator;
|
|
|
|
readonly nextSlideButton: Locator;
|
|
|
|
readonly prevSlideButton: Locator;
|
|
|
|
readonly darkModeButton: Locator;
|
|
|
|
readonly formFooter: Locator;
|
|
|
|
|
|
|
|
constructor(rootPage: Page) {
|
|
|
|
super(rootPage);
|
|
|
|
this.cell = new CellPageObject(this);
|
|
|
|
this.formHeading = this.get().locator('[data-testid="nc-survey-form__heading"]');
|
|
|
|
this.formSubHeading = this.get().locator('[data-testid="nc-survey-form__sub-heading"]');
|
|
|
|
this.fillFormButton = this.get().locator('[data-testid="nc-survey-form__fill-form-btn"]');
|
|
|
|
this.submitConfirmationButton = this.get().locator('[data-testid="nc-survey-form__btn-submit-confirm"]');
|
|
|
|
this.submitButton = this.rootPage.locator(
|
|
|
|
'.nc-survery-form__confirmation_modal [data-testid="nc-survey-form__btn-submit"]'
|
|
|
|
);
|
|
|
|
this.nextButton = this.get().locator('[data-testid="nc-survey-form__btn-next"]');
|
|
|
|
this.nextSlideButton = this.get().locator('[data-testid="nc-survey-form__icon-next"]');
|
|
|
|
this.prevSlideButton = this.get().locator('[data-testid="nc-survey-form__icon-prev"]');
|
|
|
|
this.darkModeButton = this.get().locator('[data-testid="nc-form-dark-mode"]');
|
|
|
|
this.formFooter = this.get().locator('[data-testid="nc-survey-form__footer"]');
|
|
|
|
}
|
|
|
|
|
|
|
|
get() {
|
|
|
|
return this.rootPage.locator('html >> .nc-form-view');
|
|
|
|
}
|
|
|
|
|
|
|
|
async validateHeaders({ heading, subHeading }: { heading: string; subHeading: string }) {
|
|
|
|
await expect(this.get()).toBeVisible();
|
|
|
|
await expect(this.formHeading).toHaveText(heading);
|
|
|
|
await expect(this.formSubHeading).toHaveText(subHeading);
|
|
|
|
}
|
|
|
|
|
|
|
|
async validate({ fieldLabel, footer }: { fieldLabel: string; footer: string }) {
|
|
|
|
await expect(this.get()).toBeVisible();
|
|
|
|
|
|
|
|
await expect(this.formFooter).toHaveText(footer);
|
|
|
|
|
|
|
|
const locator = this.get().locator(`[data-testid="nc-form-column-label"]`);
|
|
|
|
let fieldText = await getTextExcludeIconText(locator);
|
|
|
|
|
|
|
|
// replace whitespace with ' ' for fieldLabel & fieldText
|
|
|
|
fieldLabel = fieldLabel.replace(/\u00A0/g, ' ');
|
|
|
|
fieldText = fieldText.replace(/\u00A0/g, ' ');
|
|
|
|
|
|
|
|
expect(fieldText).toBe(fieldLabel);
|
|
|
|
|
|
|
|
// parse footer text ("1 / 3") to identify if last slide
|
|
|
|
let isLastSlide = false;
|
|
|
|
const footerText = await this.formFooter.innerText();
|
|
|
|
const slideNumber = footerText.split(' / ')[0];
|
|
|
|
const totalSlides = footerText.split(' / ')[1];
|
|
|
|
if (slideNumber === totalSlides) {
|
|
|
|
isLastSlide = true;
|
|
|
|
}
|
|
|
|
if (isLastSlide) {
|
|
|
|
await expect(this.submitConfirmationButton).toBeVisible();
|
|
|
|
} else {
|
|
|
|
await expect(this.nextButton).toBeVisible();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async fill(param: { fieldLabel: string; type?: string; value?: string; skipNavigation?: boolean }) {
|
|
|
|
await this.get().locator(`[data-testid="nc-survey-form__input-${param.fieldLabel}"]`).click();
|
|
|
|
|
|
|
|
if (param.type === 'SingleLineText') {
|
|
|
|
await this.get().locator(`[data-testid="nc-survey-form__input-${param.fieldLabel}"] >> input`).fill(param.value);
|
|
|
|
} else if (param.type === 'DateTime') {
|
|
|
|
await this.get().locator(`[data-testid="nc-survey-form__input-${param.fieldLabel}"] >> input`).first().click();
|
|
|
|
const modal = this.rootPage.locator('.nc-picker-datetime');
|
|
|
|
await expect(modal).toBeVisible();
|
|
|
|
await modal.locator('.nc-date-picker-now-btn').click();
|
|
|
|
await modal.waitFor({ state: 'hidden' });
|
|
|
|
} else if (param.type === UITypes.LongText) {
|
|
|
|
await this.get()
|
|
|
|
.locator(`[data-testid="nc-survey-form__input-${param.fieldLabel}"] >> textarea`)
|
|
|
|
.waitFor({ state: 'visible' });
|
|
|
|
await this.get().locator(`[data-testid="nc-survey-form__input-${param.fieldLabel}"] >> textarea`).click();
|
|
|
|
|
|
|
|
await this.get()
|
|
|
|
.locator(`[data-testid="nc-survey-form__input-${param.fieldLabel}"] >> textarea`)
|
|
|
|
.fill(param.value);
|
|
|
|
} else {
|
|
|
|
await this.get()
|
|
|
|
.locator(`[data-testid="nc-survey-form__input-${param.fieldLabel}"] >> input`)
|
|
|
|
.waitFor({ state: 'visible' });
|
|
|
|
|
|
|
|
await this.get().locator(`[data-testid="nc-survey-form__input-${param.fieldLabel}"] >> input`).fill(param.value);
|
|
|
|
|
|
|
|
if ([UITypes.Date, UITypes.Time, UITypes.Year, UITypes.DateTime].includes(param.type)) {
|
|
|
|
// press enter key
|
|
|
|
await this.get().locator(`[data-testid="nc-survey-form__input-${param.fieldLabel}"] >> input`).press('Enter');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
await this.get().locator(`[data-testid="nc-form-column-label"]`).click();
|
|
|
|
|
|
|
|
if (!param.skipNavigation) {
|
|
|
|
await this.nextButton.click();
|
|
|
|
}
|
|
|
|
// post next button click, allow transitions to complete
|
|
|
|
await this.rootPage.waitForTimeout(100);
|
|
|
|
}
|
|
|
|
|
|
|
|
async validateSuccessMessage(param: { message: string; showAnotherForm?: boolean }) {
|
|
|
|
await this.get().locator('[data-testid="nc-survey-form__success-msg"]').waitFor({ state: 'visible' });
|
|
|
|
|
|
|
|
await expect(
|
|
|
|
this.get().locator(`[data-testid="nc-survey-form__success-msg"]:has-text("${param.message}")`)
|
|
|
|
).toBeVisible();
|
|
|
|
|
|
|
|
if (param.showAnotherForm) {
|
|
|
|
await expect(this.get().locator(`button:has-text("Submit Another Form")`)).toBeVisible();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async clickFillForm() {
|
|
|
|
await this.fillFormButton.click();
|
|
|
|
}
|
|
|
|
|
|
|
|
async confirmAndSubmit() {
|
|
|
|
await this.submitConfirmationButton.click();
|
|
|
|
await this.submitButton.waitFor({ state: 'visible' });
|
|
|
|
|
|
|
|
await this.submitButton.click();
|
|
|
|
|
|
|
|
await this.submitButton.waitFor({ state: 'hidden' });
|
|
|
|
}
|
|
|
|
|
|
|
|
async getFormFieldErrors() {
|
|
|
|
const fieldErrorEl = this.get().locator('.ant-form-item-explain');
|
|
|
|
return {
|
|
|
|
locator: fieldErrorEl,
|
|
|
|
verify: async ({ hasError, hasErrorMsg }: { hasError?: boolean; hasErrorMsg?: string | RegExp }) => {
|
|
|
|
if (hasError !== undefined) {
|
|
|
|
if (hasError) {
|
|
|
|
await expect(fieldErrorEl).toBeVisible();
|
|
|
|
} else {
|
|
|
|
await expect(fieldErrorEl).not.toBeVisible();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hasErrorMsg !== undefined) {
|
|
|
|
await expect(fieldErrorEl).toBeVisible();
|
|
|
|
|
|
|
|
await expect(fieldErrorEl.locator('> div').filter({ hasText: hasErrorMsg }).first()).toHaveText(hasErrorMsg);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|