mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-03-24 12:11:29 -07:00
test: harden youtube picker test harness
This commit is contained in:
@@ -53,6 +53,122 @@ function createFakeElement() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createYoutubePickerDomFixture() {
|
||||||
|
return {
|
||||||
|
overlay: {
|
||||||
|
classList: createClassList(),
|
||||||
|
focus: () => {},
|
||||||
|
},
|
||||||
|
youtubePickerModal: createFakeElement(),
|
||||||
|
youtubePickerTitle: createFakeElement(),
|
||||||
|
youtubePickerPrimarySelect: createFakeElement(),
|
||||||
|
youtubePickerSecondarySelect: createFakeElement(),
|
||||||
|
youtubePickerTracks: createFakeElement(),
|
||||||
|
youtubePickerStatus: createFakeElement(),
|
||||||
|
youtubePickerContinueButton: createFakeElement(),
|
||||||
|
youtubePickerCloseButton: createFakeElement(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
type YoutubePickerTestWindow = {
|
||||||
|
dispatchEvent: (event: Event & { detail?: unknown }) => boolean;
|
||||||
|
focus: () => void;
|
||||||
|
electronAPI: Record<string, unknown>;
|
||||||
|
};
|
||||||
|
|
||||||
|
function restoreGlobalProp<K extends keyof typeof globalThis>(
|
||||||
|
key: K,
|
||||||
|
originalValue: (typeof globalThis)[K],
|
||||||
|
hadOwnProperty: boolean,
|
||||||
|
) {
|
||||||
|
if (hadOwnProperty) {
|
||||||
|
Object.defineProperty(globalThis, key, {
|
||||||
|
configurable: true,
|
||||||
|
value: originalValue,
|
||||||
|
writable: true,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Reflect.deleteProperty(globalThis, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupYoutubePickerTestEnv(options?: {
|
||||||
|
windowValue?: YoutubePickerTestWindow;
|
||||||
|
customEventValue?: unknown;
|
||||||
|
now?: () => number;
|
||||||
|
}) {
|
||||||
|
const hadWindow = Object.prototype.hasOwnProperty.call(globalThis, 'window');
|
||||||
|
const hadDocument = Object.prototype.hasOwnProperty.call(globalThis, 'document');
|
||||||
|
const hadCustomEvent = Object.prototype.hasOwnProperty.call(globalThis, 'CustomEvent');
|
||||||
|
const originalWindow = globalThis.window;
|
||||||
|
const originalDocument = globalThis.document;
|
||||||
|
const originalCustomEvent = globalThis.CustomEvent;
|
||||||
|
const originalDateNow = Date.now;
|
||||||
|
|
||||||
|
Object.defineProperty(globalThis, 'document', {
|
||||||
|
configurable: true,
|
||||||
|
value: {
|
||||||
|
createElement: () => createFakeElement(),
|
||||||
|
},
|
||||||
|
writable: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(globalThis, 'window', {
|
||||||
|
configurable: true,
|
||||||
|
value:
|
||||||
|
options?.windowValue ??
|
||||||
|
({
|
||||||
|
dispatchEvent: (_event) => true,
|
||||||
|
focus: () => {},
|
||||||
|
electronAPI: {
|
||||||
|
notifyOverlayModalOpened: () => {},
|
||||||
|
notifyOverlayModalClosed: () => {},
|
||||||
|
youtubePickerResolve: async () => ({ ok: true, message: '' }),
|
||||||
|
setIgnoreMouseEvents: () => {},
|
||||||
|
},
|
||||||
|
} satisfies YoutubePickerTestWindow),
|
||||||
|
writable: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (options?.customEventValue) {
|
||||||
|
Object.defineProperty(globalThis, 'CustomEvent', {
|
||||||
|
configurable: true,
|
||||||
|
value: options.customEventValue,
|
||||||
|
writable: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options?.now) {
|
||||||
|
Date.now = options.now;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
restore() {
|
||||||
|
Date.now = originalDateNow;
|
||||||
|
restoreGlobalProp('window', originalWindow, hadWindow);
|
||||||
|
restoreGlobalProp('document', originalDocument, hadDocument);
|
||||||
|
restoreGlobalProp('CustomEvent', originalCustomEvent, hadCustomEvent);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
test('youtube picker test env restore deletes injected globals that were originally absent', () => {
|
||||||
|
assert.equal(Object.prototype.hasOwnProperty.call(globalThis, 'window'), false);
|
||||||
|
assert.equal(Object.prototype.hasOwnProperty.call(globalThis, 'document'), false);
|
||||||
|
|
||||||
|
const env = setupYoutubePickerTestEnv();
|
||||||
|
|
||||||
|
assert.equal(Object.prototype.hasOwnProperty.call(globalThis, 'window'), true);
|
||||||
|
assert.equal(Object.prototype.hasOwnProperty.call(globalThis, 'document'), true);
|
||||||
|
|
||||||
|
env.restore();
|
||||||
|
|
||||||
|
assert.equal(Object.prototype.hasOwnProperty.call(globalThis, 'window'), false);
|
||||||
|
assert.equal(Object.prototype.hasOwnProperty.call(globalThis, 'document'), false);
|
||||||
|
assert.equal(typeof globalThis.window, 'undefined');
|
||||||
|
assert.equal(typeof globalThis.document, 'undefined');
|
||||||
|
});
|
||||||
|
|
||||||
test('youtube track picker close restores focus and mouse-ignore state', () => {
|
test('youtube track picker close restores focus and mouse-ignore state', () => {
|
||||||
const overlayFocusCalls: number[] = [];
|
const overlayFocusCalls: number[] = [];
|
||||||
const windowFocusCalls: number[] = [];
|
const windowFocusCalls: number[] = [];
|
||||||
@@ -61,9 +177,6 @@ test('youtube track picker close restores focus and mouse-ignore state', () => {
|
|||||||
const notifications: string[] = [];
|
const notifications: string[] = [];
|
||||||
const frontendCommands: unknown[] = [];
|
const frontendCommands: unknown[] = [];
|
||||||
const syncCalls: string[] = [];
|
const syncCalls: string[] = [];
|
||||||
const originalWindow = globalThis.window;
|
|
||||||
const originalDocument = globalThis.document;
|
|
||||||
const originalCustomEvent = globalThis.CustomEvent;
|
|
||||||
|
|
||||||
class TestCustomEvent extends Event {
|
class TestCustomEvent extends Event {
|
||||||
detail: unknown;
|
detail: unknown;
|
||||||
@@ -74,16 +187,8 @@ test('youtube track picker close restores focus and mouse-ignore state', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.defineProperty(globalThis, 'document', {
|
const env = setupYoutubePickerTestEnv({
|
||||||
configurable: true,
|
windowValue: {
|
||||||
value: {
|
|
||||||
createElement: () => createFakeElement(),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.defineProperty(globalThis, 'window', {
|
|
||||||
configurable: true,
|
|
||||||
value: {
|
|
||||||
dispatchEvent: (event: Event & { detail?: unknown }) => {
|
dispatchEvent: (event: Event & { detail?: unknown }) => {
|
||||||
frontendCommands.push(event.detail ?? null);
|
frontendCommands.push(event.detail ?? null);
|
||||||
return true;
|
return true;
|
||||||
@@ -104,33 +209,17 @@ test('youtube track picker close restores focus and mouse-ignore state', () => {
|
|||||||
ignoreCalls.push({ ignore, forward: options?.forward });
|
ignoreCalls.push({ ignore, forward: options?.forward });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
} satisfies YoutubePickerTestWindow,
|
||||||
});
|
customEventValue: TestCustomEvent,
|
||||||
|
|
||||||
Object.defineProperty(globalThis, 'CustomEvent', {
|
|
||||||
configurable: true,
|
|
||||||
value: TestCustomEvent,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const state = createRendererState();
|
const state = createRendererState();
|
||||||
const overlay = {
|
const dom = createYoutubePickerDomFixture();
|
||||||
classList: createClassList(),
|
dom.overlay.focus = () => {
|
||||||
focus: () => {
|
overlayFocusCalls.push(1);
|
||||||
overlayFocusCalls.push(1);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const dom = {
|
|
||||||
overlay,
|
|
||||||
youtubePickerModal: createFakeElement(),
|
|
||||||
youtubePickerTitle: createFakeElement(),
|
|
||||||
youtubePickerPrimarySelect: createFakeElement(),
|
|
||||||
youtubePickerSecondarySelect: createFakeElement(),
|
|
||||||
youtubePickerTracks: createFakeElement(),
|
|
||||||
youtubePickerStatus: createFakeElement(),
|
|
||||||
youtubePickerContinueButton: createFakeElement(),
|
|
||||||
youtubePickerCloseButton: createFakeElement(),
|
|
||||||
};
|
};
|
||||||
|
const { overlay } = dom;
|
||||||
|
|
||||||
const modal = createYoutubeTrackPickerModal(
|
const modal = createYoutubeTrackPickerModal(
|
||||||
{
|
{
|
||||||
@@ -171,31 +260,15 @@ test('youtube track picker close restores focus and mouse-ignore state', () => {
|
|||||||
assert.equal(windowFocusCalls.length > 0, true);
|
assert.equal(windowFocusCalls.length > 0, true);
|
||||||
assert.deepEqual(ignoreCalls, [{ ignore: true, forward: true }]);
|
assert.deepEqual(ignoreCalls, [{ ignore: true, forward: true }]);
|
||||||
} finally {
|
} finally {
|
||||||
Object.defineProperty(globalThis, 'window', { configurable: true, value: originalWindow });
|
env.restore();
|
||||||
Object.defineProperty(globalThis, 'document', { configurable: true, value: originalDocument });
|
|
||||||
Object.defineProperty(globalThis, 'CustomEvent', {
|
|
||||||
configurable: true,
|
|
||||||
value: originalCustomEvent,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('youtube track picker re-acknowledges repeated open requests', () => {
|
test('youtube track picker re-acknowledges repeated open requests', () => {
|
||||||
const openedNotifications: string[] = [];
|
const openedNotifications: string[] = [];
|
||||||
const originalWindow = globalThis.window;
|
const env = setupYoutubePickerTestEnv({
|
||||||
const originalDocument = globalThis.document;
|
windowValue: {
|
||||||
|
dispatchEvent: (_event) => true,
|
||||||
Object.defineProperty(globalThis, 'document', {
|
|
||||||
configurable: true,
|
|
||||||
value: {
|
|
||||||
createElement: () => createFakeElement(),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.defineProperty(globalThis, 'window', {
|
|
||||||
configurable: true,
|
|
||||||
value: {
|
|
||||||
dispatchEvent: () => true,
|
|
||||||
focus: () => {},
|
focus: () => {},
|
||||||
electronAPI: {
|
electronAPI: {
|
||||||
notifyOverlayModalOpened: (modal: string) => {
|
notifyOverlayModalOpened: (modal: string) => {
|
||||||
@@ -205,25 +278,12 @@ test('youtube track picker re-acknowledges repeated open requests', () => {
|
|||||||
youtubePickerResolve: async () => ({ ok: true, message: '' }),
|
youtubePickerResolve: async () => ({ ok: true, message: '' }),
|
||||||
setIgnoreMouseEvents: () => {},
|
setIgnoreMouseEvents: () => {},
|
||||||
},
|
},
|
||||||
},
|
} satisfies YoutubePickerTestWindow,
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const state = createRendererState();
|
const state = createRendererState();
|
||||||
const dom = {
|
const dom = createYoutubePickerDomFixture();
|
||||||
overlay: {
|
|
||||||
classList: createClassList(),
|
|
||||||
focus: () => {},
|
|
||||||
},
|
|
||||||
youtubePickerModal: createFakeElement(),
|
|
||||||
youtubePickerTitle: createFakeElement(),
|
|
||||||
youtubePickerPrimarySelect: createFakeElement(),
|
|
||||||
youtubePickerSecondarySelect: createFakeElement(),
|
|
||||||
youtubePickerTracks: createFakeElement(),
|
|
||||||
youtubePickerStatus: createFakeElement(),
|
|
||||||
youtubePickerContinueButton: createFakeElement(),
|
|
||||||
youtubePickerCloseButton: createFakeElement(),
|
|
||||||
};
|
|
||||||
|
|
||||||
const modal = createYoutubeTrackPickerModal(
|
const modal = createYoutubeTrackPickerModal(
|
||||||
{
|
{
|
||||||
@@ -260,26 +320,14 @@ test('youtube track picker re-acknowledges repeated open requests', () => {
|
|||||||
assert.deepEqual(openedNotifications, ['youtube-track-picker', 'youtube-track-picker']);
|
assert.deepEqual(openedNotifications, ['youtube-track-picker', 'youtube-track-picker']);
|
||||||
assert.equal(state.youtubePickerPayload?.sessionId, 'yt-2');
|
assert.equal(state.youtubePickerPayload?.sessionId, 'yt-2');
|
||||||
} finally {
|
} finally {
|
||||||
Object.defineProperty(globalThis, 'window', { configurable: true, value: originalWindow });
|
env.restore();
|
||||||
Object.defineProperty(globalThis, 'document', { configurable: true, value: originalDocument });
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('youtube track picker surfaces rejected resolve calls as modal status', async () => {
|
test('youtube track picker surfaces rejected resolve calls as modal status', async () => {
|
||||||
const originalWindow = globalThis.window;
|
const env = setupYoutubePickerTestEnv({
|
||||||
const originalDocument = globalThis.document;
|
windowValue: {
|
||||||
|
dispatchEvent: (_event) => true,
|
||||||
Object.defineProperty(globalThis, 'document', {
|
|
||||||
configurable: true,
|
|
||||||
value: {
|
|
||||||
createElement: () => createFakeElement(),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.defineProperty(globalThis, 'window', {
|
|
||||||
configurable: true,
|
|
||||||
value: {
|
|
||||||
dispatchEvent: () => true,
|
|
||||||
focus: () => {},
|
focus: () => {},
|
||||||
electronAPI: {
|
electronAPI: {
|
||||||
notifyOverlayModalOpened: () => {},
|
notifyOverlayModalOpened: () => {},
|
||||||
@@ -289,25 +337,12 @@ test('youtube track picker surfaces rejected resolve calls as modal status', asy
|
|||||||
},
|
},
|
||||||
setIgnoreMouseEvents: () => {},
|
setIgnoreMouseEvents: () => {},
|
||||||
},
|
},
|
||||||
},
|
} satisfies YoutubePickerTestWindow,
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const state = createRendererState();
|
const state = createRendererState();
|
||||||
const dom = {
|
const dom = createYoutubePickerDomFixture();
|
||||||
overlay: {
|
|
||||||
classList: createClassList(),
|
|
||||||
focus: () => {},
|
|
||||||
},
|
|
||||||
youtubePickerModal: createFakeElement(),
|
|
||||||
youtubePickerTitle: createFakeElement(),
|
|
||||||
youtubePickerPrimarySelect: createFakeElement(),
|
|
||||||
youtubePickerSecondarySelect: createFakeElement(),
|
|
||||||
youtubePickerTracks: createFakeElement(),
|
|
||||||
youtubePickerStatus: createFakeElement(),
|
|
||||||
youtubePickerContinueButton: createFakeElement(),
|
|
||||||
youtubePickerCloseButton: createFakeElement(),
|
|
||||||
};
|
|
||||||
|
|
||||||
const modal = createYoutubeTrackPickerModal(
|
const modal = createYoutubeTrackPickerModal(
|
||||||
{
|
{
|
||||||
@@ -348,8 +383,7 @@ test('youtube track picker surfaces rejected resolve calls as modal status', asy
|
|||||||
assert.equal(state.youtubePickerModalOpen, true);
|
assert.equal(state.youtubePickerModalOpen, true);
|
||||||
assert.equal(dom.youtubePickerStatus.textContent, 'resolve failed');
|
assert.equal(dom.youtubePickerStatus.textContent, 'resolve failed');
|
||||||
} finally {
|
} finally {
|
||||||
Object.defineProperty(globalThis, 'window', { configurable: true, value: originalWindow });
|
env.restore();
|
||||||
Object.defineProperty(globalThis, 'document', { configurable: true, value: originalDocument });
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -360,21 +394,10 @@ test('youtube track picker ignores duplicate resolve submissions while request i
|
|||||||
primaryTrackId: string | null;
|
primaryTrackId: string | null;
|
||||||
secondaryTrackId: string | null;
|
secondaryTrackId: string | null;
|
||||||
}> = [];
|
}> = [];
|
||||||
const originalWindow = globalThis.window;
|
|
||||||
const originalDocument = globalThis.document;
|
|
||||||
let releaseResolve: (() => void) | null = null;
|
let releaseResolve: (() => void) | null = null;
|
||||||
|
const env = setupYoutubePickerTestEnv({
|
||||||
Object.defineProperty(globalThis, 'document', {
|
windowValue: {
|
||||||
configurable: true,
|
dispatchEvent: (_event) => true,
|
||||||
value: {
|
|
||||||
createElement: () => createFakeElement(),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.defineProperty(globalThis, 'window', {
|
|
||||||
configurable: true,
|
|
||||||
value: {
|
|
||||||
dispatchEvent: () => true,
|
|
||||||
focus: () => {},
|
focus: () => {},
|
||||||
electronAPI: {
|
electronAPI: {
|
||||||
notifyOverlayModalOpened: () => {},
|
notifyOverlayModalOpened: () => {},
|
||||||
@@ -393,25 +416,12 @@ test('youtube track picker ignores duplicate resolve submissions while request i
|
|||||||
},
|
},
|
||||||
setIgnoreMouseEvents: () => {},
|
setIgnoreMouseEvents: () => {},
|
||||||
},
|
},
|
||||||
},
|
} satisfies YoutubePickerTestWindow,
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const state = createRendererState();
|
const state = createRendererState();
|
||||||
const dom = {
|
const dom = createYoutubePickerDomFixture();
|
||||||
overlay: {
|
|
||||||
classList: createClassList(),
|
|
||||||
focus: () => {},
|
|
||||||
},
|
|
||||||
youtubePickerModal: createFakeElement(),
|
|
||||||
youtubePickerTitle: createFakeElement(),
|
|
||||||
youtubePickerPrimarySelect: createFakeElement(),
|
|
||||||
youtubePickerSecondarySelect: createFakeElement(),
|
|
||||||
youtubePickerTracks: createFakeElement(),
|
|
||||||
youtubePickerStatus: createFakeElement(),
|
|
||||||
youtubePickerContinueButton: createFakeElement(),
|
|
||||||
youtubePickerCloseButton: createFakeElement(),
|
|
||||||
};
|
|
||||||
|
|
||||||
const modal = createYoutubeTrackPickerModal(
|
const modal = createYoutubeTrackPickerModal(
|
||||||
{
|
{
|
||||||
@@ -467,26 +477,14 @@ test('youtube track picker ignores duplicate resolve submissions while request i
|
|||||||
assert.equal(dom.youtubePickerContinueButton.disabled, false);
|
assert.equal(dom.youtubePickerContinueButton.disabled, false);
|
||||||
assert.equal(dom.youtubePickerCloseButton.disabled, false);
|
assert.equal(dom.youtubePickerCloseButton.disabled, false);
|
||||||
} finally {
|
} finally {
|
||||||
Object.defineProperty(globalThis, 'window', { configurable: true, value: originalWindow });
|
env.restore();
|
||||||
Object.defineProperty(globalThis, 'document', { configurable: true, value: originalDocument });
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('youtube track picker keeps no-track controls disabled after a rejected continue request', async () => {
|
test('youtube track picker keeps no-track controls disabled after a rejected continue request', async () => {
|
||||||
const originalWindow = globalThis.window;
|
const env = setupYoutubePickerTestEnv({
|
||||||
const originalDocument = globalThis.document;
|
windowValue: {
|
||||||
|
dispatchEvent: (_event) => true,
|
||||||
Object.defineProperty(globalThis, 'document', {
|
|
||||||
configurable: true,
|
|
||||||
value: {
|
|
||||||
createElement: () => createFakeElement(),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.defineProperty(globalThis, 'window', {
|
|
||||||
configurable: true,
|
|
||||||
value: {
|
|
||||||
dispatchEvent: () => true,
|
|
||||||
focus: () => {},
|
focus: () => {},
|
||||||
electronAPI: {
|
electronAPI: {
|
||||||
notifyOverlayModalOpened: () => {},
|
notifyOverlayModalOpened: () => {},
|
||||||
@@ -494,25 +492,12 @@ test('youtube track picker keeps no-track controls disabled after a rejected con
|
|||||||
youtubePickerResolve: async () => ({ ok: false, message: 'still no tracks' }),
|
youtubePickerResolve: async () => ({ ok: false, message: 'still no tracks' }),
|
||||||
setIgnoreMouseEvents: () => {},
|
setIgnoreMouseEvents: () => {},
|
||||||
},
|
},
|
||||||
},
|
} satisfies YoutubePickerTestWindow,
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const state = createRendererState();
|
const state = createRendererState();
|
||||||
const dom = {
|
const dom = createYoutubePickerDomFixture();
|
||||||
overlay: {
|
|
||||||
classList: createClassList(),
|
|
||||||
focus: () => {},
|
|
||||||
},
|
|
||||||
youtubePickerModal: createFakeElement(),
|
|
||||||
youtubePickerTitle: createFakeElement(),
|
|
||||||
youtubePickerPrimarySelect: createFakeElement(),
|
|
||||||
youtubePickerSecondarySelect: createFakeElement(),
|
|
||||||
youtubePickerTracks: createFakeElement(),
|
|
||||||
youtubePickerStatus: createFakeElement(),
|
|
||||||
youtubePickerContinueButton: createFakeElement(),
|
|
||||||
youtubePickerCloseButton: createFakeElement(),
|
|
||||||
};
|
|
||||||
|
|
||||||
const modal = createYoutubeTrackPickerModal(
|
const modal = createYoutubeTrackPickerModal(
|
||||||
{
|
{
|
||||||
@@ -548,52 +533,16 @@ test('youtube track picker keeps no-track controls disabled after a rejected con
|
|||||||
assert.equal(dom.youtubePickerCloseButton.disabled, true);
|
assert.equal(dom.youtubePickerCloseButton.disabled, true);
|
||||||
assert.equal(dom.youtubePickerStatus.textContent, 'still no tracks');
|
assert.equal(dom.youtubePickerStatus.textContent, 'still no tracks');
|
||||||
} finally {
|
} finally {
|
||||||
Object.defineProperty(globalThis, 'window', { configurable: true, value: originalWindow });
|
env.restore();
|
||||||
Object.defineProperty(globalThis, 'document', { configurable: true, value: originalDocument });
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('youtube track picker only consumes handled keys', async () => {
|
test('youtube track picker only consumes handled keys', async () => {
|
||||||
const originalWindow = globalThis.window;
|
const env = setupYoutubePickerTestEnv();
|
||||||
const originalDocument = globalThis.document;
|
|
||||||
|
|
||||||
Object.defineProperty(globalThis, 'document', {
|
|
||||||
configurable: true,
|
|
||||||
value: {
|
|
||||||
createElement: () => createFakeElement(),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.defineProperty(globalThis, 'window', {
|
|
||||||
configurable: true,
|
|
||||||
value: {
|
|
||||||
dispatchEvent: () => true,
|
|
||||||
focus: () => {},
|
|
||||||
electronAPI: {
|
|
||||||
notifyOverlayModalOpened: () => {},
|
|
||||||
notifyOverlayModalClosed: () => {},
|
|
||||||
youtubePickerResolve: async () => ({ ok: true, message: '' }),
|
|
||||||
setIgnoreMouseEvents: () => {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const state = createRendererState();
|
const state = createRendererState();
|
||||||
const dom = {
|
const dom = createYoutubePickerDomFixture();
|
||||||
overlay: {
|
|
||||||
classList: createClassList(),
|
|
||||||
focus: () => {},
|
|
||||||
},
|
|
||||||
youtubePickerModal: createFakeElement(),
|
|
||||||
youtubePickerTitle: createFakeElement(),
|
|
||||||
youtubePickerPrimarySelect: createFakeElement(),
|
|
||||||
youtubePickerSecondarySelect: createFakeElement(),
|
|
||||||
youtubePickerTracks: createFakeElement(),
|
|
||||||
youtubePickerStatus: createFakeElement(),
|
|
||||||
youtubePickerContinueButton: createFakeElement(),
|
|
||||||
youtubePickerCloseButton: createFakeElement(),
|
|
||||||
};
|
|
||||||
|
|
||||||
const modal = createYoutubeTrackPickerModal(
|
const modal = createYoutubeTrackPickerModal(
|
||||||
{
|
{
|
||||||
@@ -635,8 +584,7 @@ test('youtube track picker only consumes handled keys', async () => {
|
|||||||
);
|
);
|
||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
} finally {
|
} finally {
|
||||||
Object.defineProperty(globalThis, 'window', { configurable: true, value: originalWindow });
|
env.restore();
|
||||||
Object.defineProperty(globalThis, 'document', { configurable: true, value: originalDocument });
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -647,24 +595,11 @@ test('youtube track picker ignores immediate Enter after open before allowing ke
|
|||||||
primaryTrackId: string | null;
|
primaryTrackId: string | null;
|
||||||
secondaryTrackId: string | null;
|
secondaryTrackId: string | null;
|
||||||
}> = [];
|
}> = [];
|
||||||
const originalWindow = globalThis.window;
|
|
||||||
const originalDocument = globalThis.document;
|
|
||||||
const originalDateNow = Date.now;
|
|
||||||
let now = 10_000;
|
let now = 10_000;
|
||||||
|
const env = setupYoutubePickerTestEnv({
|
||||||
Object.defineProperty(globalThis, 'document', {
|
now: () => now,
|
||||||
configurable: true,
|
windowValue: {
|
||||||
value: {
|
dispatchEvent: (_event) => true,
|
||||||
createElement: () => createFakeElement(),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Date.now = () => now;
|
|
||||||
|
|
||||||
Object.defineProperty(globalThis, 'window', {
|
|
||||||
configurable: true,
|
|
||||||
value: {
|
|
||||||
dispatchEvent: () => true,
|
|
||||||
focus: () => {},
|
focus: () => {},
|
||||||
electronAPI: {
|
electronAPI: {
|
||||||
notifyOverlayModalOpened: () => {},
|
notifyOverlayModalOpened: () => {},
|
||||||
@@ -680,25 +615,12 @@ test('youtube track picker ignores immediate Enter after open before allowing ke
|
|||||||
},
|
},
|
||||||
setIgnoreMouseEvents: () => {},
|
setIgnoreMouseEvents: () => {},
|
||||||
},
|
},
|
||||||
},
|
} satisfies YoutubePickerTestWindow,
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const state = createRendererState();
|
const state = createRendererState();
|
||||||
const dom = {
|
const dom = createYoutubePickerDomFixture();
|
||||||
overlay: {
|
|
||||||
classList: createClassList(),
|
|
||||||
focus: () => {},
|
|
||||||
},
|
|
||||||
youtubePickerModal: createFakeElement(),
|
|
||||||
youtubePickerTitle: createFakeElement(),
|
|
||||||
youtubePickerPrimarySelect: createFakeElement(),
|
|
||||||
youtubePickerSecondarySelect: createFakeElement(),
|
|
||||||
youtubePickerTracks: createFakeElement(),
|
|
||||||
youtubePickerStatus: createFakeElement(),
|
|
||||||
youtubePickerContinueButton: createFakeElement(),
|
|
||||||
youtubePickerCloseButton: createFakeElement(),
|
|
||||||
};
|
|
||||||
|
|
||||||
const modal = createYoutubeTrackPickerModal(
|
const modal = createYoutubeTrackPickerModal(
|
||||||
{
|
{
|
||||||
@@ -761,9 +683,7 @@ test('youtube track picker ignores immediate Enter after open before allowing ke
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
} finally {
|
} finally {
|
||||||
Date.now = originalDateNow;
|
env.restore();
|
||||||
Object.defineProperty(globalThis, 'window', { configurable: true, value: originalWindow });
|
|
||||||
Object.defineProperty(globalThis, 'document', { configurable: true, value: originalDocument });
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -774,20 +694,9 @@ test('youtube track picker uses track list as the source of truth for available
|
|||||||
primaryTrackId: string | null;
|
primaryTrackId: string | null;
|
||||||
secondaryTrackId: string | null;
|
secondaryTrackId: string | null;
|
||||||
}> = [];
|
}> = [];
|
||||||
const originalWindow = globalThis.window;
|
const env = setupYoutubePickerTestEnv({
|
||||||
const originalDocument = globalThis.document;
|
windowValue: {
|
||||||
|
dispatchEvent: (_event) => true,
|
||||||
Object.defineProperty(globalThis, 'document', {
|
|
||||||
configurable: true,
|
|
||||||
value: {
|
|
||||||
createElement: () => createFakeElement(),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.defineProperty(globalThis, 'window', {
|
|
||||||
configurable: true,
|
|
||||||
value: {
|
|
||||||
dispatchEvent: () => true,
|
|
||||||
focus: () => {},
|
focus: () => {},
|
||||||
electronAPI: {
|
electronAPI: {
|
||||||
notifyOverlayModalOpened: () => {},
|
notifyOverlayModalOpened: () => {},
|
||||||
@@ -803,25 +712,12 @@ test('youtube track picker uses track list as the source of truth for available
|
|||||||
},
|
},
|
||||||
setIgnoreMouseEvents: () => {},
|
setIgnoreMouseEvents: () => {},
|
||||||
},
|
},
|
||||||
},
|
} satisfies YoutubePickerTestWindow,
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const state = createRendererState();
|
const state = createRendererState();
|
||||||
const dom = {
|
const dom = createYoutubePickerDomFixture();
|
||||||
overlay: {
|
|
||||||
classList: createClassList(),
|
|
||||||
focus: () => {},
|
|
||||||
},
|
|
||||||
youtubePickerModal: createFakeElement(),
|
|
||||||
youtubePickerTitle: createFakeElement(),
|
|
||||||
youtubePickerPrimarySelect: createFakeElement(),
|
|
||||||
youtubePickerSecondarySelect: createFakeElement(),
|
|
||||||
youtubePickerTracks: createFakeElement(),
|
|
||||||
youtubePickerStatus: createFakeElement(),
|
|
||||||
youtubePickerContinueButton: createFakeElement(),
|
|
||||||
youtubePickerCloseButton: createFakeElement(),
|
|
||||||
};
|
|
||||||
|
|
||||||
const modal = createYoutubeTrackPickerModal(
|
const modal = createYoutubeTrackPickerModal(
|
||||||
{
|
{
|
||||||
@@ -868,7 +764,6 @@ test('youtube track picker uses track list as the source of truth for available
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
} finally {
|
} finally {
|
||||||
Object.defineProperty(globalThis, 'window', { configurable: true, value: originalWindow });
|
env.restore();
|
||||||
Object.defineProperty(globalThis, 'document', { configurable: true, value: originalDocument });
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user