Skip to content

Commit e77f27f

Browse files
authored
Merge branch 'getgrit:main' into main
2 parents 848bcaf + 4dfa817 commit e77f27f

32 files changed

+443
-194
lines changed

.grit/patterns/css/aspect_ratio.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
title: Aspect ratio
33
---
44

5-
# {{ page.title }}
6-
75
```grit
86
language css
97

.grit/patterns/go/cloudflare_go_v2.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ Future migrations will be more seamless as we will be automatically generating t
1111
{% /note %}
1212

1313

14+
This migration can be applied automatically using the [Grit CLI](https://docs.grit.io/cli/quickstart):
15+
16+
```
17+
grit apply cloudflare_go_v2
18+
```
19+
20+
1421
```grit
1522
language go
1623
@@ -651,12 +658,6 @@ file($body) where {
651658
}
652659
```
653660

654-
This migration can be applied automatically using the [Grit CLI](https://docs.grit.io/cli/quickstart):
655-
656-
```
657-
grit apply cloudflare_go_v2
658-
```
659-
660661
## Client construction with API key and email
661662

662663
Old:

.grit/patterns/java/no_big_decimal_double.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
---
2-
title: "BigDecimal(double)" should not be used
2+
title: "`BigDecimal(double)` should not be used"
33
tags: [java]
44
---
55

6-
# "BigDecimal(double)" should not be used
7-
86
Because of floating point imprecision, the `BigDecimal(double)` constructor can be somewhat unpredictable. It is better to use `BigDecimal.valueOf(double)`.
97

108

.grit/patterns/js/codecept_to_playwright.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
---
22
title: Convert CodeceptJS to Playwright
3+
tags: [migration]
34
---
45

56
Migrate from CodeceptJS to Playwright.
@@ -17,7 +18,7 @@ predicate convert_tags($scenario, $description) {
1718
$tags += `@$fragment`,
1819
},
1920
},
20-
21+
2122
$tags = join($tags, ` `),
2223
$description => trim(`$description $tags`, " "),
2324
}

.grit/patterns/js/curly.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ if (x > 0) {
3737
}
3838
```
3939

40-
##else
40+
## else
4141
```js
4242
if (x > 0)
4343
doStuff();

.grit/patterns/js/cypress_to_playwright.md

Lines changed: 147 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Convert Cypress to Playwright
3-
tags: [hidden]
3+
tags: [migration]
44
---
55

66
Migrate from Cypress to Playwright.
@@ -13,38 +13,88 @@ pattern convert_cypress_assertions() {
1313
or {
1414
`expect($arg).to.not.be.null` => `expect($arg).not.toBeNull()`,
1515
`expect($arg).to.not.be.undefined` => `expect($arg).not.toBeUndefined()`,
16+
`expect($arg).to.include($item)` => `expect($arg).toContain($item)`,
17+
`expect($arg).to.eql($item)` => `expect($arg).toEqual($item)`,
18+
`$locator.should($cond1, $cond2)` as $should where {
19+
$pw_cond = "",
20+
$cond1 <: or {
21+
`'contain'` where {
22+
$pw_cond += `toContainText($cond2)`,
23+
},
24+
`'have.attr'` where {
25+
$pw_cond += `toHaveAttribute($cond2)`,
26+
},
27+
},
28+
$should => `await expect($locator).$pw_cond`,
29+
},
1630
`$locator.should($condition)` as $should where {
1731
$condition <: bubble or {
1832
`'exist'` => `toBeAttached()`,
1933
`'not.exist'` => `not.toBeAttached()`,
2034
},
2135
$should => `await expect($locator).$condition`,
2236
},
23-
`$locator.should($cond1, $cond2)` as $should where {
24-
$pw_cond = "",
25-
$cond1 <: `'contain'` where {
26-
$pw_cond += `toContainText($cond2)`,
27-
},
28-
$should => `await expect($locator).$pw_cond`,
29-
}
3037
}
3138
}
3239
3340
pattern convert_cypress_queries() {
3441
or {
3542
`cy.visit($loc)` => `await page.goto($loc)`,
3643
`cy.get($locator)` => `page.locator($locator)`,
44+
`cy.contains($text, $options)` => `await expect(page.getByText($text)).toBeVisible($options)`,
45+
`cy.get($locator).contains($text).$action()` => `await page.locator($locator, { hasText: $text }).$action()`,
46+
`cy.get($locator).contains($text)` => `page.locator($locator, { hasText: $text })`,
47+
`cy.contains($text)` => `await expect(page.getByText($text)).toBeVisible()`,
3748
`cy.log($log)` => `console.log($log)`,
49+
`cy.wait($timeout)` => `await page.waitForTimeout($timeout)`,
50+
`$locator.find($inner)` => `$locator.locator($inner)`,
51+
`$locator.eq($n)` => `$locator.nth($n)`,
52+
`$locator.click($opts)` => `await $locator.click($opts)`,
53+
`$locator.text()` => `await $locator.textContent()`,
3854
`Cypress.env('$var')` => `process.env.$var`,
3955
`cy.onlyOn($var === $cond)` => `if ($var !== $cond) {
4056
test.skip();
4157
}`,
58+
`cy.$_($selector).each(($locator) => {
59+
$body
60+
})` as $loop where {
61+
$var = `$[locator]s`,
62+
$loop => `const $var = await page.locator($selector).all();
63+
for (const $locator of $var) {
64+
$body
65+
}`
66+
},
67+
`cy.request({ $opts })` as $req where {
68+
or {
69+
$opts <: contains pair(key=`method`, value=`"$method"`),
70+
$method = `get`,
71+
},
72+
$opts <: contains pair(key=`url`, value=$url),
73+
$method = lowercase($method),
74+
$other_opts = [],
75+
$opts <: some bubble($other_opts) $opt where {
76+
$opt <: not contains or {
77+
`method`,
78+
`url`,
79+
},
80+
$other_opts += $opt,
81+
},
82+
$other_opts = join($other_opts, `,`),
83+
$req => `await request.$method($url, { $other_opts })`
84+
}
4285
}
4386
}
4487
4588
pattern convert_cypress_test() {
4689
or {
47-
`describe($description, $suite)` => `test.describe($description, $suite)`,
90+
`describe($description, $suite)` => `test.describe($description, $suite)` where {
91+
$suite <: maybe contains bubble or {
92+
`before($hook)` => `test.beforeAll(async $hook)`,
93+
`beforeEach($hook)` => `test.beforeEach(async $hook)`,
94+
`after($hook)` => `test.afterAll(async $hook)`,
95+
`afterEach($hook)` => `test.afterEach(async $hook)`,
96+
},
97+
},
4898
or {
4999
`it($description, () => { $body })`,
50100
`test($description, () => { $body })`
@@ -58,7 +108,7 @@ contains bubble or {
58108
convert_cypress_assertions(),
59109
convert_cypress_queries(),
60110
} where {
61-
$program <: contains bubble convert_cypress_test(),
111+
$program <: maybe contains bubble convert_cypress_test(),
62112
$expect = `expect`,
63113
$expect <: ensure_import_from(source=`"@playwright/test"`),
64114
$test = `test`,
@@ -93,3 +143,90 @@ test.describe('A mock test', () => {
93143
});
94144
});
95145
```
146+
147+
## Converts requests
148+
149+
```js
150+
cy.request({
151+
method: 'POST',
152+
url: '/submit',
153+
body: JSON.stringify({
154+
content: 'Hello world',
155+
}),
156+
failOnStatusCode: false,
157+
});
158+
cy.contains('Submitted', { timeout: 10000 });
159+
```
160+
161+
```ts
162+
import { expect, test } from '@playwright/test';
163+
164+
await request.post('/submit', {
165+
body: JSON.stringify({
166+
content: 'Hello world',
167+
}),
168+
failOnStatusCode: false,
169+
});
170+
await expect(page.getByText('Submitted')).toBeVisible({ timeout: 10000 });
171+
```
172+
173+
## Converts hooks
174+
175+
```js
176+
describe('Grouping', function () {
177+
before(function () {
178+
setup();
179+
});
180+
181+
afterEach(function () {
182+
cy.wait(1000);
183+
teardown();
184+
});
185+
});
186+
```
187+
188+
```ts
189+
import { expect, test } from '@playwright/test';
190+
191+
test.describe('Grouping', function () {
192+
test.beforeAll(async function () {
193+
setup();
194+
});
195+
196+
test.afterEach(async function () {
197+
await page.waitForTimeout(1000);
198+
teardown();
199+
});
200+
});
201+
```
202+
203+
## Converts composite queries
204+
205+
```js
206+
describe('Grouping', function () {
207+
it('my test', async () => {
208+
cy.get('.header').find('.button').eq(1).click({ force: true });
209+
cy.get('.sidebar').contains('Files').click();
210+
cy.get('.header').find('.button').eq(1).should('have.attr', 'disabled');
211+
cy.get('.button').each((button) => {
212+
expect(button.text()).to.eql('Submit');
213+
});
214+
});
215+
});
216+
```
217+
218+
```ts
219+
import { expect, test } from '@playwright/test';
220+
221+
test.describe('Grouping', function () {
222+
test('my test', async ({ page, request }) => {
223+
await page.locator('.header').locator('.button').nth(1).click({ force: true });
224+
await page.locator('.sidebar', { hasText: 'Files' }).click();
225+
await expect(page.locator('.header').locator('.button').nth(1)).toHaveAttribute('disabled');
226+
const buttons = await page.locator('.button').all();
227+
for (const button of buttons) {
228+
expect(await button.textContent()).toEqual('Submit');
229+
}
230+
});
231+
});
232+
```

.grit/patterns/js/intelligent_useEffect_to_useLayoutEffect.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: [React2Hooks] Intelligent useEffect vs useLayoutEffect
2+
title: "[React2Hooks] Intelligent useEffect vs useLayoutEffect"
33
tags: [fix]
44
---
55

.grit/patterns/js/no_return_assign.md

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@ title: Hoist assignment out of `return` statement
33
tags: [good, se]
44
---
55

6-
# {{ page.title }}
7-
8-
This rule hoists the assignments out of `return`. Does not apply when assignment is wrapped in parentheses.
6+
This rule hoists the assignments out of `return`. Because an assignment, `=` is easy to confuse with a comparison, `==`, The best practice is not to use any assignments in return statements.
97

8+
This does not apply when assignment is wrapped in parentheses.
109

1110
```grit
1211
engine marzano(0.1)
@@ -21,10 +20,6 @@ language js
2120
} => `$assignment;\n return $left;`
2221
```
2322

24-
```
25-
An assignment, `=`, is easy to confuse with a comparison, `==`. The best practice is not to use any assignments in return statements.
26-
```
27-
2823
## Hoist `=` from `return` statement
2924

3025
```javascript

.grit/patterns/js/no_unsafe_negation.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ title: Rewrite `!key in col` ⇒ `!(key in col)`
33
tags: [fix]
44
---
55

6-
# {{ page.title }}
7-
86
Negates `key` instead of the entire expression, which is likely a bug.
97

108
The intent is usually to negate the entire relation expression.

.grit/patterns/js/prefer_early_return.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ title: PreferEarlyReturn
33
tags: [lint, style]
44
---
55

6-
# {{ page.title }}
7-
86
Prefer to use early returns to keep functions flat.
97

108

0 commit comments

Comments
 (0)