How to proceed when Playwright tests fail at call to action buttons (like register, add to cart) in a production website but they are working if the same steps are done manually.
For example a test always fail when trying to register a new user, but registration works ok when I perform the same actions manually in the same website.
Steps performed in the test: go to website, click on user icon, type in the user email to be created in the registration modal, click on Continue.
Website UI: "An error ocurred, please try again".
Console tab: "Failed to load resource: the server responded with a status of 403 /api/account/profile/auth-options:1".
Network tab: endpoint auth-options request header status code 403 Forbidden. Access Denied You don't have permission to access on this server.
The test fails due to timeout after the login function call:
import { test, expect } from '@playwright/test';
import { LandingPage } from '../pageObjects/landingPage';
import { LoginModalPage } from '../pageObjects/loginModalPage';
test.describe('test suite', () => {
test.beforeEach(async({ page }) => {
const landingPage = new LandingPage(page);
await landingPage.goToLandingPage();
});
test('add product to the cart', async ({ page }) => {
const landingPage = new LandingPage(page);
const loginModal = new LoginModalPage(page);
await landingPage.customerInfoButton.click();
await loginModal.login('[email protected]', 'password');
await landingPage.logout();
});
});
Involved page objects:
import { Page, Locator } from '@playwright/test'
export class LoginModalPage {
readonly page: Page;
readonly loginModal: Locator;
readonly emailInputField: Locator;
readonly contactDataCheckbox: Locator;
readonly termsAndConditionsCheckbox: Locator;
readonly continueButton: Locator;
constructor(page: Page){
this.page = page;
this.loginModal = page.getByTestId('landing-screen');
this.emailInputField = this.loginModal.getByRole('textbox', {name: 'email address'});
this.contactDataCheckbox = this.loginModal.locator('.gl-checkbox__label', {hasText: 'contact data'});
this.termsAndConditionsCheckbox = this.loginModal.locator('.gl-checkbox__label', {hasText: 'Register'});
this.continueButton = this.loginModal.getByRole('button', {name: 'Continue'});
}
async login(user: string, password: string){
await this.emailInputField.pressSequentially(user, {delay: 50});
await this.contactDataCheckbox.click();
await this.termsAndConditionsCheckbox.click();
await this.continueButton.click();
}
}
import { Page, expect, Locator } from '@playwright/test'
export class LandingPage {
readonly page: Page;
readonly cookiesButton: Locator;
readonly heading: Locator;
readonly customerInfoButton: Locator;
readonly accountTab: Locator;
constructor(page: Page){
this.page = page;
this.cookiesButton = page.getByRole('button', { name: 'accept cookies'});
this.heading = page.getByRole('heading', { name: 'buy now' });
this.customerInfoButton = page.getByTestId('customer-info-button');
this.accountTab = page.getByTestId('home-account-tab');
}
async goToLandingPage(){
await this.page.goto('/');
}
async checkTitleAndHeaderPage(){
await expect(this.page).toHaveTitle(/official site/);
await expect(this.heading).toBeVisible();
}
}
Playwright config:
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
fullyParallel: false,
retries: process.env.CI ? 2 : 2,
workers: process.env.CI ? 1 : undefined,
reporter: 'html',
use: {
baseURL: websiteURL,
testIdAttribute: 'data-auto-id',
trace: 'on',
},
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome']
},
},
{
name: 'Google Chrome',
use: { ...devices['Desktop Chrome'], channel: 'chrome' },
},
],
});
What I've tried:
- different test input data
- running in different browsers
- adding hard waits
- clear cookies (but I was not able to have it working)
- set user agent in the code
- checked differences in the endpoint call for the test and manually doing the same in the website in the Network tab:
- Referrer Policy: "no-referrer" in the test, "strict-origin-when-cross-origin" in manual.
- content-type response header: "text/html" in the test, "application/json; charset=utf-8" in manual.
- Referer: (empty) in the test, url/endpoint in manual.
- Sec-Ch-Ua: "Chromium";v="123", "Not:A-Brand";v="8" in the test, "Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122" in manual.
- Sec-Ch-Ua-Platform: "Windows" in the test, "Android" in manual.
- User-Agent: "Mozilla/5.0 (Windows NT 10.0..." in the test, "Mozilla/5.0 (Linux, Android 6.0..."