@tui-sandbox/library 5.1.2 → 6.0.0
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/CHANGELOG.md +11 -0
- package/dist/src/scripts/tui.js +13 -5
- package/dist/src/server/TestServer.d.ts +1 -2
- package/dist/src/server/TestServer.js +1 -3
- package/dist/src/server/cypress-support/contents.d.ts +1 -0
- package/dist/src/server/cypress-support/contents.js +60 -0
- package/dist/src/server/cypress-support/contents.test.d.ts +1 -0
- package/dist/src/server/cypress-support/contents.test.js +55 -0
- package/dist/src/server/cypress-support/createCypressSupportFile.d.ts +11 -0
- package/dist/src/server/cypress-support/createCypressSupportFile.js +29 -0
- package/dist/src/server/cypress-support/createCypressSupportFile.test.d.ts +1 -0
- package/dist/src/server/cypress-support/createCypressSupportFile.test.js +35 -0
- package/dist/src/server/server.d.ts +1 -1
- package/dist/src/server/server.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -4
- package/src/scripts/tui.ts +14 -5
- package/src/server/TestServer.ts +1 -5
- package/src/server/cypress-support/contents.test.ts +56 -0
- package/src/server/cypress-support/contents.ts +64 -0
- package/src/server/cypress-support/createCypressSupportFile.test.ts +44 -0
- package/src/server/cypress-support/createCypressSupportFile.ts +40 -0
- package/src/server/server.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tui-sandbox/library",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"@catppuccin/palette": "1.7.1",
|
|
11
|
-
"@trpc/client": "11.0.0-rc.
|
|
12
|
-
"@trpc/server": "11.0.0-rc.
|
|
11
|
+
"@trpc/client": "11.0.0-rc.638",
|
|
12
|
+
"@trpc/server": "11.0.0-rc.638",
|
|
13
13
|
"@xterm/addon-attach": "0.11.0",
|
|
14
14
|
"@xterm/addon-fit": "0.10.0",
|
|
15
15
|
"@xterm/xterm": "5.5.0",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"node-pty": "1.0.0",
|
|
23
23
|
"prettier": "3.3.3",
|
|
24
24
|
"tsx": "4.19.2",
|
|
25
|
-
"type-fest": "4.
|
|
25
|
+
"type-fest": "4.27.0",
|
|
26
26
|
"winston": "3.17.0",
|
|
27
27
|
"zod": "3.23.8"
|
|
28
28
|
},
|
|
@@ -36,6 +36,10 @@
|
|
|
36
36
|
"vite": "5.4.11",
|
|
37
37
|
"vitest": "2.1.5"
|
|
38
38
|
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"cypress": "^13",
|
|
41
|
+
"type-fest": "4.27.0"
|
|
42
|
+
},
|
|
39
43
|
"scripts": {
|
|
40
44
|
"build": "concurrently --names 'vite,tsc' 'vite build' 'tsc' --prefix-colors blue,green",
|
|
41
45
|
"dev": "concurrently --names 'client,server' 'pnpm dev:client' 'pnpm dev:server' --prefix-colors blue,green",
|
package/src/scripts/tui.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { stat } from "node:fs/promises"
|
|
2
2
|
import path from "node:path"
|
|
3
|
-
import {
|
|
3
|
+
import { createCypressSupportFile } from "../server/cypress-support/createCypressSupportFile.js"
|
|
4
|
+
import type { TestServerConfig } from "../server/index.js"
|
|
5
|
+
import { startTestServer, updateTestdirectorySchemaFile } from "../server/index.js"
|
|
4
6
|
|
|
5
7
|
//
|
|
6
8
|
// This is the main entrypoint to tui-sandbox
|
|
@@ -12,18 +14,25 @@ const args = process.argv.slice(2)
|
|
|
12
14
|
if (args[0] !== "start") {
|
|
13
15
|
throw new Error(`Usage: tui start`)
|
|
14
16
|
}
|
|
17
|
+
const outputFileName = "MyTestDirectory.ts"
|
|
15
18
|
|
|
16
19
|
/** The cwd in the user's directory when they are running this script. Not the
|
|
17
20
|
* cwd of the script itself. */
|
|
18
21
|
const cwd = process.cwd()
|
|
19
|
-
console.log(`🚀 Starting test server in ${cwd}
|
|
20
|
-
await stat(path.join(cwd,
|
|
22
|
+
console.log(`🚀 Starting test server in ${cwd} - this should be the root of your integration-tests directory 🤞🏻`)
|
|
23
|
+
await stat(path.join(cwd, outputFileName))
|
|
21
24
|
|
|
22
25
|
try {
|
|
23
|
-
|
|
26
|
+
const config = {
|
|
24
27
|
testEnvironmentPath: path.join(cwd, "test-environment/"),
|
|
25
|
-
outputFilePath: path.join(cwd,
|
|
28
|
+
outputFilePath: path.join(cwd, outputFileName),
|
|
29
|
+
} satisfies TestServerConfig
|
|
30
|
+
await createCypressSupportFile({
|
|
31
|
+
cypressSupportDirectoryPath: path.join(cwd, "cypress", "support"),
|
|
32
|
+
supportFileName: "tui-sandbox.ts",
|
|
26
33
|
})
|
|
34
|
+
await updateTestdirectorySchemaFile(config)
|
|
35
|
+
await startTestServer(config)
|
|
27
36
|
} catch (e) {
|
|
28
37
|
console.error(e)
|
|
29
38
|
}
|
package/src/server/TestServer.ts
CHANGED
|
@@ -6,8 +6,6 @@ import express from "express"
|
|
|
6
6
|
import { accessSync } from "fs"
|
|
7
7
|
import path from "path"
|
|
8
8
|
import { fileURLToPath } from "url"
|
|
9
|
-
import type { TestServerConfig } from "./updateTestdirectorySchemaFile.js"
|
|
10
|
-
import { updateTestdirectorySchemaFile } from "./updateTestdirectorySchemaFile.js"
|
|
11
9
|
|
|
12
10
|
export type TestServerSettings = {
|
|
13
11
|
port: number
|
|
@@ -19,11 +17,9 @@ const __dirname = path.dirname(__filename)
|
|
|
19
17
|
export class TestServer {
|
|
20
18
|
public constructor(private readonly settings: TestServerSettings) {}
|
|
21
19
|
|
|
22
|
-
public async startAndRun(appRouter: AnyTRPCRouter
|
|
20
|
+
public async startAndRun(appRouter: AnyTRPCRouter): Promise<void> {
|
|
23
21
|
console.log("🚀 Server starting")
|
|
24
22
|
|
|
25
|
-
await updateTestdirectorySchemaFile(config)
|
|
26
|
-
|
|
27
23
|
const app = express()
|
|
28
24
|
app.use(
|
|
29
25
|
"/trpc",
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { createCypressSupportFileContents } from "./contents.js"
|
|
2
|
+
|
|
3
|
+
it("should return the expected contents", async () => {
|
|
4
|
+
// this test is to help track breaking changes with releases
|
|
5
|
+
expect(await createCypressSupportFileContents()).toMatchInlineSnapshot(`
|
|
6
|
+
"/// <reference types="cypress" />
|
|
7
|
+
//
|
|
8
|
+
// This file is autogenerated by tui-sandbox. Do not edit it directly.
|
|
9
|
+
//
|
|
10
|
+
import type { StartNeovimGenericArguments } from "@tui-sandbox/library/dist/src/server/types"
|
|
11
|
+
import type { OverrideProperties } from "type-fest"
|
|
12
|
+
import type { MyTestDirectory, MyTestDirectoryFile } from "../../MyTestDirectory"
|
|
13
|
+
|
|
14
|
+
export type NeovimContext = {
|
|
15
|
+
contents: MyTestDirectory
|
|
16
|
+
rootPathAbsolute: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
declare global {
|
|
20
|
+
interface Window {
|
|
21
|
+
startNeovim(startArguments?: MyStartNeovimServerArguments): Promise<NeovimContext>
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type MyStartNeovimServerArguments = OverrideProperties<
|
|
26
|
+
StartNeovimGenericArguments,
|
|
27
|
+
{
|
|
28
|
+
filename?: MyTestDirectoryFile | { openInVerticalSplits: MyTestDirectoryFile[] }
|
|
29
|
+
// NOTE: right now you need to make sure the config-modifications directory exists in your test directory
|
|
30
|
+
startupScriptModifications?: Array<keyof MyTestDirectory["config-modifications"]["contents"]>
|
|
31
|
+
}
|
|
32
|
+
>
|
|
33
|
+
|
|
34
|
+
Cypress.Commands.add("startNeovim", (startArguments?: MyStartNeovimServerArguments) => {
|
|
35
|
+
cy.window().then(async win => {
|
|
36
|
+
return await win.startNeovim(startArguments)
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
Cypress.Commands.add("typeIntoTerminal", (text: string, options?: Partial<Cypress.TypeOptions>) => {
|
|
41
|
+
// the syntax for keys is described here:
|
|
42
|
+
// https://docs.cypress.io/api/commands/type
|
|
43
|
+
cy.get("textarea").focus().type(text, options)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
declare global {
|
|
47
|
+
namespace Cypress {
|
|
48
|
+
interface Chainable {
|
|
49
|
+
startNeovim(args?: MyStartNeovimServerArguments): Chainable<NeovimContext>
|
|
50
|
+
typeIntoTerminal(text: string, options?: Partial<Cypress.TypeOptions>): Chainable<void>
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
"
|
|
55
|
+
`)
|
|
56
|
+
})
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { format, resolveConfig } from "prettier"
|
|
2
|
+
import { fileURLToPath } from "url"
|
|
3
|
+
|
|
4
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
5
|
+
|
|
6
|
+
export async function createCypressSupportFileContents(): Promise<string> {
|
|
7
|
+
// this is the interface of tui-sandbox as far as cypress in the user's
|
|
8
|
+
// application is concerned
|
|
9
|
+
let text = `
|
|
10
|
+
/// <reference types="cypress" />
|
|
11
|
+
//
|
|
12
|
+
// This file is autogenerated by tui-sandbox. Do not edit it directly.
|
|
13
|
+
//
|
|
14
|
+
import type { OverrideProperties } from "type-fest"
|
|
15
|
+
import type { StartNeovimGenericArguments } from "@tui-sandbox/library/dist/src/server/types"
|
|
16
|
+
import type { MyTestDirectory, MyTestDirectoryFile } from "../../MyTestDirectory"
|
|
17
|
+
|
|
18
|
+
export type NeovimContext = {
|
|
19
|
+
contents: MyTestDirectory
|
|
20
|
+
rootPathAbsolute: string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
declare global {
|
|
24
|
+
interface Window {
|
|
25
|
+
startNeovim(startArguments?: MyStartNeovimServerArguments): Promise<NeovimContext>
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type MyStartNeovimServerArguments = OverrideProperties<
|
|
30
|
+
StartNeovimGenericArguments,
|
|
31
|
+
{
|
|
32
|
+
filename?: MyTestDirectoryFile | { openInVerticalSplits: MyTestDirectoryFile[] }
|
|
33
|
+
// NOTE: right now you need to make sure the config-modifications directory exists in your test directory
|
|
34
|
+
startupScriptModifications?: Array<keyof MyTestDirectory["config-modifications"]["contents"]>
|
|
35
|
+
}
|
|
36
|
+
>
|
|
37
|
+
|
|
38
|
+
Cypress.Commands.add("startNeovim", (startArguments?: MyStartNeovimServerArguments) => {
|
|
39
|
+
cy.window().then(async win => {
|
|
40
|
+
return await win.startNeovim(startArguments)
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
Cypress.Commands.add("typeIntoTerminal", (text: string, options?: Partial<Cypress.TypeOptions>) => {
|
|
45
|
+
// the syntax for keys is described here:
|
|
46
|
+
// https://docs.cypress.io/api/commands/type
|
|
47
|
+
cy.get("textarea").focus().type(text, options)
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
declare global {
|
|
51
|
+
namespace Cypress {
|
|
52
|
+
interface Chainable {
|
|
53
|
+
startNeovim(args?: MyStartNeovimServerArguments): Chainable<NeovimContext>
|
|
54
|
+
typeIntoTerminal(text: string, options?: Partial<Cypress.TypeOptions>): Chainable<void>
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
`
|
|
59
|
+
|
|
60
|
+
const options = await resolveConfig(__filename)
|
|
61
|
+
text = await format(text, { ...options, parser: "typescript" })
|
|
62
|
+
|
|
63
|
+
return text
|
|
64
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from "fs"
|
|
2
|
+
import { createCypressSupportFileContents } from "./contents.js"
|
|
3
|
+
import type { CreateCypressSupportFileResult } from "./createCypressSupportFile.js"
|
|
4
|
+
import { createCypressSupportFile } from "./createCypressSupportFile.js"
|
|
5
|
+
|
|
6
|
+
vi.mock("fs")
|
|
7
|
+
vi.mock("./contents.ts")
|
|
8
|
+
|
|
9
|
+
const mocked = {
|
|
10
|
+
readFileSync: vi.mocked(readFileSync),
|
|
11
|
+
writeFileSync: vi.mocked(writeFileSync),
|
|
12
|
+
createCypressSupportFileContents: vi.mocked(createCypressSupportFileContents),
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
describe("createCypressSupportFileContents", () => {
|
|
16
|
+
it("should update the file if the schema has changed", async () => {
|
|
17
|
+
mocked.readFileSync.mockImplementationOnce(() => "")
|
|
18
|
+
mocked.writeFileSync.mockImplementationOnce(() => {
|
|
19
|
+
//
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
const result = await createCypressSupportFile({
|
|
23
|
+
cypressSupportDirectoryPath: "cypress/support",
|
|
24
|
+
supportFileName: "tui-sandbox.ts",
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
expect(result).toBe("updated" satisfies CreateCypressSupportFileResult)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it("should not update the file if the schema has not changed", async () => {
|
|
31
|
+
mocked.readFileSync.mockImplementationOnce(() => "contents")
|
|
32
|
+
mocked.writeFileSync.mockImplementationOnce(() => {
|
|
33
|
+
//
|
|
34
|
+
})
|
|
35
|
+
mocked.createCypressSupportFileContents.mockImplementationOnce(async () => "contents")
|
|
36
|
+
|
|
37
|
+
const result = await createCypressSupportFile({
|
|
38
|
+
cypressSupportDirectoryPath: "cypress/support",
|
|
39
|
+
supportFileName: "tui-sandbox.ts",
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
expect(result).toBe("did-nothing" satisfies CreateCypressSupportFileResult)
|
|
43
|
+
})
|
|
44
|
+
})
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from "fs"
|
|
2
|
+
import path from "path"
|
|
3
|
+
import { createCypressSupportFileContents } from "./contents.js"
|
|
4
|
+
|
|
5
|
+
export type CreateCypressSupportFileArgs = {
|
|
6
|
+
cypressSupportDirectoryPath: string
|
|
7
|
+
supportFileName: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type CreateCypressSupportFileResult = "updated" | "did-nothing"
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* This is the interface of tui-sandbox as far as cypress in the user's
|
|
14
|
+
* application is concerned. It needs to be checked for changes once per
|
|
15
|
+
* tui-sandbox version.
|
|
16
|
+
*/
|
|
17
|
+
export async function createCypressSupportFile({
|
|
18
|
+
cypressSupportDirectoryPath,
|
|
19
|
+
supportFileName,
|
|
20
|
+
}: CreateCypressSupportFileArgs): Promise<CreateCypressSupportFileResult> {
|
|
21
|
+
const text = await createCypressSupportFileContents()
|
|
22
|
+
|
|
23
|
+
let oldSchema = ""
|
|
24
|
+
const outputFilePath = path.join(cypressSupportDirectoryPath, supportFileName)
|
|
25
|
+
try {
|
|
26
|
+
oldSchema = readFileSync(outputFilePath, "utf-8")
|
|
27
|
+
} catch (error) {
|
|
28
|
+
console.log(`No existing cypress support file found at ${outputFilePath}, creating a new one`)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (oldSchema !== text) {
|
|
32
|
+
// it's important to not write the file if the schema hasn't changed
|
|
33
|
+
// because file watchers will trigger on file changes and we don't want to
|
|
34
|
+
// trigger a build if the schema hasn't changed
|
|
35
|
+
writeFileSync(outputFilePath, text)
|
|
36
|
+
return "updated"
|
|
37
|
+
} else {
|
|
38
|
+
return "did-nothing"
|
|
39
|
+
}
|
|
40
|
+
}
|
package/src/server/server.ts
CHANGED
|
@@ -73,7 +73,7 @@ export async function startTestServer(config: TestServerConfig): Promise<TestSer
|
|
|
73
73
|
port: 3000,
|
|
74
74
|
})
|
|
75
75
|
const appRouter = await createAppRouter(config)
|
|
76
|
-
await testServer.startAndRun(appRouter
|
|
76
|
+
await testServer.startAndRun(appRouter)
|
|
77
77
|
|
|
78
78
|
return testServer
|
|
79
79
|
}
|