Skip to content

Commit 0464b27

Browse files
committed
test: expanded tests for creator interface
Minor typos fixed
1 parent f29c49c commit 0464b27

File tree

3 files changed

+272
-18
lines changed

3 files changed

+272
-18
lines changed

e2e/creator.spec.ts

+251-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import { test, expect } from '@playwright/test';
2-
2+
import { mockEveryVoiceAPI } from './fixtures/data-fixture';
3+
import fs from 'fs';
34
test.describe('test creator interface', () => {
4-
test('check UI', async ({ page }) => {
5+
test.beforeEach('Setup', async ({ page }) => {
6+
mockEveryVoiceAPI(page);
57
await page.goto('/create');
8+
});
9+
test('check UI', async ({ page }) => {
610
await expect(
711
page.getByTestId('config-file-importer'),
812
'should have config loader '
@@ -17,4 +21,249 @@ test.describe('test creator interface', () => {
1721
'should have creator link'
1822
).toBeVisible();
1923
});
24+
test('check create configuration', async ({ page }) => {
25+
await page.locator('#step-config-tab').click({ force: true });
26+
await page.locator('#input-config-tab').click({ force: true });
27+
await expect(
28+
page.locator('#save_config'),
29+
'save configuration should be disabled'
30+
).toHaveAttribute('disabled');
31+
await page.getByLabel('Title of activity').fill('transcribe test');
32+
33+
await page.getByLabel('API').fill('https://mock-api.dev/');
34+
await page
35+
.getByLabel('Instruction for this activity')
36+
.fill('transcribe what you hear');
37+
await expect(
38+
page.getByText(/API endpoint is reachable/),
39+
'alert api status'
40+
).toBeVisible();
41+
await expect(
42+
page.locator('#save_config'),
43+
'save configuration should be enabled'
44+
).not.toHaveAttribute('disabled');
45+
const download = page.waitForEvent('download');
46+
await page.locator('#save_config').click();
47+
const configFile = JSON.parse(
48+
fs.readFileSync(await (await download).path(), {
49+
encoding: 'utf8',
50+
flag: 'r',
51+
})
52+
);
53+
await expect(
54+
configFile.title,
55+
'Downloaded configuration file title is correct'
56+
).toMatch('transcribe test');
57+
await expect(
58+
configFile.text_instructions,
59+
'Downloaded configuration file instruction is correct'
60+
).toMatch('transcribe what you hear');
61+
await expect(
62+
configFile.api,
63+
'Downloaded configuration file api is correct'
64+
).toMatch('https://mock-api.dev/');
65+
});
66+
test('check load configuration', async ({ page }) => {
67+
const config = JSON.parse(
68+
fs.readFileSync('e2e/fixtures/test-config.json', {
69+
encoding: 'utf8',
70+
flag: 'r',
71+
})
72+
);
73+
74+
await page.locator('#step-config-tab').click({ force: true });
75+
await page.locator('#input-config-tab').click({ force: true });
76+
await expect(
77+
page.locator('#save_config'),
78+
'save configuration should be disabled'
79+
).toHaveAttribute('disabled');
80+
await expect(
81+
page.getByLabel('Title of activity'),
82+
'title should be empty'
83+
).toBeEmpty();
84+
await page.locator('#load-config-tab').click({ force: true });
85+
await page
86+
.getByTestId('config-file-importer')
87+
.setInputFiles('e2e/fixtures/test-config.json');
88+
await expect(
89+
page.getByText(/Activity parameters have been loaded/),
90+
'alert config loaded'
91+
).toBeVisible();
92+
await expect(
93+
page.getByText(/API endpoint is reachable/),
94+
'alert api status'
95+
).toBeVisible();
96+
//go back config tab to verify data
97+
await page.locator('#step-config-tab').click({ force: true });
98+
await page.locator('#input-config-tab').click({ force: true });
99+
await expect(
100+
page.locator('#save_config'),
101+
'save configuration should be enabled'
102+
).not.toHaveAttribute('disabled');
103+
await expect(
104+
page.getByLabel('Title of activity'),
105+
'title should have correct value'
106+
).toHaveValue(config.title);
107+
await expect(
108+
page.getByLabel('API', { exact: true }),
109+
'api should have correct value'
110+
).toHaveValue(config.api);
111+
});
112+
test('check create data', async ({ page }) => {
113+
await page.locator('#step-data-tab').click({ force: true });
114+
await page.locator('#input-data-tab').click({ force: true });
115+
116+
const textBox = page.getByLabel('Data for this activity');
117+
const addDataBtn = page.getByTestId('add_data');
118+
const exportDataBtn = page.getByTestId('export_data');
119+
const dataList = page.getByTestId('data_list');
120+
await expect(textBox, 'text box should be visible').toBeVisible();
121+
await expect(
122+
addDataBtn,
123+
'add data button should be disabled'
124+
).toHaveAttribute('disabled');
125+
await expect(
126+
exportDataBtn,
127+
'export data button should be disabled'
128+
).toHaveAttribute('disabled');
129+
await expect(
130+
dataList.locator('span'),
131+
'data list should be empty'
132+
).toHaveCount(0);
133+
134+
await textBox.fill('X̱EX̱E ÁLḴ ȻEȻENSIEW̱');
135+
await textBox.blur();
136+
await expect(
137+
addDataBtn,
138+
'add data button should be enabled'
139+
).not.toHaveAttribute('disabled');
140+
await expect(
141+
exportDataBtn,
142+
'export data button should be disabled'
143+
).toHaveAttribute('disabled');
144+
await addDataBtn.click({ force: true });
145+
await expect(
146+
dataList.locator('span'),
147+
'data list should have data'
148+
).toHaveCount(1);
149+
150+
await expect(
151+
exportDataBtn,
152+
'export data button should be enabled'
153+
).not.toHaveAttribute('disabled');
154+
const download = page.waitForEvent('download');
155+
await exportDataBtn.click();
156+
const dataFile = JSON.parse(
157+
fs.readFileSync(await (await download).path(), {
158+
encoding: 'utf8',
159+
flag: 'r',
160+
})
161+
);
162+
expect(dataFile[0].orthography, 'verify data file').toMatch(
163+
'X̱EX̱E ÁLḴ ȻEȻENSIEW̱'
164+
);
165+
});
166+
test('check load data', async ({ page }) => {
167+
const data = JSON.parse(
168+
fs.readFileSync('e2e/fixtures/test-data.json', {
169+
encoding: 'utf8',
170+
flag: 'r',
171+
})
172+
);
173+
await page.locator('#step-data-tab').click({ force: true });
174+
await page.locator('#input-data-tab').click({ force: true });
175+
const dataList = page.getByTestId('data_list');
176+
await expect(
177+
dataList.locator('span'),
178+
'data list should be empty'
179+
).toHaveCount(0);
180+
await page.locator('#load-data-tab').click({ force: true });
181+
await page
182+
.getByTestId('data-file-importer')
183+
.setInputFiles('e2e/fixtures/test-data.json');
184+
await expect(
185+
page.getByText(/Activity data have been loaded/),
186+
'alert data loaded'
187+
).toBeVisible();
188+
await expect(
189+
dataList.locator('span'),
190+
'data list should have data'
191+
).toHaveCount(data.length);
192+
let r = 0;
193+
for (const row of await dataList.locator('span').all()) {
194+
expect(row, `should contain text ${data[r].orthography}`).toContainText(
195+
data[r].orthography
196+
);
197+
r++;
198+
}
199+
});
200+
test('check preview and export', async ({ page }) => {
201+
const data = JSON.parse(
202+
fs.readFileSync('e2e/fixtures/test-activity.json', {
203+
encoding: 'utf8',
204+
flag: 'r',
205+
})
206+
);
207+
const exportActivityButton = page.locator('#step-export-activity-button');
208+
expect(
209+
exportActivityButton,
210+
'export button should be disabled'
211+
).toHaveAttribute('disabled');
212+
await page.locator('#load-config-tab').click({ force: true });
213+
await page
214+
.getByTestId('config-file-importer')
215+
.setInputFiles('e2e/fixtures/test-config.json');
216+
await expect(
217+
page.getByText(/Activity parameters have been loaded/),
218+
'alert config loaded'
219+
).toBeVisible();
220+
expect(
221+
exportActivityButton,
222+
'export button should be disabled'
223+
).toHaveAttribute('disabled');
224+
await page
225+
.getByTestId('data-file-importer')
226+
.setInputFiles('e2e/fixtures/test-data.json');
227+
await expect(
228+
page.getByText(/Activity data have been loaded/),
229+
'alert config loaded'
230+
).toBeVisible();
231+
expect(
232+
exportActivityButton,
233+
'export button should be enabled'
234+
).not.toHaveAttribute('disabled');
235+
await expect(
236+
page.getByTestId('start_activity'),
237+
'should have start button'
238+
).toBeVisible();
239+
await page.getByTestId('start_activity').click({ force: true });
240+
//Give the correct answer and check the results
241+
await expect(
242+
page.getByText('Audio generated'),
243+
'should display notice about audio'
244+
).toBeVisible();
245+
await expect(
246+
exportActivityButton,
247+
'export data button should be enabled'
248+
).not.toHaveAttribute('disabled');
249+
const download = page.waitForEvent('download');
250+
await exportActivityButton.click();
251+
const activityFile = JSON.parse(
252+
fs.readFileSync(await (await download).path(), {
253+
encoding: 'utf8',
254+
flag: 'r',
255+
})
256+
);
257+
await expect(
258+
activityFile.configuration.title,
259+
'title should have correct value'
260+
).toMatch(data.configuration.title);
261+
await expect(
262+
activityFile.configuration.api,
263+
'api should have correct value'
264+
).toMatch(data.configuration.api);
265+
expect(activityFile.data, 'data should have correct value').toMatch(
266+
data.data
267+
);
268+
});
20269
});

src/app/transcribing-activity-configuration/transcribing-activity-configuration.component.html

+8-9
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ <h3>Create a transcription activity</h3>
3030
Step 3: Preview
3131
</md-primary-tab>
3232
<md-filled-button
33-
mat-button
34-
id="step-export-tab"
33+
id="step-export-activity-button"
3534
[active]="configStep == 4"
3635
(click)="exportActivity()"
3736
[disabled]="data.length < 2 || !api_is_reachable"
@@ -210,7 +209,6 @@ <h3>Create a transcription activity</h3>
210209
</div>
211210
</div>
212211
<md-filled-button
213-
mat-button
214212
id="save_config"
215213
(click)="exportActivityConfiguration()"
216214
[disabled]="activityConfigurationForm.value.title.length < 3"
@@ -234,8 +232,8 @@ <h3>Create a transcription activity</h3>
234232
Create Data
235233
</md-primary-tab>
236234
<md-primary-tab
237-
id="load-config-tab"
238-
aria-controls="load-config-panel"
235+
id="load-data-tab"
236+
aria-controls="load-data-panel"
239237
[active]="activityDataActiveTab == 1"
240238
(click)="activityDataActiveTab = 1"
241239
>
@@ -278,24 +276,25 @@ <h3>Create a transcription activity</h3>
278276

279277
<div class="">
280278
<md-outlined-button
281-
mat-button
279+
data-test-id="add_data"
282280
class="btn btn-xl btn-primary me-2"
283281
(click)="addWord($event)"
282+
[disabled]="new_word.length < 1"
284283
>
285284
Add
286285
</md-outlined-button>
287286

288287
<md-filled-tonal-button
289-
mat-button
288+
data-test-id="export_data"
290289
class="btn btn-xl btn-info"
291290
(click)="exportActivityData()"
292291
[disabled]="data.length < 1"
293292
>
294-
Export Word List
293+
Export List
295294
</md-filled-tonal-button>
296295
</div>
297296

298-
<div class="">
297+
<div class="" data-test-id="data_list">
299298
@for( word of data; track word){
300299
<span class="btn btn-outline-secondary m-1">
301300
{{ word.orthography }}

src/app/transcribing-activity-configuration/transcribing-activity-configuration.component.ts

+13-7
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ export class TranscribingActivityConfigurationComponent {
221221
this.activityConfigurationForm.patchValue(
222222
JSON.parse(b64_to_utf8(text.substring(text.indexOf('base64,') + 7)))
223223
);
224-
this.toastr.success('Activity parameters have be loaded');
224+
this.toastr.success('Activity parameters have been loaded');
225225
if (this.activityConfigurationForm.value.title.length)
226226
this.configStep = 2;
227227
this.update_api_status();
@@ -242,7 +242,7 @@ export class TranscribingActivityConfigurationComponent {
242242
if (data[0] !== undefined && data[0]['orthography']) {
243243
this.data = data as Word[];
244244

245-
this.toastr.success('Activity data have be loaded');
245+
this.toastr.success('Activity data have been loaded');
246246
if (this.activityConfigurationForm.value.title.length)
247247
this.previewActivity();
248248
} else {
@@ -255,11 +255,16 @@ export class TranscribingActivityConfigurationComponent {
255255
'checking api status',
256256
this.activityConfigurationForm.value.api
257257
);
258-
if (this.activityConfigurationForm.value.api.length)
259-
fetch(this.activityConfigurationForm.value.api, {
260-
method: 'OPTIONS',
261-
headers: new Headers({ mode: 'no-cors' }),
262-
})
258+
if (this.activityConfigurationForm.value.api.length) {
259+
const API =
260+
(this.activityConfigurationForm.value.api.match(/\//g) || []).length > 2
261+
? this.activityConfigurationForm.value.api.substr(
262+
0,
263+
this.activityConfigurationForm.value.api.lastIndexOf('/')
264+
)
265+
: this.activityConfigurationForm.value.api;
266+
267+
fetch(API + '/gradio_api/info')
263268
.then(() => {
264269
this.api_is_reachable = true;
265270
this.toastr.success('API endpoint is reachable');
@@ -268,6 +273,7 @@ export class TranscribingActivityConfigurationComponent {
268273
this.api_is_reachable = false;
269274
this.toastr.error(`API endpoint could not be reached \n${err}`);
270275
});
276+
}
271277
}
272278
updateData($event: Event) {
273279
this.new_word = ($event.currentTarget as HTMLInputElement)?.value;

0 commit comments

Comments
 (0)