Created
September 3, 2023 19:07
-
-
Save nadvolod/da44ba1997fe44f737be66c431c6ef72 to your computer and use it in GitHub Desktop.
Using a Data Factory with Playwright and TypeScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface UserData { | |
username: string; | |
password: string; | |
} | |
interface AddressData { | |
street: string; | |
city: string; | |
zipCode: string; | |
} | |
interface PaymentData { | |
cardNumber: string; | |
expiryDate: string; | |
cvv: string; | |
} | |
export class DataFactory { | |
static createUser(): UserData { | |
return { | |
username: `user_${Math.random().toString(36).substring(7)}`, | |
password: `pass_${Math.random().toString(36).substring(7)}` | |
}; | |
} | |
static createAddress(): AddressData { | |
return { | |
street: `123${Math.random().toString(36).substring(7)} St`, | |
city: `City_${Math.random().toString(36).substring(7)}`, | |
zipCode: `ZIP_${Math.random().toString(36).substring(7)}` | |
}; | |
} | |
static createPayment(): PaymentData { | |
return { | |
cardNumber: `4111${Math.floor(Math.random() * 9999999999)}`, | |
expiryDate: `0${Math.floor(Math.random() * 9) + 1}/23`, | |
cvv: `${Math.floor(Math.random() * 999)}` | |
}; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Pros: | |
Separation of Concerns: Each factory focuses on creating a specific type of data, making the code more maintainable and understandable. | |
Reusability: You can use individual factories in different tests or even different projects. | |
Extensibility: Adding new types of data won't clutter a single factory class, reducing the risk of creating a "God object." | |
Cons: | |
Complexity: Handling multiple factories can become challenging, especially if they need to share data or configurations. | |
Dependency Management: If one factory relies on another, a change in one could affect the other. | |
Interaction Methods: | |
Composition: One factory can include an instance of another factory to generate composite data. Prefer composition over Inheritance. | |
Inheritance: If there's a common set of features among factories, a base factory class can be created. | |
Factory of Factories: Create a meta-factory that coordinates the use of multiple factories. | |
Example: Using Composition | |
Suppose you have UserDataFactory and AddressDataFactory. You can use them together in a CompleteUserDataFactory. | |
// UserDataFactory.ts | |
export class UserDataFactory { | |
generateUserData() { | |
return { | |
username: `user_${Math.random().toString(36).substring(7)}`, | |
password: `pass_${Math.random().toString(36).substring(7)}` | |
}; | |
} | |
} | |
// AddressDataFactory.ts | |
export class AddressDataFactory { | |
generateAddressData() { | |
return { | |
street: `123${Math.random().toString(36).substring(7)} St`, | |
city: `City_${Math.random().toString(36).substring(7)}`, | |
zipCode: `ZIP_${Math.random().toString(36).substring(7)}` | |
}; | |
} | |
} | |
// CompleteUserDataFactory.ts | |
import { UserDataFactory } from './UserDataFactory'; | |
import { AddressDataFactory } from './AddressDataFactory'; | |
export class CompleteUserDataFactory { | |
private userDataFactory = new UserDataFactory(); | |
private addressDataFactory = new AddressDataFactory(); | |
generateCompleteUserData() { | |
return { | |
user: this.userDataFactory.generateUserData(), | |
address: this.addressDataFactory.generateAddressData() | |
}; | |
} | |
} | |
Summary: | |
Having multiple data factories makes sense when: | |
The types of data are logically separate. | |
You want to reuse a specific type of data across multiple tests or scenarios. | |
Interaction between them can be managed through techniques like Composition, Inheritance, or a Factory of Factories, depending on the complexity and the relationships between the data types. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//usage in a test | |
import { chromium } from 'playwright'; | |
import { DataFactory } from './dataFactory'; | |
(async () => { | |
const userData = DataFactory.createUser(); | |
const addressData = DataFactory.createAddress(); | |
const paymentData = DataFactory.createPayment(); | |
const browser = await chromium.launch(); | |
const page = await browser.newPage(); | |
await page.goto('https://example.com/login'); | |
// Login | |
await page.fill('input[name="username"]', userData.username); | |
await page.fill('input[name="password"]', userData.password); | |
await page.click('button[type="submit"]'); | |
await browser.close(); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment