scrabble-solver 2.18.10-alpha.0 → 2.18.10-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bun.lock +29 -29
- package/e2e/app.spec.ts +3 -3
- package/e2e/bugs/112-character-bonus.spec.ts +1 -1
- package/e2e/bugs/129-esc-sidebar.spec.ts +1 -1
- package/e2e/bugs/3-x-tile-in-polish.spec.ts +1 -1
- package/e2e/bugs/30-click-inside-radio-icon.spec.ts +1 -1
- package/e2e/bugs/333-disabled-radio-cursor.spec.ts +1 -1
- package/e2e/bugs/342-results-sorting.spec.ts +1 -1
- package/e2e/bugs/363-dictionary-input-unique-words.spec.ts +1 -1
- package/e2e/bugs/380-transliteration-when-pasting.spec.ts +1 -1
- package/e2e/bugs/398-digraphs-in-created-words.spec.ts +2 -2
- package/e2e/bugs/401-board-state-on-game-change.spec.ts +1 -1
- package/e2e/bugs/452-stale-translations-cache.spec.ts +1 -1
- package/e2e/features/198-highlight-unreachable-cells.spec.ts +1 -2
- package/e2e/features/430-highlight-unreachable-cells-results.spec.ts +1 -2
- package/e2e/features/91-hover-remaining-tile-highlights.spec.ts +3 -4
- package/e2e/features/hidden-coordinates-migration.spec.ts +1 -1
- package/e2e/features/words-preview.spec.ts +4 -4
- package/e2e/lib/actions.ts +17 -4
- package/e2e/lib/selectors.ts +1 -1
- package/package.json +3 -3
- package/.claude/settings.local.json +0 -38
- package/.github/workflows/build.yml +0 -16
- package/.github/workflows/bunx.yml +0 -66
- package/.github/workflows/deploy.yml +0 -32
- package/.github/workflows/e2e.yml +0 -26
- package/.github/workflows/npx.yml +0 -69
- package/.github/workflows/oxfmt.yml +0 -18
- package/.github/workflows/oxlint.yml +0 -19
- package/.github/workflows/unit.yml +0 -19
- package/playwright-report/index.html +0 -49
- package/test-results/.last-run.json +0 -4
- package/todo.txt +0 -5
package/bun.lock
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"": {
|
|
6
6
|
"name": "scrabble-solver",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@scrabble-solver/scrabble-solver": "2.18.10-alpha.
|
|
8
|
+
"@scrabble-solver/scrabble-solver": "2.18.10-alpha.1",
|
|
9
9
|
"open-cli": "9.0.0",
|
|
10
10
|
"wait-on": "9.5.1",
|
|
11
11
|
},
|
|
@@ -28,48 +28,48 @@
|
|
|
28
28
|
},
|
|
29
29
|
"packages/configs": {
|
|
30
30
|
"name": "@scrabble-solver/configs",
|
|
31
|
-
"version": "2.18.10-alpha.
|
|
31
|
+
"version": "2.18.10-alpha.1",
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@scrabble-solver/constants": "2.18.10-alpha.
|
|
34
|
-
"@scrabble-solver/types": "2.18.10-alpha.
|
|
33
|
+
"@scrabble-solver/constants": "2.18.10-alpha.1",
|
|
34
|
+
"@scrabble-solver/types": "2.18.10-alpha.1",
|
|
35
35
|
},
|
|
36
36
|
},
|
|
37
37
|
"packages/constants": {
|
|
38
38
|
"name": "@scrabble-solver/constants",
|
|
39
|
-
"version": "2.18.10-alpha.
|
|
39
|
+
"version": "2.18.10-alpha.1",
|
|
40
40
|
},
|
|
41
41
|
"packages/dictionaries": {
|
|
42
42
|
"name": "@scrabble-solver/dictionaries",
|
|
43
|
-
"version": "2.18.10-alpha.
|
|
43
|
+
"version": "2.18.10-alpha.1",
|
|
44
44
|
"bin": {
|
|
45
45
|
"remove-dictionaries": "bin/remove-dictionaries.js",
|
|
46
46
|
"update-dictionaries": "bin/update-dictionaries.js",
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@kamilmielnik/gaddag": "3.0.0",
|
|
50
|
-
"@scrabble-solver/logger": "2.18.10-alpha.
|
|
51
|
-
"@scrabble-solver/types": "2.18.10-alpha.
|
|
52
|
-
"@scrabble-solver/word-lists": "2.18.10-alpha.
|
|
50
|
+
"@scrabble-solver/logger": "2.18.10-alpha.1",
|
|
51
|
+
"@scrabble-solver/types": "2.18.10-alpha.1",
|
|
52
|
+
"@scrabble-solver/word-lists": "2.18.10-alpha.1",
|
|
53
53
|
},
|
|
54
54
|
},
|
|
55
55
|
"packages/logger": {
|
|
56
56
|
"name": "@scrabble-solver/logger",
|
|
57
|
-
"version": "2.18.10-alpha.
|
|
57
|
+
"version": "2.18.10-alpha.1",
|
|
58
58
|
},
|
|
59
59
|
"packages/scrabble-solver": {
|
|
60
60
|
"name": "@scrabble-solver/scrabble-solver",
|
|
61
|
-
"version": "2.18.10-alpha.
|
|
61
|
+
"version": "2.18.10-alpha.1",
|
|
62
62
|
"dependencies": {
|
|
63
63
|
"@floating-ui/react": "0.27.20",
|
|
64
64
|
"@kamilmielnik/gaddag": "3.0.0",
|
|
65
65
|
"@reduxjs/toolkit": "2.13.0",
|
|
66
|
-
"@scrabble-solver/configs": "2.18.10-alpha.
|
|
67
|
-
"@scrabble-solver/constants": "2.18.10-alpha.
|
|
68
|
-
"@scrabble-solver/dictionaries": "2.18.10-alpha.
|
|
69
|
-
"@scrabble-solver/logger": "2.18.10-alpha.
|
|
70
|
-
"@scrabble-solver/solver": "2.18.10-alpha.
|
|
71
|
-
"@scrabble-solver/types": "2.18.10-alpha.
|
|
72
|
-
"@scrabble-solver/word-definitions": "2.18.10-alpha.
|
|
66
|
+
"@scrabble-solver/configs": "2.18.10-alpha.1",
|
|
67
|
+
"@scrabble-solver/constants": "2.18.10-alpha.1",
|
|
68
|
+
"@scrabble-solver/dictionaries": "2.18.10-alpha.1",
|
|
69
|
+
"@scrabble-solver/logger": "2.18.10-alpha.1",
|
|
70
|
+
"@scrabble-solver/solver": "2.18.10-alpha.1",
|
|
71
|
+
"@scrabble-solver/types": "2.18.10-alpha.1",
|
|
72
|
+
"@scrabble-solver/word-definitions": "2.18.10-alpha.1",
|
|
73
73
|
"classnames": "2.5.1",
|
|
74
74
|
"env-cmd": "11.0.0",
|
|
75
75
|
"include-media": "2.0.0",
|
|
@@ -104,29 +104,29 @@
|
|
|
104
104
|
},
|
|
105
105
|
"packages/solver": {
|
|
106
106
|
"name": "@scrabble-solver/solver",
|
|
107
|
-
"version": "2.18.10-alpha.
|
|
107
|
+
"version": "2.18.10-alpha.1",
|
|
108
108
|
"dependencies": {
|
|
109
109
|
"@kamilmielnik/gaddag": "3.0.0",
|
|
110
|
-
"@scrabble-solver/types": "2.18.10-alpha.
|
|
110
|
+
"@scrabble-solver/types": "2.18.10-alpha.1",
|
|
111
111
|
},
|
|
112
112
|
"devDependencies": {
|
|
113
|
-
"@scrabble-solver/configs": "2.18.10-alpha.
|
|
114
|
-
"@scrabble-solver/constants": "2.18.10-alpha.
|
|
115
|
-
"@scrabble-solver/dictionaries": "2.18.10-alpha.
|
|
113
|
+
"@scrabble-solver/configs": "2.18.10-alpha.1",
|
|
114
|
+
"@scrabble-solver/constants": "2.18.10-alpha.1",
|
|
115
|
+
"@scrabble-solver/dictionaries": "2.18.10-alpha.1",
|
|
116
116
|
},
|
|
117
117
|
},
|
|
118
118
|
"packages/types": {
|
|
119
119
|
"name": "@scrabble-solver/types",
|
|
120
|
-
"version": "2.18.10-alpha.
|
|
120
|
+
"version": "2.18.10-alpha.1",
|
|
121
121
|
"dependencies": {
|
|
122
|
-
"@scrabble-solver/constants": "2.18.10-alpha.
|
|
122
|
+
"@scrabble-solver/constants": "2.18.10-alpha.1",
|
|
123
123
|
},
|
|
124
124
|
},
|
|
125
125
|
"packages/word-definitions": {
|
|
126
126
|
"name": "@scrabble-solver/word-definitions",
|
|
127
|
-
"version": "2.18.10-alpha.
|
|
127
|
+
"version": "2.18.10-alpha.1",
|
|
128
128
|
"dependencies": {
|
|
129
|
-
"@scrabble-solver/types": "2.18.10-alpha.
|
|
129
|
+
"@scrabble-solver/types": "2.18.10-alpha.1",
|
|
130
130
|
"cheerio": "1.2.0",
|
|
131
131
|
"follow-redirects": "1.16.2",
|
|
132
132
|
"striptags": "3.2.0",
|
|
@@ -138,9 +138,9 @@
|
|
|
138
138
|
},
|
|
139
139
|
"packages/word-lists": {
|
|
140
140
|
"name": "@scrabble-solver/word-lists",
|
|
141
|
-
"version": "2.18.10-alpha.
|
|
141
|
+
"version": "2.18.10-alpha.1",
|
|
142
142
|
"dependencies": {
|
|
143
|
-
"@scrabble-solver/types": "2.18.10-alpha.
|
|
143
|
+
"@scrabble-solver/types": "2.18.10-alpha.1",
|
|
144
144
|
"cheerio": "1.2.0",
|
|
145
145
|
"follow-redirects": "1.16.2",
|
|
146
146
|
"transliteration": "2.7.0",
|
package/e2e/app.spec.ts
CHANGED
|
@@ -13,10 +13,10 @@ import {
|
|
|
13
13
|
getRackTile,
|
|
14
14
|
getResult,
|
|
15
15
|
getSettingOption,
|
|
16
|
-
getSettingsButton,
|
|
17
16
|
getTooltip,
|
|
18
17
|
hoverResult,
|
|
19
18
|
moveMouseAway,
|
|
19
|
+
openSettingsModal,
|
|
20
20
|
solve,
|
|
21
21
|
typeRack,
|
|
22
22
|
visitIndex,
|
|
@@ -31,7 +31,7 @@ test.describe('app', () => {
|
|
|
31
31
|
|
|
32
32
|
test('has default setting values', async ({ page }) => {
|
|
33
33
|
await visitIndex(page);
|
|
34
|
-
await
|
|
34
|
+
await openSettingsModal(page);
|
|
35
35
|
|
|
36
36
|
await expect(getSettingOption(page, 'Game', 'Scrabble')).toBeChecked();
|
|
37
37
|
await expect(getSettingOption(page, 'Language', 'English (US)')).toBeChecked();
|
|
@@ -43,7 +43,7 @@ test.describe('app', () => {
|
|
|
43
43
|
test.describe('full app test', () => {
|
|
44
44
|
test('Scrabble - Polish', async ({ page }) => {
|
|
45
45
|
await visitIndex(page);
|
|
46
|
-
await
|
|
46
|
+
await openSettingsModal(page);
|
|
47
47
|
await getSettingOption(page, 'Language', 'Polski').check();
|
|
48
48
|
await closeModal(page);
|
|
49
49
|
await typeRack(page, 'abł');
|
|
@@ -9,7 +9,7 @@ test.describe('#112 - Scrabble - Character bonus not applied', () => {
|
|
|
9
9
|
test('correctly shows points for a result which gets a character bonus', async ({ page }) => {
|
|
10
10
|
await Lib.visitIndex(page);
|
|
11
11
|
|
|
12
|
-
await Lib.
|
|
12
|
+
await Lib.openSettingsModal(page);
|
|
13
13
|
await Lib.getSettingOption(page, 'Language', 'Français').check();
|
|
14
14
|
await Lib.closeModal(page);
|
|
15
15
|
await Lib.typeRack(page, 'jours');
|
|
@@ -8,7 +8,7 @@ import * as Lib from '../lib';
|
|
|
8
8
|
test.describe('#129 - Esc does not close the sidebar when letters input is focused', () => {
|
|
9
9
|
test('Esc key closes the sidebar when rack is focused', async ({ page }) => {
|
|
10
10
|
await Lib.visitIndex(page);
|
|
11
|
-
await Lib.
|
|
11
|
+
await Lib.openSettingsModal(page);
|
|
12
12
|
await Lib.typeRack(page, 'a');
|
|
13
13
|
await page.keyboard.press('Escape');
|
|
14
14
|
|
|
@@ -8,7 +8,7 @@ import * as Lib from '../lib';
|
|
|
8
8
|
test.describe('#3 - "X" tile is allowed in Polish', () => {
|
|
9
9
|
test('does not accept "X" tile in Polish', async ({ page }) => {
|
|
10
10
|
await Lib.visitIndex(page);
|
|
11
|
-
await Lib.
|
|
11
|
+
await Lib.openSettingsModal(page);
|
|
12
12
|
await Lib.getSettingOption(page, 'Language', 'Polski').check();
|
|
13
13
|
await Lib.closeModal(page);
|
|
14
14
|
await Lib.typeBoard(page, 'x', 'horizontal', { x: 7, y: 7 });
|
|
@@ -8,7 +8,7 @@ import * as Lib from '../lib';
|
|
|
8
8
|
test.describe('#30 - Clicking inside an icon of non-first unchecked radio button does not select that option', () => {
|
|
9
9
|
test('Clicking inside an icon of first unchecked radio button selects it', async ({ page }) => {
|
|
10
10
|
await Lib.visitIndex(page);
|
|
11
|
-
await Lib.
|
|
11
|
+
await Lib.openSettingsModal(page);
|
|
12
12
|
await Lib.getSettingOption(page, 'Language', 'English (GB)').click();
|
|
13
13
|
|
|
14
14
|
const icon = Lib.getSettingOption(page, 'Language', 'English (US)')
|
|
@@ -8,7 +8,7 @@ import * as Lib from '../lib';
|
|
|
8
8
|
test.describe('#333 - Disabled radio button has cursor: pointer', () => {
|
|
9
9
|
test('Disabled radio button has cursor: not-allowed', async ({ page }) => {
|
|
10
10
|
await Lib.visitIndex(page);
|
|
11
|
-
await Lib.
|
|
11
|
+
await Lib.openSettingsModal(page);
|
|
12
12
|
await Lib.getSettingOption(page, 'Language', 'Polski').check();
|
|
13
13
|
await Lib.getSettingOption(page, 'Gra', 'Scrabble').scrollIntoViewIfNeeded();
|
|
14
14
|
|
|
@@ -8,7 +8,7 @@ import * as Lib from '../lib';
|
|
|
8
8
|
test.describe('#342 - Incorrect sorting when filtering', () => {
|
|
9
9
|
test('correctly sorts valid results first when text filter is active', async ({ page }) => {
|
|
10
10
|
await Lib.visitIndex(page);
|
|
11
|
-
await Lib.
|
|
11
|
+
await Lib.openSettingsModal(page);
|
|
12
12
|
await Lib.getSettingOption(page, 'Language', 'Polski').check();
|
|
13
13
|
await Lib.closeModal(page);
|
|
14
14
|
await Lib.typeBoard(page, 'bopie', 'horizontal', { x: 6, y: 3 });
|
|
@@ -13,7 +13,7 @@ test.describe('#363 - Dictionary input should display unique words', () => {
|
|
|
13
13
|
});
|
|
14
14
|
|
|
15
15
|
await Lib.visitIndex(page);
|
|
16
|
-
await Lib.
|
|
16
|
+
await Lib.openSettingsModal(page);
|
|
17
17
|
await Lib.getSettingOption(page, 'Language', 'Türkçe').check();
|
|
18
18
|
await Lib.closeModal(page);
|
|
19
19
|
await Lib.typeBoard(page, 'ponje', 'horizontal', { x: 3, y: 7 });
|
|
@@ -44,7 +44,7 @@ async function testTransliterationOnPaste(
|
|
|
44
44
|
},
|
|
45
45
|
) {
|
|
46
46
|
await Lib.visitIndex(page);
|
|
47
|
-
await Lib.
|
|
47
|
+
await Lib.openSettingsModal(page);
|
|
48
48
|
await Lib.getSettingOption(page, 'Language', language).check();
|
|
49
49
|
await Lib.closeModal(page);
|
|
50
50
|
await Lib.paste(Lib.getBoardTile(page, 0, 0), word);
|
|
@@ -8,11 +8,11 @@ import * as Lib from '../lib';
|
|
|
8
8
|
test.describe('#398 - Solitary digraph tiles are recognised as created words', () => {
|
|
9
9
|
test('should transliterate special characters when pasting in French', async ({ page }) => {
|
|
10
10
|
await Lib.visitIndex(page);
|
|
11
|
-
await Lib.
|
|
11
|
+
await Lib.openSettingsModal(page);
|
|
12
12
|
await Lib.getSettingOption(page, 'Language', 'Español').check();
|
|
13
13
|
await Lib.closeModal(page);
|
|
14
14
|
await Lib.pasteBoard(page, 'chiclean', 'horizontal', { x: 3, y: 7 });
|
|
15
|
-
await page.getByLabel('Palabras creadas', { exact: true })
|
|
15
|
+
await Lib.openModal(page, page.getByLabel('Palabras creadas', { exact: true }));
|
|
16
16
|
|
|
17
17
|
const modal = Lib.getOpenModal(page);
|
|
18
18
|
await expect(modal.getByText('ch', { exact: true })).toHaveCount(0);
|
|
@@ -12,7 +12,7 @@ test.describe('#401 - Board state not preserved on game type change', () => {
|
|
|
12
12
|
await Lib.visitIndex(page);
|
|
13
13
|
await Lib.typeBoard(page, 'word', 'horizontal', { x: 7, y: 7 });
|
|
14
14
|
|
|
15
|
-
await Lib.
|
|
15
|
+
await Lib.openSettingsModal(page);
|
|
16
16
|
await Lib.getSettingOption(page, 'Game', 'Super Scrabble').check();
|
|
17
17
|
await Lib.closeModal(page);
|
|
18
18
|
|
|
@@ -26,7 +26,7 @@ test.describe('#452 - Stale translations cache', () => {
|
|
|
26
26
|
});
|
|
27
27
|
await page.reload();
|
|
28
28
|
|
|
29
|
-
await
|
|
29
|
+
await Lib.openWordsModal(page);
|
|
30
30
|
await expect(Lib.getOpenModal(page).getByRole('button', { name: 'Validity', exact: true })).toBeVisible();
|
|
31
31
|
});
|
|
32
32
|
});
|
|
@@ -70,8 +70,7 @@ test.describe('#198 - Highlight unreachable cells', () => {
|
|
|
70
70
|
});
|
|
71
71
|
|
|
72
72
|
async function setHighlightUnreachableCells(page: Page, value: 'Off' | 'On') {
|
|
73
|
-
await Lib.
|
|
74
|
-
await expect(Lib.getOpenModal(page)).toBeVisible();
|
|
73
|
+
await Lib.openSettingsModal(page);
|
|
75
74
|
await Lib.getSettingOption(page, 'Highlight unreachable cells', value).check();
|
|
76
75
|
await Lib.closeModal(page);
|
|
77
76
|
}
|
|
@@ -60,8 +60,7 @@ test.describe('#430 - Highlight unreachable cells includes current results', ()
|
|
|
60
60
|
});
|
|
61
61
|
|
|
62
62
|
async function setHighlightUnreachableCells(page: Page, value: 'Off' | 'On') {
|
|
63
|
-
await Lib.
|
|
64
|
-
await expect(Lib.getOpenModal(page)).toBeVisible();
|
|
63
|
+
await Lib.openSettingsModal(page);
|
|
65
64
|
await Lib.getSettingOption(page, 'Highlight unreachable cells', value).check();
|
|
66
65
|
await Lib.closeModal(page);
|
|
67
66
|
}
|
|
@@ -82,13 +82,12 @@ test.describe('#91 - Hovering remaining tile highlights all same tiles on the bo
|
|
|
82
82
|
});
|
|
83
83
|
|
|
84
84
|
async function openRemainingTilesModal(page: Page) {
|
|
85
|
-
await page.getByLabel('Remaining tiles', { exact: true })
|
|
86
|
-
await expect(Lib.getOpenModal(page)).toBeVisible();
|
|
85
|
+
await Lib.openModal(page, page.getByLabel('Remaining tiles', { exact: true }));
|
|
87
86
|
}
|
|
88
87
|
|
|
89
88
|
async function openRemainingTilesModalFromMenu(page: Page) {
|
|
90
|
-
await
|
|
91
|
-
await Lib.getOpenModal(page).getByLabel('Remaining tiles', { exact: true })
|
|
89
|
+
await Lib.openMenuModal(page);
|
|
90
|
+
await Lib.openModal(page, Lib.getOpenModal(page).getByLabel('Remaining tiles', { exact: true }));
|
|
92
91
|
await expect(page.getByTestId('remaining-tile-a')).toBeVisible();
|
|
93
92
|
}
|
|
94
93
|
|
|
@@ -16,7 +16,7 @@ test.describe('"hidden" coordinates migration', () => {
|
|
|
16
16
|
|
|
17
17
|
await expect(Lib.getBoardContainer(page).getByText('A', { exact: true })).toBeVisible();
|
|
18
18
|
|
|
19
|
-
await Lib.
|
|
19
|
+
await Lib.openSettingsModal(page);
|
|
20
20
|
await expect(Lib.getSettingOption(page, 'Coordinates', 'Original')).toBeChecked();
|
|
21
21
|
await Lib.closeModal(page);
|
|
22
22
|
|
|
@@ -39,7 +39,7 @@ test.describe('Words preview', () => {
|
|
|
39
39
|
await Lib.getOpenModal(page).getByRole('button', { name: 'Preview', exact: true }).click();
|
|
40
40
|
await Lib.expectTileHighlighted(Lib.getBoardTile(page, 3, 3));
|
|
41
41
|
|
|
42
|
-
await page.getByRole('button', { name: 'Results', exact: true })
|
|
42
|
+
await Lib.openModal(page, page.getByRole('button', { name: 'Results', exact: true }));
|
|
43
43
|
const result = Lib.getOpenModal(page).getByTestId('result').first();
|
|
44
44
|
await expect(result).not.toHaveAttribute('aria-current');
|
|
45
45
|
await result.click();
|
|
@@ -77,7 +77,7 @@ test.describe('Words preview', () => {
|
|
|
77
77
|
await Lib.getOpenModal(page).getByRole('button', { name: 'Preview', exact: true }).click();
|
|
78
78
|
await Lib.expectTileHighlighted(Lib.getBoardTile(page, 3, 3));
|
|
79
79
|
|
|
80
|
-
await Lib.
|
|
80
|
+
await Lib.openSettingsModal(page);
|
|
81
81
|
await Lib.getSettingOption(page, 'Language', 'Polski').check();
|
|
82
82
|
await Lib.closeModal(page);
|
|
83
83
|
|
|
@@ -127,8 +127,8 @@ test.describe('Words preview', () => {
|
|
|
127
127
|
test('previewing from the menu-opened modal returns to the board', async ({ page }) => {
|
|
128
128
|
await Lib.visitIndex(page);
|
|
129
129
|
await Lib.typeBoard(page, 'cat', 'horizontal', { x: 3, y: 3 });
|
|
130
|
-
await
|
|
131
|
-
await Lib.getOpenModal(page).getByLabel('Created words', { exact: true })
|
|
130
|
+
await Lib.openMenuModal(page);
|
|
131
|
+
await Lib.openModal(page, Lib.getOpenModal(page).getByLabel('Created words', { exact: true }));
|
|
132
132
|
|
|
133
133
|
await expect(Lib.getWord(page, 0)).toHaveAttribute('aria-current', 'true');
|
|
134
134
|
|
package/e2e/lib/actions.ts
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
getResult,
|
|
13
13
|
getResultCandidatePicker,
|
|
14
14
|
getResultsContainer,
|
|
15
|
+
getSettingsButton,
|
|
15
16
|
getWord,
|
|
16
17
|
} from './selectors';
|
|
17
18
|
|
|
@@ -39,13 +40,25 @@ export async function closeModal(page: Page): Promise<void> {
|
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
export async function openWordsModal(page: Page): Promise<void> {
|
|
42
|
-
await page.getByLabel('Created words', { exact: true })
|
|
43
|
-
await expect(getOpenModal(page)).toBeVisible();
|
|
43
|
+
await openModal(page, page.getByLabel('Created words', { exact: true }));
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
export async function openResultsModal(page: Page): Promise<void> {
|
|
47
|
-
await getResultCandidatePicker(page)
|
|
48
|
-
|
|
47
|
+
await openModal(page, getResultCandidatePicker(page));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export async function openSettingsModal(page: Page): Promise<void> {
|
|
51
|
+
await openModal(page, getSettingsButton(page));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export async function openMenuModal(page: Page): Promise<void> {
|
|
55
|
+
await openModal(page, page.getByRole('button', { name: 'Menu', exact: true }));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export async function openModal(page: Page, trigger: Locator): Promise<void> {
|
|
59
|
+
const openModalsBeforeClick = await getOpenModal(page).count();
|
|
60
|
+
await trigger.click();
|
|
61
|
+
await expect(getOpenModal(page)).toHaveCount(openModalsBeforeClick + 1);
|
|
49
62
|
}
|
|
50
63
|
|
|
51
64
|
export async function closeModalWithButton(page: Page): Promise<void> {
|
package/e2e/lib/selectors.ts
CHANGED
|
@@ -5,7 +5,7 @@ export function getModal(page: Page): Locator {
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
export function getOpenModal(page: Page): Locator {
|
|
8
|
-
return page.locator('.ReactModal__Overlay--after-open').getByRole('dialog');
|
|
8
|
+
return page.locator('.ReactModal__Overlay--after-open:not(.ReactModal__Overlay--before-close)').getByRole('dialog');
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export function getBoardContainer(page: Page): Locator {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scrabble-solver",
|
|
3
|
-
"version": "2.18.10-alpha.
|
|
3
|
+
"version": "2.18.10-alpha.1",
|
|
4
4
|
"description": "Scrabble Solver 2 - Free, open-source, cross-platform, multi-language analysis tool for Scrabble, Scrabble Duel, Super Scrabble, Letter League, Crossplay, Literaki, Kelimelik, Wyrazy, and Wordfeud. Quickly find the top-scoring words using the given board and tiles.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"scrabble",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"reinstall": "bun run clean && bun install && bun run build",
|
|
42
42
|
"release": "bun run release:prepare && bun run test && nx release --skip-publish && bun run release:publish",
|
|
43
43
|
"release:prepare": "bun run clean && bun install",
|
|
44
|
-
"release:publish": "git push --follow-tags && npm publish --workspaces --include-workspace-root --access public --tag $(node -p \"/-/.test(require('./package.json').version) ? 'next' : 'latest'\") && gh release create $(node -p \"require('./package.json').version\") --draft --generate-notes --prerelease=$(node -p \"/-/.test(require('./package.json').version)\")",
|
|
44
|
+
"release:publish": "git push --follow-tags && npm publish --workspaces --include-workspace-root --access public --tag $(node -p \"/-/.test(require('./package.json').version) ? 'next' : 'latest'\") && gh release create $(node -p \"require('./package.json').version\") --repo kamilmielnik/scrabble-solver --draft --generate-notes --prerelease=$(node -p \"/-/.test(require('./package.json').version)\")",
|
|
45
45
|
"screencast": "start-server-and-test start:app http://localhost:3333 screencast:record",
|
|
46
46
|
"screencast:record": "bun scripts/record-screencast.ts",
|
|
47
47
|
"start": "bun run --parallel --no-orphans 'start:*'",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"packages/scrabble-solver"
|
|
79
79
|
],
|
|
80
80
|
"dependencies": {
|
|
81
|
-
"@scrabble-solver/scrabble-solver": "2.18.10-alpha.
|
|
81
|
+
"@scrabble-solver/scrabble-solver": "2.18.10-alpha.1",
|
|
82
82
|
"open-cli": "9.0.0",
|
|
83
83
|
"wait-on": "9.5.1"
|
|
84
84
|
},
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"permissions": {
|
|
3
|
-
"allow": [
|
|
4
|
-
"Bash(npm run:*)",
|
|
5
|
-
"Bash(ls:*)",
|
|
6
|
-
"Bash(npm ls:*)",
|
|
7
|
-
"Bash(npx next:*)",
|
|
8
|
-
"Bash(npx tsc:*)",
|
|
9
|
-
"Bash(yarn install:*)",
|
|
10
|
-
"Bash(npm install:*)",
|
|
11
|
-
"Bash(node:*)",
|
|
12
|
-
"Bash(npm view:*)",
|
|
13
|
-
"Bash(npx --yes oxfmt --help)",
|
|
14
|
-
"Bash(npx --yes oxfmt --migrate=prettier)",
|
|
15
|
-
"Bash(npm uninstall:*)",
|
|
16
|
-
"Bash(grep:*)",
|
|
17
|
-
"Bash(echo '.foo { color: red; }')",
|
|
18
|
-
"Bash(npx oxfmt:*)",
|
|
19
|
-
"Bash(rm /tmp/test.scss)",
|
|
20
|
-
"Bash(gh issue *)",
|
|
21
|
-
"Bash(npx jest *)",
|
|
22
|
-
"Bash(xargs sed *)",
|
|
23
|
-
"Bash(gh api *)",
|
|
24
|
-
"Bash(find cypress/support -name \"index*\" -exec cat {} \\\\;)",
|
|
25
|
-
"Bash(npx eslint *)",
|
|
26
|
-
"Bash(file *.avif)",
|
|
27
|
-
"Bash(which convert *)",
|
|
28
|
-
"Bash(convert \"/home/kamil/desktop/ss/scrabble-word-game-pieces-arranged-grid-from-isolated-white-background_506134-13355.avif\" -resize 400x /tmp/ss3.png)",
|
|
29
|
-
"Read(//tmp/**)",
|
|
30
|
-
"Bash(du -b /tmp/rect-*.png)",
|
|
31
|
-
"Bash(convert \"/tmp/rect-il_1080xN.4271871875_3ays.jpg.png\" -resize 600x /tmp/rect1-small.png)",
|
|
32
|
-
"Bash(convert \"/tmp/rect-they-finished-scrabble-board-game-using-the-letters-made-out-of-tiles-S37FPF.jpg.png\" -resize 600x /tmp/rect2-small.png)",
|
|
33
|
-
"Bash(convert *)",
|
|
34
|
-
"Bash(xargs -I {} dirname {})",
|
|
35
|
-
"Bash(xargs -I {} ls -1 {}/)"
|
|
36
|
-
]
|
|
37
|
-
}
|
|
38
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
name: Build
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [master]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [master]
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
build:
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
steps:
|
|
13
|
-
- uses: actions/checkout@v6
|
|
14
|
-
- uses: oven-sh/setup-bun@v2
|
|
15
|
-
- run: bun install --frozen-lockfile
|
|
16
|
-
- run: bun run build
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
name: bunx
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [master]
|
|
6
|
-
schedule:
|
|
7
|
-
- cron: '0 0 * * *' # every day at 00:00 UTC
|
|
8
|
-
workflow_dispatch: # allow manual triggering
|
|
9
|
-
|
|
10
|
-
jobs:
|
|
11
|
-
bunx:
|
|
12
|
-
runs-on: ubuntu-latest
|
|
13
|
-
steps:
|
|
14
|
-
- uses: oven-sh/setup-bun@v2
|
|
15
|
-
- uses: actions/checkout@v6
|
|
16
|
-
- name: Wait for the released version to be published on npm
|
|
17
|
-
run: |
|
|
18
|
-
VERSION=$(node -p "require('./package.json').version")
|
|
19
|
-
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
|
|
20
|
-
echo "Target version: $VERSION"
|
|
21
|
-
# Unscoped CLI package + every non-private workspace package, published
|
|
22
|
-
# together by `bun run release`. All version in lockstep.
|
|
23
|
-
PACKAGES=$(node -p "['scrabble-solver', ...require('fs').readdirSync('packages').map(d=>require('./packages/'+d+'/package.json')).filter(p=>!p.private).map(p=>p.name)].join(' ')")
|
|
24
|
-
echo "Waiting for: $PACKAGES"
|
|
25
|
-
for pkg in $PACKAGES; do
|
|
26
|
-
for i in $(seq 1 60); do
|
|
27
|
-
if [ "$(npm view "$pkg@$VERSION" version 2>/dev/null)" = "$VERSION" ]; then
|
|
28
|
-
echo "✓ $pkg@$VERSION is available"
|
|
29
|
-
break
|
|
30
|
-
fi
|
|
31
|
-
if [ "$i" -eq 60 ]; then
|
|
32
|
-
echo "::error::Timed out waiting for $pkg@$VERSION on npm" >&2
|
|
33
|
-
exit 1
|
|
34
|
-
fi
|
|
35
|
-
echo "… $pkg@$VERSION not available yet (attempt $i/60); sleeping 15s"
|
|
36
|
-
sleep 15
|
|
37
|
-
done
|
|
38
|
-
done
|
|
39
|
-
- name: Download published package
|
|
40
|
-
run: |
|
|
41
|
-
npm pack scrabble-solver@"$VERSION"
|
|
42
|
-
mkdir work-dir
|
|
43
|
-
tar -xzf scrabble-solver-*.tgz -C work-dir --strip-components=1
|
|
44
|
-
- run: bun install --frozen-lockfile
|
|
45
|
-
working-directory: work-dir
|
|
46
|
-
- name: Pre-warm dictionaries cache
|
|
47
|
-
run: node packages/dictionaries/bin/update-dictionaries.js
|
|
48
|
-
working-directory: work-dir
|
|
49
|
-
- name: Install Playwright browsers
|
|
50
|
-
run: bunx playwright install --with-deps chromium
|
|
51
|
-
working-directory: work-dir
|
|
52
|
-
- name: Install the published package globally
|
|
53
|
-
run: bun add --global scrabble-solver@${{ env.VERSION }}
|
|
54
|
-
- name: Run e2e tests against the global binary
|
|
55
|
-
run: bunx start-server-and-test scrabble-solver http://localhost:3333 'bunx playwright test'
|
|
56
|
-
working-directory: work-dir
|
|
57
|
-
env:
|
|
58
|
-
PLAYWRIGHT_BASE_URL: http://localhost:3333
|
|
59
|
-
- uses: actions/upload-artifact@v7
|
|
60
|
-
if: failure()
|
|
61
|
-
with:
|
|
62
|
-
name: playwright-artifacts
|
|
63
|
-
path: |
|
|
64
|
-
work-dir/playwright-report
|
|
65
|
-
work-dir/test-results
|
|
66
|
-
if-no-files-found: ignore
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
name: Deploy
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
workflow_dispatch:
|
|
5
|
-
inputs:
|
|
6
|
-
branch:
|
|
7
|
-
description: 'Branch to deploy'
|
|
8
|
-
type: string
|
|
9
|
-
required: true
|
|
10
|
-
default: 'master'
|
|
11
|
-
|
|
12
|
-
permissions: {}
|
|
13
|
-
|
|
14
|
-
concurrency:
|
|
15
|
-
group: deploy
|
|
16
|
-
|
|
17
|
-
jobs:
|
|
18
|
-
deploy:
|
|
19
|
-
runs-on: ubuntu-latest
|
|
20
|
-
steps:
|
|
21
|
-
- name: Deploy
|
|
22
|
-
env:
|
|
23
|
-
BRANCH: ${{ inputs.branch }}
|
|
24
|
-
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
|
|
25
|
-
DEPLOY_KNOWN_HOSTS: ${{ secrets.DEPLOY_KNOWN_HOSTS }}
|
|
26
|
-
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
|
|
27
|
-
run: |
|
|
28
|
-
install -d -m 700 ~/.ssh
|
|
29
|
-
printf '%s\n' "$DEPLOY_SSH_KEY" > ~/.ssh/id_ed25519
|
|
30
|
-
printf '%s\n' "$DEPLOY_KNOWN_HOSTS" > ~/.ssh/known_hosts
|
|
31
|
-
chmod 600 ~/.ssh/id_ed25519
|
|
32
|
-
ssh -o StrictHostKeyChecking=yes -o BatchMode=yes -o ConnectTimeout=30 "deploy@$DEPLOY_HOST" "$BRANCH"
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
name: E2E
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [master]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [master]
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
e2e:
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
steps:
|
|
13
|
-
- uses: actions/checkout@v6
|
|
14
|
-
- uses: oven-sh/setup-bun@v2
|
|
15
|
-
- run: bun install --frozen-lockfile
|
|
16
|
-
- run: bunx playwright install --with-deps chromium
|
|
17
|
-
- run: bun run build
|
|
18
|
-
- run: bunx start-server-and-test start:app http://localhost:3333 test-playwright:run
|
|
19
|
-
- uses: actions/upload-artifact@v7
|
|
20
|
-
if: failure()
|
|
21
|
-
with:
|
|
22
|
-
name: playwright-artifacts
|
|
23
|
-
path: |
|
|
24
|
-
playwright-report
|
|
25
|
-
test-results
|
|
26
|
-
if-no-files-found: ignore
|