Skip to content

Commit 108eb7e

Browse files
internal: (studio) make the protocol database accessible to studio (#31443)
* internal: (studio) make the protocol database accessible to studio * PR comment
1 parent 6bf7383 commit 108eb7e

File tree

10 files changed

+61
-4
lines changed

10 files changed

+61
-4
lines changed

packages/server/lib/cloud/protocol.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ export class ProtocolManager implements ProtocolManagerShape {
6262
} : undefined
6363
}
6464

65+
get db () {
66+
return this._db
67+
}
68+
6569
async prepareProtocol (script: string, options: ProtocolManagerOptions) {
6670
this._captureHash = base64url.fromBase64(crypto.createHash('SHA256').update(script).digest('base64'))
6771

packages/server/lib/cloud/studio.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import os from 'os'
66
import { agent } from '@packages/network'
77
import Debug from 'debug'
88
import { requireScript } from './require_script'
9+
import type Database from 'better-sqlite3'
910

1011
interface StudioServer { default: StudioServerDefaultShape }
1112

@@ -37,6 +38,10 @@ export class StudioManager implements StudioManagerShape {
3738
return manager
3839
}
3940

41+
setProtocolDb (db: Database.Database): void {
42+
this.invokeSync('setProtocolDb', { isEssential: true }, db)
43+
}
44+
4045
async setup ({ script, studioPath, studioHash, projectSlug, cloudApi }: SetupOptions): Promise<void> {
4146
const { createStudioServer } = requireScript<StudioServer>(script).default
4247

@@ -100,6 +105,7 @@ export class StudioManager implements StudioManagerShape {
100105
}
101106

102107
try {
108+
// @ts-expect-error - TS not associating the method & args properly, even though we know it's correct
103109
return this._studioServer[method].apply(this._studioServer, args)
104110
} catch (error: unknown) {
105111
let actualError: Error

packages/server/lib/project-base.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,10 @@ export class ProjectBase extends EE {
447447

448448
await browsers.connectProtocolToBrowser({ browser: this.browser, foundBrowsers: this.options.browsers, protocolManager: this.protocolManager })
449449

450+
if (this.protocolManager.db) {
451+
this.ctx.coreData.studio?.setProtocolDb(this.protocolManager.db)
452+
}
453+
450454
return { canAccessStudioAI: true }
451455
}
452456

packages/server/test/support/fixtures/cloud/protocol/test-protocol.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Database } from 'better-sqlite3'
1+
import type Database from 'better-sqlite3'
22
import type { AppCaptureProtocolInterface, CDPClient, ResponseStreamOptions } from '@packages/types'
33
import { Readable } from 'stream'
44

@@ -12,7 +12,7 @@ export class AppCaptureProtocol implements AppCaptureProtocolInterface {
1212
responseStreamReceived (options: ResponseStreamOptions): Readable {
1313
return Readable.from([])
1414
}
15-
beforeSpec ({ workingDirectory, archivePath, dbPath, db }: { workingDirectory: string, archivePath: string, dbPath: string, db: Database }): void {}
15+
beforeSpec ({ workingDirectory, archivePath, dbPath, db }: { workingDirectory: string, archivePath: string, dbPath: string, db: Database.Database }): void {}
1616
addRunnables (runnables: any): void {}
1717
commandLogAdded (log: any): void {}
1818
commandLogChanged (log: any): void {}

packages/server/test/support/fixtures/cloud/studio/test-studio.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { StudioServerShape, StudioServerDefaultShape, StudioBrowser } from '@packages/types'
2+
import type Database from 'better-sqlite3'
23
import type { Router } from 'express'
34

45
class StudioServer implements StudioServerShape {
@@ -9,6 +10,9 @@ class StudioServer implements StudioServerShape {
910
canAccessStudioAI (browser: StudioBrowser): Promise<boolean> {
1011
return Promise.resolve(true)
1112
}
13+
14+
setProtocolDb (db: Database.Database): void {
15+
}
1216
}
1317

1418
const studioServerDefault: StudioServerDefaultShape = {

packages/server/test/unit/cloud/protocol_spec.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,20 @@ describe('lib/cloud/protocol', () => {
350350
})
351351
})
352352

353+
describe('.db', () => {
354+
it('returns the database instance', () => {
355+
const mockDb = { test: 'db' }
356+
357+
protocolManager['_db'] = mockDb
358+
359+
expect(protocolManager.db).to.equal(mockDb)
360+
})
361+
362+
it('returns undefined when no database is set', () => {
363+
expect(protocolManager.db).to.be.undefined
364+
})
365+
})
366+
353367
describe('.uploadCaptureArtifact()', () => {
354368
let filePath: string
355369
let fileSize: number

packages/server/test/unit/cloud/studio_spec.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,27 @@ describe('lib/cloud/studio', () => {
160160
name: 'chrome',
161161
family: 'chromium',
162162
channel: 'stable',
163+
displayName: 'Chrome',
164+
version: '120.0.0',
165+
majorVersion: '120',
166+
path: '/path/to/chrome',
167+
isHeaded: true,
168+
isHeadless: false,
163169
})
164170

165171
expect(result).to.be.true
166172
})
167173
})
174+
175+
describe('setProtocolDb', () => {
176+
it('sets the protocol database on the studio server', () => {
177+
const mockDb = { test: 'db' }
178+
179+
sinon.stub(studio, 'setProtocolDb')
180+
181+
studioManager.setProtocolDb(mockDb as any)
182+
183+
expect(studio.setProtocolDb).to.be.calledWith(mockDb)
184+
})
185+
})
168186
})

packages/server/test/unit/project_spec.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,14 +737,17 @@ This option will not have an effect in Some-other-name. Tests that rely on web s
737737
const mockSetupProtocol = sinon.stub()
738738
const mockBeforeSpec = sinon.stub()
739739
const mockAccessStudioLLM = sinon.stub().resolves(true)
740+
const mockSetProtocolDb = sinon.stub()
740741

741742
this.project.spec = {}
742743
this.project.ctx.coreData.studio = {
743744
canAccessStudioAI: mockAccessStudioLLM,
744745
protocolManager: {
745746
setupProtocol: mockSetupProtocol,
746747
beforeSpec: mockBeforeSpec,
748+
db: { test: 'db' },
747749
},
750+
setProtocolDb: mockSetProtocolDb,
748751
}
749752

750753
sinon.stub(browsers, 'connectProtocolToBrowser').resolves()
@@ -793,6 +796,7 @@ This option will not have an effect in Some-other-name. Tests that rely on web s
793796
})
794797

795798
expect(this.project['_protocolManager']).to.eq(this.project.ctx.coreData.studio.protocolManager)
799+
expect(mockSetProtocolDb).to.be.calledWith({ test: 'db' })
796800
})
797801

798802
it('passes onStudioInit callback with AI enabled but no protocol manager', async function () {

packages/types/src/protocol.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Database } from 'better-sqlite3'
1+
import type Database from 'better-sqlite3'
22
import type ProtocolMapping from 'devtools-protocol/types/protocol-mapping'
33
import type { IncomingHttpHeaders } from 'http'
44
import type { Readable } from 'stream'
@@ -38,7 +38,7 @@ export interface AppCaptureProtocolCommon {
3838

3939
export interface AppCaptureProtocolInterface extends AppCaptureProtocolCommon {
4040
getDbMetadata (): { offset: number, size: number } | undefined
41-
beforeSpec ({ spec, workingDirectory, archivePath, dbPath, db }: { spec: FoundSpec & { instanceId: string }, workingDirectory: string, archivePath: string, dbPath: string, db: Database }): void
41+
beforeSpec ({ spec, workingDirectory, archivePath, dbPath, db }: { spec: FoundSpec & { instanceId: string }, workingDirectory: string, archivePath: string, dbPath: string, db: Database.Database }): void
4242
uploadStallSamplingInterval: () => number
4343
connectToBrowser (cdpClient: CDPClient): Promise<void>
4444
}
@@ -138,6 +138,7 @@ export interface ProtocolManagerShape extends AppCaptureProtocolCommon {
138138
uploadCaptureArtifact(artifact: CaptureArtifact): Promise<UploadCaptureArtifactResult | undefined>
139139
connectToBrowser (cdpClient: CDPClient): Promise<void>
140140
close (): void
141+
db?: Database.Database
141142
}
142143

143144
type Response = {

packages/types/src/studio/studio-server-types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import type { Router } from 'express'
44
import type { AxiosInstance } from 'axios'
5+
import type Database from 'better-sqlite3'
56

67
interface RetryOptions {
78
maxAttempts: number
@@ -32,6 +33,7 @@ export interface StudioServerOptions {
3233
export interface StudioServerShape {
3334
initializeRoutes(router: Router): void
3435
canAccessStudioAI(browser: Cypress.Browser): Promise<boolean>
36+
setProtocolDb(database: Database.Database): void
3537
}
3638

3739
export interface StudioServerDefaultShape {

0 commit comments

Comments
 (0)