Skip to content

Commit

Permalink
- create new ui tests
Browse files Browse the repository at this point in the history
- update readme
- reorganize folder structure
  • Loading branch information
ecureuill committed Dec 6, 2023
1 parent 8031bc8 commit 1ac6f8a
Show file tree
Hide file tree
Showing 80 changed files with 789 additions and 275 deletions.
152 changes: 152 additions & 0 deletions e2e.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# End-to-End (E2E) Tests
E2E tests, located in `e2e/`, aim to verify the complete functionality of the application. They cover scenarios such as user authentication, navigation, and interactions with different pages.

## E2E scenarios

### login.spec.ts

1. **Should Login with user "standard_user"**
- Description: Verify that `standard_user` can successfully log in.
- Steps: Navigate to the login page, enter valid credentials for standard_user, and confirm successful login.

2. **Should Login with user "visual_user"**
- Description: Verify that `visual_user` can successfully log in.
- Steps: Navigate to the login page, enter valid credentials for a visual user, and ensure successful login.

3. **Should Login with user "error_user"**
- Description: Verify that `error_user` can successfully log in.
- Steps: Attempt to log in with the credentials of a user prone to errors and validate the system's response.

4. **Should Login with user "problem_user"**
- Description: Verify that `problem_user` can successfully log in.
- Steps: Log in using the credentials of a user known for causing problems and analyze the system's response.

5. **Should Login with user "performance_user"**
- Description: Validate the `performance_user`'s behavior when a known problematic user attempts to log in.
- Steps: Log in using the credentials of a user specifically used for performance testing and assess the login speed.

6. **Should Not Login with Wrong Credentials**
- Description: Confirm that the system rejects login attempts with incorrect credentials.
- Steps: Attempt to log in with invalid username and password combinations and verify that the system denies access.

7. **Should Not Login with Locked User**
- Description: Test the system's response when attempting to log in with a locked user account.
- Steps: Use the credentials of a locked user account and check for the expected system behavior.

8. **Should Not Login with Empty User**
- Description: Confirm that login is not possible with an empty username field.
- Steps: Attempt to log in without entering a username and validate the system's response.

9. **Should Not Login with Empty Password**
- Description: Verify that login is not allowed when the password field is left empty.
- Steps: Attempt to log in without entering a password and confirm the expected system behavior.

10. **Should Not Login with Empty Credential**
- Description: Test the system's response to an attempt to log in without entering any credentials.
- Steps: Try to log in without providing any username or password and ensure that access is denied.

### inventory.spec.ts

1. **Should List by Name (Z to A)**
- Description: Confirm that the inventory items are displayed in descending order by name.
- Steps: Navigate to the inventory page, select the "Z to A" sorting option, and validate the item order.

2. **Should List by Name (A to Z)**
- Description: Ensure that the inventory items are displayed in ascending order by name.
- Steps: Navigate to the inventory page, select the "A to Z" sorting option, and verify the item order.

3. **Should List by Price (Low to High)**
- Description: Validate that the inventory items are sorted from low to high based on price.
- Steps: Navigate to the inventory page, select the "Low to High" sorting option, and check the item order.

4. **Should List by Price (High to Low)**
- Description: Check that the inventory items are sorted from high to low based on price.
- Steps: Navigate to the inventory page, select the "High to Low" sorting option, and confirm the item order.

5. **Should Add to Cart and Then Remove from Cart**
- Description: Test the ability to add an item to the cart and subsequently remove it.
- Steps: Add an item to the cart, remove the added item.

### inventoryItem.spec.ts

1. **Should Add to Cart and Update Cart Counter**
- Description: Confirm that adding an item to the cart updates the cart counter.
- Steps: Navigate to an item's detailed view, add item to the cart and verify that the cart counter reflects the updated count.

2. **Should Remove from Cart and Update Cart Counter**
- Description: Verify that removing an item from the cart updates the cart counter accordingly.
- Steps: Navigate to an item's detailed view, add item to the cart, remove it, and check that the cart counter is decremented.

3. **Should Return to Inventory Page**
- Description: Test the functionality to return to the inventory page from an item-specific view.
- Steps: Navigate to an item's detailed view, use the back button, and confirm returning to the inventory page.

### cart.spec.ts

1. **Should Remove Item and Decrease Cart Counter**
- **Description:** Validate that removing an item from the cart results in a decrease in the cart counter.
- **Steps:** Add an item to the cart, note the initial cart count, remove the item, and confirm the cart counter is decremented.

2. **Should Remove All Items**
- **Description:** Test the ability to remove all items from the cart.
- **Steps:** Add multiple items to the cart, initiate the removal of all items, and verify that the cart is empty afterward.

3. **Should Continue Shopping**
- **Description:** Confirm the functionality to continue shopping from the cart.
- **Steps:** Navigate to the cart, choose to continue shopping, and ensure a return to the inventory page.

4. **Should Checkout**
- **Description:** Validate the checkout process initiated from the cart.
- **Steps:** Add an item to the cart, proceed to checkout, and confirm successful navigation to the checkout process.

### checkout.spec.ts

1. **Should Checkout and Go Back Home**
- Description: Confirm the successful checkout process, leading back to the home page.
- Steps: Go through the checkout process, complete the purchase, and validate redirection to the home page.

2. **Should Not Checkout with Empty Form**
- Description: Validate that attempting to check out with an empty form is not allowed.
- Steps: Initiate the checkout process with an empty form and confirm the expected system behavior.

3. **Should Not Checkout Without First Name**
- Description: Confirm that checkout is not possible without entering a first name.
- Steps: Start the checkout process without providing a first name and validate the system's response.

4. **Should Not Checkout Without Last Name**
- Description: Verify that checkout requires entering a last name.
- Steps: Attempt to check out without providing a last name and ensure the expected system behavior.

5. **Should Not Checkout Without Zip Code**
- Description: Confirm that a zip code is a required field for the checkout process.
- Steps: Start the checkout without entering a zip code and check for the system's expected response.

6. **Should Cancel Checkout on Step One**
- Description: Test the ability to cancel the checkout process on the first step.
- Steps: Begin the checkout process and choose to cancel at the first step, verifying a return to the previous state.

7. **Should Cancel Checkout on Step Two**
- Description: Confirm that the checkout process can be canceled on the second step.
- Steps: Progress to the second step of checkout and choose to cancel, checking for the expected system behavior.

### menu.spec.ts

1. **Should Open and Close Menu**
- **Description:** Verify that the menu can be successfully opened and closed.
- **Steps:** Open the menu, confirm its visibility, close the menu, and validate its closure.

2. **Should Reset App State**
- **Description:** Test the functionality to reset the application state from the menu.
- **Steps:** Navigate to the menu, choose the option to reset the app state, and confirm a reset.

3. **Should Visit About**
- **Description:** Confirm that the "About" section is accessible from the menu.
- **Steps:** Open the menu, select the "About" option, and validate successful navigation to the "About" page.

4. **Should Visit All Items**
- **Description:** Validate the ability to visit the "Inventory" page from the menu.
- **Steps:** Open the menu, choose the "All Items" option, and confirm successful navigation to the corresponding page.

5. **Should Logout**
- **Description:** Test the logout functionality from the menu.
- **Steps:** Open the menu, select the logout option, and confirm the expected logout behavior.
102 changes: 63 additions & 39 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,50 +100,74 @@ export default defineConfig({
// dependencies: ['setup'],
// },
{
name: 'visual',
name: 'visual on Desktop Chrome',
testMatch: '**/visual/*.spec.ts',
use: {
...devices['Desktop Chrome'],
}
},

// {
// name: 'firefox',
// use: {
// ...devices['Desktop Firefox'],
// storageState: STORAGE_STATE_DEFAULT_USER
// },
// dependencies: ['setup'],
// },

// {
// name: 'webkit',
// use: {
// ...devices['Desktop Safari'],
// storageState: STORAGE_STATE_DEFAULT_USER
// },
// dependencies: ['setup'],
// },

/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: { ...devices['Pixel 5'] },
// },
// {
// name: 'Mobile Safari',
// use: { ...devices['iPhone 12'] },
// },

/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
// },
// {
// name: 'Google Chrome',
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
// },
{
name: 'visual on Pixel 5',
testMatch: '**/visual/*.spec.ts',
use: {
...devices['Pixel 5'],
}
},
{
name: 'visual on iPhone 12',
testMatch: '**/visual/*.spec.ts',
use: {
...devices['iPhone 12'],
}
},
/* UI Test */
{
name: 'UI on Desktop Chrome',
testMatch: '**/ui/*.spec.ts',
use: {
...devices['Desktop Chrome'],
storageState: STORAGE_STATE_DEFAULT_USER
},
dependencies: ['setup'],
},
{
name: 'UI on Desktop Firefox',
testMatch: '**/ui/*.spec.ts',
use: {
...devices['Desktop Firefox'],
storageState: STORAGE_STATE_DEFAULT_USER
},
dependencies: ['setup'],
},
{
name: 'UI on Desktop Safari',
testMatch: '**/ui/*.spec.ts',
use: {
...devices['Desktop Safari'],
storageState: STORAGE_STATE_DEFAULT_USER
},
dependencies: ['setup'],
},
{
name: 'UI on Pixel 5',
testMatch: '**/ui/*.spec.ts',
grepInvert: /@responsive/,
use: {
...devices['Pixel 5'],
storageState: STORAGE_STATE_DEFAULT_USER
},
dependencies: ['setup'],
},
{
name: 'UI on Iphone 12',
testMatch: '**/ui/*.spec.ts',
grepInvert: /@responsive/,
use: {
...devices['iPhone 12'],
storageState: STORAGE_STATE_DEFAULT_USER
},
dependencies: ['setup'],
}
],

/* Run your local dev server before starting the tests */
Expand Down
23 changes: 20 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
# Playwright E2E Testing Project for saucedemo.com

Hello! This is my E2E testing project for [soucedemo.com](soucedemo.com) using Playwright and TypeScript! I developed this project as part of my learning journey in test automation.
Check the [test report](ecureuill.github.io/saucedemo-playwright)

The workflow, defined in the `.github/workflows/playwright.yml` file, executes Playwright tests on specified browsers and operating systems. After the test execution, Playwright generates a comprehensive report detailing both passed and failed scenarios. The GitHub Actions workflow is set up to automatically publish this Playwright test report to GitHub Pages.

This integration ensures that the latest Playwright test results are readily available, providing transparency and visibility into the testing process.

The generated report, showcasing insights into the results of the Playwright tests, is accessible at [ecureuill.github.io/saucedemo-playwright](ecureuill.github.io/saucedemo-playwright).

## Technologies Used

Expand Down Expand Up @@ -32,6 +37,9 @@ saucedemo/
│ ├── e2e/
│ │ └── login.spec.ts
│ │ └── ...
│ ├── ui/
│ │ └── login.spec.ts
│ │ └── ...
│ ├── visual/
│ │ └── visual.spec.ts
│ └── auth.setup.ts
Expand All @@ -45,11 +53,20 @@ saucedemo/

### 1. End-to-End (E2E) Tests

E2E tests, located in `e2e/`, aim to verify the complete functionality of the application. They cover scenarios such as user authentication, navigation, and interactions with different pages.
E2E tests, located in `e2e/`, aim to verify the complete functionality of the application. They cover scenarios such as user authentication, navigation, and interactions with different pages.

Check all scenarios [here](/e2e.md).

### 2. Visual Snapshot Tests

Visual snapshot tests, in `visual/`, focus on ensuring visual consistency across different test runs. They use Playwright's screenshot capabilities to compare and verify changes in the interface.
Visual snapshot tests, located in the `visual/` directory, play a crucial role in ensuring the visual consistency of the application across various test runs. Leveraging Playwright's powerful screenshot capabilities, these tests capture valid screenshots while navigating through the site in the context of a `standard_user`. Subsequently, the application's interface is tested against these baseline screenshots, this time with the user logged in as `visual_user`. This comparison process helps identify and verify any changes in the interface, ensuring a consistent and visually appealing user experience.

### 2. User Interface (UI) Tests

The UI tests, located in the `ui/` directory, are designed to scrutinize essential aspects such as usability, layout integrity, responsiveness, and the visual aesthetics of the application. In this initial version, responsiveness is assessed by simulating window resizing, and the integrity of the layout is validated. In upcoming versions, the testing scope will be expanded to delve deeper into these initiated aspects, while also addressing additional facets for a more comprehensive evaluation of the application's user interface.

Check all scenarios [here](/ui.md).


## Page Objects and Componentization

Expand Down
8 changes: 4 additions & 4 deletions tests/components/CheckoutFormComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class CheckoutFormComponent extends FormComponent {
await this.locatorZipCodeInput.fill(data.zipCode);
}

override validateErrorUX = async (): Promise<void> => {
override validateErrorLayout = async (): Promise<void> => {
await expect(this.locatorSubmitButton).toHaveText('Continue');

await expect(this.locatorFirstNameInput).toBeVisible();
Expand All @@ -41,10 +41,10 @@ export class CheckoutFormComponent extends FormComponent {
await expect(this.locatorZipCodeInput).toHaveAttribute('placeholder', 'Zip/Postal Code');
await expect(this.locatorZipCodeInput).toHaveClass(/\berror\b/);

return super.validateErrorUX();
return super.validateErrorLayout();
}

override validateDefaultUx = async (): Promise<void> => {
override validateDefaultLayout = async (): Promise<void> => {
await expect(this.locatorSubmitButton).toHaveText('Continue');

await expect(this.locatorFirstNameInput).toBeVisible();
Expand All @@ -62,7 +62,7 @@ export class CheckoutFormComponent extends FormComponent {
await expect(this.locatorZipCodeInput).toHaveAttribute('placeholder', 'Zip/Postal Code');
await expect(this.locatorZipCodeInput).not.toHaveClass(/\berror\b/);

return super.validateDefaultUx();
return super.validateDefaultLayout();
}

}
2 changes: 1 addition & 1 deletion tests/components/FooterComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class FooterComponent {
this.locatorLinkedinLink = this.locatorFooter.getByRole('link', { name: 'Linkedin' });
}

validateDefaultUX = async () => {
validateDefaultLayout = async () => {
await expect(this.locatorCopyRights).toBeVisible();
await expect(this.locatorTwitterLink).toBeVisible();
await expect(this.locatorFacebookLink).toBeVisible();
Expand Down
12 changes: 10 additions & 2 deletions tests/components/FormComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export abstract class FormComponent {
* <svg class="error_icon"/>
* ```
*/
async validateErrorUX(){
async validateErrorLayout(){
await expect(this.locatorForm).toBeVisible();
await expect(this.locatorForm.locator('input:not([type=submit]).error')).not.toHaveCount(0);
await expect(this.locatorForm.locator('svg.error_icon')).not.toHaveCount(0);
Expand All @@ -41,12 +41,20 @@ export abstract class FormComponent {
/**
* When form is valid, no input field should have error styles not error icon
*/
async validateDefaultUx() {
async validateDefaultLayout() {
await expect(this.locatorForm).toBeVisible();
await expect(this.locatorForm.locator('input:not([type=submit]).error')).toHaveCount(0);
await expect(this.locatorForm.locator('svg.error_icon')).toHaveCount(0);
await this.errorComponent.isNotVisible();
await expect(this.locatorSubmitButton).toBeVisible();
}

validateFormFieldsAreNotOverlapped = async () => {
const locatorFormFields = await this.locatorForm.locator('input').all();

for(const field of locatorFormFields){
await expect(field.evaluate(node => (node as HTMLElement).offsetParent !== null)).toBe(true);
}
}

}
2 changes: 1 addition & 1 deletion tests/components/HeaderComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class HeaderComponent {
this.locatorMenuButton = this.page.getByRole('button', { name: 'Open Menu' });
}

validateDefaultUX = async () => {
validateDefaultLayout = async () => {
await expect(this.locatorHeading).toBeVisible();
await expect(this.locatorCartLink).toBeVisible();
await expect(this.locatorMenuButton).toBeVisible();
Expand Down
Loading

0 comments on commit 1ac6f8a

Please sign in to comment.