Introduction
As we setup the stage in Part 2 we are ready to continue exploration. Next is Claude 3.7 Sonnet (Thinking).
Prerequisites
- Claude 3.7 Sonnet (Thinking) is selected as a model
- The following prompt is run:
Create a test case utilizing provided constants for navigating to the web app, login, create/edit/delete an article. Try to verify the result after every major step. Use provided instructions
Generated POM (Page Object Model)
class ConduitPage {
readonly page: Page;
constructor(page: Page) {
this.page = page;
}
// Locators
get loginButton() { return this.page.getByRole('link', { name: 'Sign in' }); }
get emailInput() { return this.page.getByRole('textbox', { name: 'Email' }); }
get passwordInput() { return this.page.getByRole('textbox', { name: 'Password' }); }
get signInButton() { return this.page.getByRole('button', { name: 'Sign in' }); }
get newArticleButton() { return this.page.getByRole('link', { name: ' New Article' }); }
get articleTitleInput() { return this.page.getByRole('textbox', { name: 'Article Title' }); }
get articleAboutInput() { return this.page.getByRole('textbox', { name: 'What\'s this article about?' }); }
get articleContentInput() { return this.page.getByRole('textbox', { name: 'Write your article (in' }); }
get publishArticleButton() { return this.page.getByRole('button', { name: 'Publish Article' }); }
get editArticleButton() { return this.page.getByRole('link', { name: ' Edit Article' }).first(); }
get deleteArticleButton() { return this.page.getByRole('button', { name: ' Delete Article' }).first(); }
get articleTitleHeading() { return this.page.getByRole('heading', { level: 1 }); }
get yourFeedTab() { return this.page.getByText('Your Feed'); }
// Actions
async navigate() {
await this.page.goto(url);
}
async login() {
// Check if already logged in
if (await this.page.getByRole('link', { name: 'Sign in' }).isVisible()) {
await this.loginButton.click();
await this.emailInput.fill(email);
await this.passwordInput.fill(password);
await this.signInButton.click();
// Verify login successful
await expect(this.page.getByRole('link', { name: 'idavidov' })).toBeVisible();
}
}
async createArticle(title: string, about: string, content: string) {
await this.newArticleButton.click();
await this.articleTitleInput.fill(title);
await this.articleAboutInput.fill(about);
await this.articleContentInput.fill(content);
await this.publishArticleButton.click();
// Verify article was created
await expect(this.articleTitleHeading).toHaveText(title);
}
async editArticle(title: string, about: string, content: string) {
await this.editArticleButton.click();
await this.articleTitleInput.fill(title);
await this.articleAboutInput.fill(about);
await this.articleContentInput.fill(content);
await this.publishArticleButton.click();
// Verify article was updated
await expect(this.articleTitleHeading).toHaveText(title);
}
async deleteArticle() {
await this.deleteArticleButton.click();
// Verify we're redirected to home page
await expect(this.yourFeedTab).toBeVisible();
}
}
NOTE The provided example was generated from the first time. Only update which was needed to be made was to remove 'articleContent' locator due to wrong behavior.
Pros of the selected pattern
- Lazy Evaluation: Locators are created only when accessed, ensuring up-to-date references.
- Readability: Clean, property-like access (pageObject.usernameInput).
- Encapsulation: Easy to add logic or assertions in the getter if needed.
- IntelliSense: Good support in editors for auto-completion.
Cons of the selected pattern
- Performance: Each access creates a new locator (though Playwright locators are lightweight).
- Inheritance: Overriding getters in subclasses can be less straightforward than overriding fields.
What's next?
Stay tuned for next article in which we will explore SWE-1.
Please, do not hesitate to start conversation regarding the test or it's result.
🙏🏻 Thank you for reading! Building robust, scalable automation frameworks is a journey best taken together. If you found this article helpful, consider joining a growing community of QA professionals 🚀 who are passionate about mastering modern testing.
Join the community and get the latest articles and tips by signing up for the newsletter.
Top comments (0)