Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BDGR-180][WIP] Write new vMix client and mock server #645

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ jobs:
cache-dependency-path: "yarn.lock"
- run: yarn install --immutable --inline-builds

- run: yarn test -- --coverage
- run: yarn test

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
Expand Down Expand Up @@ -112,7 +112,7 @@ jobs:

- run: yarn prisma:migrateProd

- run: yarn test:integration -- --coverage
- run: yarn test:integration

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
Expand Down
2 changes: 1 addition & 1 deletion desktop/e2e/complete/vmix.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
server,
} from "./serverAPI";
import type { CompleteShowType } from "../../src/common/types";
import type VMixConnection from "../../src/main/vmix/vmix";
import type VMixConnection from "@ystv/vmix";
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";

let testShow: CompleteShowType;
Expand Down
62 changes: 62 additions & 0 deletions desktop/e2e/standalone/vmix.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { test, expect } from "./base";

test.use({
enabledIntegrations: ["obs", "ontime", "vmix"],
});

test("load VTs into vMix", async ({ app: [app, page], testMediaPath }) => {
await page.getByRole("button", { name: "Select" }).click();

await page.getByText("Continuity", { exact: true }).click();
await page.getByRole("menuitem", { name: "Test Rundown" }).click();

await page.getByRole("button", { name: "Download", exact: true }).click();

await app.evaluate((_, testMediaPath) => {
globalThis.__MOCK_VMIX((when, vmix, It) => {
when(() => vmix.getFullState())
.thenResolve({
version: "26",
edition: "4k",
inputs: [],
})
.once();
when(() => vmix.addInput("VideoList", It.isString())).thenResolve("123");
when(() => vmix.renameInput("123", It.isString())).thenResolve();
when(() => vmix.clearList("123")).thenResolve();
when(() =>
vmix.getPartialState(`vmix/inputs/input[@shortTitle="VTs"]`),
).thenResolve({ ["@_state"]: "Paused" });
when(() => vmix.addInputToList("123", It.isString())).thenResolve();
when(() => vmix.getFullState()).thenResolve({
version: "26",
edition: "4k",
inputs: [
{
key: "123",
number: 1,
type: "VideoList",
title: "VTs - smpte_bars_15s.mp4",
shortTitle: "VTs",
state: "Paused",
position: 0,
duration: 0,
loop: false,
selectedIndex: 1,
items: [
{
source: testMediaPath,
selected: true,
},
],
},
],
});
});
}, `${testMediaPath}/smpte_bars_15s (#1).mp4`);

await expect(page.getByText("Load", { exact: true })).toBeVisible();
await page.getByRole("button", { name: "Load All VTs" }).click();

await expect(page.getByText("Good to go!")).toBeVisible();
});
110 changes: 61 additions & 49 deletions desktop/electron.vite.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ const visualizeBundle = process.argv.includes("--visualize-bundle");
* can import (and forbid importing @badger/prisma/client).
* However, zod-prisma-types still needs to import the actual Prisma client in one place,
* transformJsonNull.ts, so that it can access Prisma.JsonNull/Prisma.DbNull.
*
*
* To fix this, we stub out this one import, which thereby ensures the Prisma client runtime
* never gets bundled in. This is safe to do, because we will never need to interact with
* Prisma.{Db,Json}Null in Desktop.
*/
const jsonNullStub = "export const transformJsonNull = v => v; export default transformJsonNull;"
const jsonNullStubPlaceholder = "\0ignore_prisma_placeholder"
const jsonNullStub =
"export const transformJsonNull = v => v; export default transformJsonNull;";
const jsonNullStubPlaceholder = "\0ignore_prisma_placeholder";
/** @type {import("vite").Plugin} */
const IgnorePrismaJsonNullPlugin = {
name: "ignorePrismaJsonNull",
Expand All @@ -42,12 +43,14 @@ const IgnorePrismaJsonNullPlugin = {
return null;
},
load(name) {
return name === jsonNullStubPlaceholder ? {
code: jsonNullStub,
moduleSideEffects: false,
} : null;
return name === jsonNullStubPlaceholder
? {
code: jsonNullStub,
moduleSideEffects: false,
}
: null;
},
enforce: "pre"
enforce: "pre",
};

const base = defineConfig({
Expand Down Expand Up @@ -107,49 +110,58 @@ const base = defineConfig({
* @type {import('electron-vite').UserConfig}
*/
const config = {
main: mergeConfig(base, defineConfig({
plugins: [
IgnorePrismaJsonNullPlugin,
commonjs(),
visualizeBundle &&
visualizer({
filename: "bundle-main.html",
}),
].filter(Boolean),
resolve: {
conditions: ["node"],
browserField: false,
},
build: {
sourcemap: true,
}
})),
renderer: mergeConfig(base, defineConfig({
plugins: [
visualizeBundle &&
visualizer({
filename: "bundle-renderer.html",
}),
].filter(Boolean),
build: {
rollupOptions: {
input: "./src/renderer/index.html",
main: mergeConfig(
base,
defineConfig({
plugins: [
IgnorePrismaJsonNullPlugin,
commonjs(),
visualizeBundle &&
visualizer({
filename: "bundle-main.html",
}),
].filter(Boolean),
resolve: {
conditions: ["node", "badger-internal"],
browserField: false,
},
},
})),
preload: mergeConfig(base, defineConfig({
plugins: [
visualizeBundle &&
visualizer({
filename: "bundle-preload.html",
}),
].filter(Boolean),
build: {
lib: {
entry: "./src/common/preload.ts",
build: {
sourcemap: true,
},
},
})),
}),
),
renderer: mergeConfig(
base,
defineConfig({
plugins: [
visualizeBundle &&
visualizer({
filename: "bundle-renderer.html",
}),
].filter(Boolean),
build: {
rollupOptions: {
input: "./src/renderer/index.html",
},
},
}),
),
preload: mergeConfig(
base,
defineConfig({
plugins: [
visualizeBundle &&
visualizer({
filename: "bundle-preload.html",
}),
].filter(Boolean),
build: {
lib: {
entry: "./src/common/preload.ts",
},
},
}),
),
};

export default config;
1 change: 1 addition & 0 deletions desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"@types/react-dom": "^18.2.14",
"@types/uuid": "^9.0.2",
"@types/which": "^3.0.0",
"@ystv/vmix": "workspace:*",
"badger-server": "workspace:*",
"bufferutil": "^4.0.7",
"classnames": "^2.3.2",
Expand Down
2 changes: 1 addition & 1 deletion desktop/src/main/vmix/vMix.mock.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getLogger } from "loglevel";
import { mock, when, It, verify, reset } from "strong-mock";
import VMixConnection from "./vmix";
import VMixConnection from "@ystv/vmix";

const logger = getLogger("vMix.mock");

Expand Down
20 changes: 0 additions & 20 deletions desktop/src/main/vmix/vmix.test.integration.ts

This file was deleted.

Loading
Loading