Skip to content

Commit 1f0fb28

Browse files
authored
Tests except stream shift. (#6050)
1 parent 637a60f commit 1f0fb28

11 files changed

Lines changed: 1237 additions & 168 deletions

File tree

app/components-react/windows/go-live/useGoLiveSettings.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ class GoLiveSettingsState extends StreamInfoView<IGoLiveSettingsState> {
114114
),
115115
});
116116

117-
console.log('updating ', otherEnabledTarget, ' to disabled');
118117
// Update the settings to disable the other enabled platform
119118
updated = {
120119
platforms: {

app/components-react/windows/settings/Stream.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,7 @@ function CustomDestinationList() {
586586

587587
{shouldShowPrimeLabel ? (
588588
<ButtonHighlighted
589+
name="customDestUltraBtn"
589590
onClick={() => addCustomDest(true)}
590591
filled
591592
text={$t('Ultra')}

test/helpers/modules/forms/form.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -282,29 +282,32 @@ export async function readFields(...args: unknown[]): Promise<TFormData> {
282282

283283
/**
284284
* A shortcut for useForm().assertFormContains()
285+
* Pass `indexKey` and `valueKey` to control field lookup (defaults: 'name', 'displayValue')
285286
*/
286287
export async function assertFormContains(
287288
formData: TFormData,
288-
indexKey?: string,
289+
messageOrIndexKey?: string,
290+
indexKeyOrValueKey?: string,
289291
valueKey?: string,
290292
): Promise<unknown>;
291293
export async function assertFormContains(
292294
formName: string,
293295
formData: TFormData,
294-
indexKey?: string,
296+
messageOrIndexKey?: string,
297+
indexKeyOrValueKey?: string,
295298
valueKey?: string,
296299
): Promise<unknown>;
297300
export async function assertFormContains(...args: any[]): Promise<unknown> {
298301
if (typeof args[0] === 'string') {
299-
const [formName, formData, indexKey, valueKey] = args;
302+
const [formName, formData, ...rest] = args;
300303
// TODO: fake hook
301304
// eslint-disable-next-line react-hooks/rules-of-hooks
302-
return useForm(formName).assertFormContains(formData, indexKey, valueKey);
305+
return useForm(formName).assertFormContains(formData, ...rest);
303306
} else {
304-
const [formData, indexKey, valueKey] = args;
307+
const [formData, ...rest] = args;
305308
// TODO: fake hook
306309
// eslint-disable-next-line react-hooks/rules-of-hooks
307-
return useForm().assertFormContains(formData, indexKey, valueKey);
310+
return useForm().assertFormContains(formData, ...rest);
308311
}
309312
}
310313

test/helpers/modules/streaming.ts

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ import { sleep } from '../sleep';
2020
import { fillForm, TFormData, useForm } from './forms';
2121
import { setOutputResolution, showSettingsWindow } from './settings/settings';
2222
import { StreamSettingsService } from '../../../app/services/settings/streaming';
23+
import {
24+
WebsocketService,
25+
IStreamShiftRequested,
26+
IStreamShiftActionCompleted,
27+
} from '../../../app/services/websocket';
28+
import { RestreamService } from '../../../app/services/restream';
2329

2430
/**
2531
* Go live and wait for stream start
@@ -153,13 +159,14 @@ export async function waitForSettingsWindowLoaded() {
153159
}
154160

155161
async function waitForStreamShift() {
156-
// eslint-disable-next-line react-hooks/rules-of-hooks
157-
await useMainWindow(async () => {
158-
const streamShifted = await isDisplayed('span=Another stream detected', { timeout: 5000 });
159-
if (streamShifted) {
160-
await click('span=Force Start');
161-
}
162-
});
162+
// The "Another stream detected" prompt renders in the child window (GoLive)
163+
// via promptAction (Ant Design modal). Check the child window for the prompt
164+
// and dismiss it if found so the go live flow can proceed.
165+
await focusChild();
166+
const streamShifted = await isDisplayed('span=Another stream detected', { timeout: 5000 });
167+
if (streamShifted) {
168+
await click('span=Force Start');
169+
}
163170
}
164171

165172
export async function switchAdvancedMode() {
@@ -238,3 +245,34 @@ export async function addCustomDestination(name: string, url: string, streamKey:
238245
});
239246
await clickButton('Save');
240247
}
248+
249+
/**
250+
* Mock a Stream Shift socket event
251+
*
252+
* @param type - 'streamSwitchRequest' (switch to another device) or
253+
* 'switchActionComplete' (switch to the current device)
254+
* @param identifier - stream id
255+
*/
256+
export async function fireStreamShiftSocketEvent(
257+
type: IStreamShiftRequested['type'] | IStreamShiftActionCompleted['type'],
258+
identifier: string,
259+
): Promise<void> {
260+
const event: IStreamShiftRequested | IStreamShiftActionCompleted = {
261+
type,
262+
for: '',
263+
data: { identifier },
264+
event_id: `test_${type}`,
265+
};
266+
(await getApiClient())
267+
.getResource<WebsocketService>('WebsocketService')
268+
.sendSocketEventForTest(event);
269+
}
270+
271+
/**
272+
* Emit directly on RestreamService.isLive, triggering the GoLive window's subscription
273+
* without going through the real HTTP API. Pass true to show the "Another stream detected"
274+
* prompt; pass false to clear it.
275+
*/
276+
export async function fireIsLiveEvent(isLive: boolean): Promise<void> {
277+
(await getApiClient()).getResource<RestreamService>('RestreamService').emitIsLiveForTest(isLive);
278+
}

test/helpers/modules/user.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import { getContext, TExecutionContext } from '../webdriver';
22
import { TPlatform } from '../../../app/services/platforms';
3-
import { ITestUserFeatures, reserveUserFromPool, logIn as userLogin } from '../webdriver/user';
3+
import {
4+
ITestUser,
5+
ITestUserFeatures,
6+
reserveUserFromPool,
7+
logIn as userLogin,
8+
} from '../webdriver/user';
49
import { click, clickButton } from './core';
510
import { fillForm } from './forms';
611
import { showSettingsWindow } from './settings/settings';
@@ -14,9 +19,13 @@ export function logIn(
1419
return userLogin(getContext(), platform, features, waitForUI, isOnboardingTest);
1520
}
1621

17-
export async function addCustomDestination(t: TExecutionContext) {
18-
const user = await reserveUserFromPool(t, 'twitch');
19-
const name = 'MyCustomDest';
22+
export async function addCustomDestination(
23+
t: TExecutionContext,
24+
destName?: string,
25+
testUser?: ITestUser,
26+
) {
27+
const user = testUser ?? (await reserveUserFromPool(t, 'twitch'));
28+
const name = destName ?? 'MyCustomDest';
2029

2130
// add new destination
2231
await showSettingsWindow('Stream');

test/regular/highlighter.ts

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
11
import { test, useWebdriver } from '../helpers/webdriver';
22
import { setTemporaryRecordingPath } from '../helpers/modules/settings/settings';
3-
import { click, clickButton, focusMain, select, waitForDisplayed } from '../helpers/modules/core';
3+
import { clickButton, focusMain, isDisplayed, waitForDisplayed } from '../helpers/modules/core';
44
import { showPage } from '../helpers/modules/navigation';
55
import {
6+
clickGoLive,
67
prepareToGoLive,
78
stopStream,
89
tryToGoLive,
10+
waitForSettingsWindowLoaded,
911
waitForStreamStart,
1012
} from '../helpers/modules/streaming';
1113
import { logIn } from '../helpers/modules/user';
1214
import { saveReplayBuffer } from '../helpers/modules/replay-buffer';
13-
import { assertFormContains, fillForm } from '../helpers/modules/forms';
15+
import { fillForm } from '../helpers/modules/forms';
1416
import { withUser } from '../helpers/webdriver/user';
1517
const path = require('path');
1618
const fs = require('fs');
1719

20+
// not a react hook
21+
// eslint-disable-next-line react-hooks/rules-of-hooks
1822
useWebdriver();
1923

2024
test('Highlighter save and export', async t => {
@@ -45,11 +49,53 @@ test('Highlighter save and export', async t => {
4549
t.true(fs.existsSync(exportLocation), 'The video file should exist');
4650
});
4751

48-
test.skip('AI Highlighter', withUser('twitch', { prime: true }), async t => {
49-
const recordingDir = await setTemporaryRecordingPath();
50-
52+
test('AI Highlighter', withUser('twitch', { prime: true }), async t => {
53+
// AI Highlighter install button shows
5154
await showPage('Highlighter');
52-
await clickButton('Install AI Highlighter App');
55+
await waitForDisplayed('[name="installHighlighter"]');
5356

57+
// Go live with AI Highlighter enabled
5458
await prepareToGoLive();
59+
await clickGoLive();
60+
await waitForSettingsWindowLoaded();
61+
62+
await fillForm({
63+
title: 'Test stream',
64+
twitchGame: 'Fortnite',
65+
});
66+
67+
// Highlighter div shows
68+
await waitForSettingsWindowLoaded();
69+
t.true(
70+
await isDisplayed('[name="install-highlighter"]'),
71+
'Case 1: Highlighter card should show for supported game',
72+
);
73+
74+
// Highlighter div hides
75+
await fillForm({
76+
twitchGame: 'DOOM',
77+
});
78+
await waitForSettingsWindowLoaded();
79+
t.false(
80+
await isDisplayed('[name="install-highlighter"]'),
81+
'Case 2: Highlighter card should hide for not supported game',
82+
);
83+
84+
// Highlighter div shows again
85+
await fillForm({
86+
twitchGame: 'Fortnite',
87+
});
88+
await waitForSettingsWindowLoaded();
89+
t.true(
90+
await isDisplayed('[name="install-highlighter"]'),
91+
'Case 3: Highlighter card should show when changing from an unsupported game to a supported game',
92+
);
93+
await clickButton('Close');
94+
await clickGoLive();
95+
await waitForSettingsWindowLoaded();
96+
t.true(
97+
await isDisplayed('[name="install-highlighter"]'),
98+
'Case 5: Highlighter card should show for supported game when opening go live window',
99+
);
100+
await clickButton('Close');
55101
});

0 commit comments

Comments
 (0)