Skip to content

Commit

Permalink
Added Playwright examples to the documentation (#164)
Browse files Browse the repository at this point in the history
* added playwright examples
* removed incorrect comment
* corrections to RabbitAI's comment
  • Loading branch information
Kunonuk authored Aug 21, 2024
1 parent 7dc7581 commit fd68007
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 0 deletions.
67 changes: 67 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ npx cypress run --project ./e2e

You can run your [factory_bot](https://github.com/thoughtbot/factory_bot) directly as well

then in Cypress
```js
// spec/cypress/e2e/simple.cy.js
describe('My First Test', () => {
Expand All @@ -195,6 +196,32 @@ describe('My First Test', () => {
})
})
```

then in Playwright
```js
const { test, expect, request } = require('@playwright/test');

test.describe('My First Test', () => {
test('visit root', async ({ page }) => {
// This calls to the backend to prepare the application state
await appFactories([
['create_list', 'post', 10],
['create', 'post', { title: 'Hello World' }],
['create', 'post', 'with_comments', { title: 'Factory_bot Traits here' }]
]);

// Visit the application under test
await page.goto('/');

await expect(page).toHaveText('Hello World');

// Accessing result
const records = await appFactories([['create', 'invoice', { paid: false }]]);
await page.goto(`/invoices/${records[0].id}`);
});
});
```

You can check the [association docs](docs/factory_bot_associations.md) on more ways to setup association with the correct data.

In some cases, using static Cypress fixtures may not provide sufficient flexibility when mocking HTTP response bodies. It's possible to use `FactoryBot.build` to generate Ruby hashes that can then be used as mock JSON responses:
Expand Down Expand Up @@ -509,6 +536,46 @@ beforeEach(() => {
});
```

add the following file to Playwright
```js
// test/playwright/support/on-rails.js
async function appCommands(body) {
const context = await request.newContext();
const response = await context.post('/__e2e__/command', {
data: body,
headers: {
'Content-Type': 'application/json'
}
});

if (response.status() !== 201) {
const responseBody = await response.text();
throw new Error(`Expected status 201 but got ${response.status()} - ${responseBody}`);
}

return response.json();
}

async function app(name, commandOptions = {}) {
const body = await appCommands({ name, options: commandOptions });
return body[0];
}

async function appScenario(name, options = {}) {
const body = { name: `scenarios/${name}`, options };
const result = await appCommands(body);
return result[0];
}

async function appFactories(options) {
return app('factory_bot', options);
}

async function clean() {
await app('clean');
}
```

## API Prefix

If your Rails server is exposed under a proxy, typically https://my-local.dev/api, you can use the `api_prefix` option.
Expand Down
30 changes: 30 additions & 0 deletions docs/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,33 @@ cy.forceLogin()
cy.forceLogin({redirect_to: '/profile'})
cy.forceLogin({email: '[email protected]'})
```

In `playwright/support/on-rails.js`:

```js
async function forceLogin(page, { email, redirect_to = '/' }) {
// Validate inputs
if (typeof email !== 'string' || typeof redirect_to !== 'string') {
throw new Error('Invalid input: email and redirect_to must be non-empty strings');
}

const response = await page.request.post('/__e2e__/force_login', {
data: { email: email, redirect_to: redirect_to },
headers: { 'Content-Type': 'application/json' }
});

// Handle response based on status code
if (response.ok()) {
await page.goto(redirect_to);
} else {
// Throw an exception for specific error statuses
throw new Error(`Login failed with status: ${response.status()}`);
}
}
```

Examples of usage in Playwright specs:
```js
await forceLogin(page, { email: '[email protected]', redirect_to: '/profile' });

```
14 changes: 14 additions & 0 deletions docs/factory_bot_associations.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ cy.appFactories([['create', 'author']]).then((records) => {
})
```

then in Playwright
There are a few ways you can set up associations with the correct data using Playwright and FactoryBot.
```js
const records = await appFactories([['create', 'author', { name: 'James' }]], context);
await appFactories([['create', 'post', { title: 'Playwright is cool', author_id: records[0].id }]], context);
// Note: These Playwright examples demonstrate asynchronous interactions with the server for setting up data associations. Ensure that your environment is configured to handle these async operations.
```


## 2. Using transient attributes

```rb
Expand Down Expand Up @@ -81,6 +90,11 @@ cy.appFactories([['create', 'post', { title: 'Cypress is cool', author_name: 'Ja
cy.appFactories([['create', 'post']])
```

then in Playwright
```js
const records = await appFactories([['create', 'post', { title: 'Playwright is cool', author_name: 'James' }]]);
```

## 3. Using Nested Attributes

```rb
Expand Down

0 comments on commit fd68007

Please sign in to comment.