-
Notifications
You must be signed in to change notification settings - Fork 109
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
feat: preflight scripts for laboratory #5564
Merged
Merged
Changes from 122 commits
Commits
Show all changes
128 commits
Select commit
Hold shift + click to select a range
e4b09bd
add query builder for laboratory
dimaMachina 3bdcab2
temp
dimaMachina a455613
fix
dimaMachina aa5ecb8
fix
dimaMachina db6f984
pnpm
dimaMachina 1362231
Merge branch 'main' into add-graphiql-explorer2
dimaMachina 24c1f7f
Merge branch 'main' into add-graphiql-explorer2
dimaMachina 97414e1
use stable version of `@graphiql/plugin-explorer`, update graphiql
dimaMachina 06c2ecc
Merge branch 'main' into explorer3
dimaMachina 5c8b2f0
refactor use-operation-collections-plugin.tsx
dimaMachina 1e1dd05
more
dimaMachina 6c6fc1d
more refactoring
dimaMachina 0b48243
update explorer
dimaMachina 7f0025e
undo rename to have less diff changes
dimaMachina 23fe786
- [ ] remove custom prebuild `rss-generator.ts` script
dimaMachina fc3966c
fix types
dimaMachina 9276cb7
move `theme.config.tsx` to src
dimaMachina 770a158
more product updates work
dimaMachina 3f17764
prettify
dimaMachina 06d5b96
more
dimaMachina 816f92a
more
dimaMachina 257860c
prettier
dimaMachina f06fed4
grammarly
dimaMachina e9ffc80
prettify
dimaMachina 2110c7d
add eslint-disable-next-line
dimaMachina 6fbdd04
update date
dimaMachina f942172
polish
dimaMachina 0c3a9f9
apply review
dimaMachina d20f454
replace I with we
dimaMachina d3a66bc
remove mention of `plugin` in `Operations collections plugin`
dimaMachina bb00d01
use Laurin's query builder suggestion
dimaMachina 36f8c32
polish graphiql v4 alpha
dimaMachina dd5b588
polish
dimaMachina 1510a01
mention link to graphiql
dimaMachina 527373b
apply Kamil suggestions
dimaMachina 14e8cf0
Merge branch 'main' into add-graphiql-explorer2
dimaMachina 736b77c
Merge branch 'explorer3' into laboratory-product-update
dimaMachina aff9468
apply Saihaj review changes and polish after new landing page merge
dimaMachina 2469276
Merge branch 'main' into laboratory-product-update
dimaMachina a54b13d
remove old look of operations collections
dimaMachina 3f5a2d6
all in one
dimaMachina 28342ba
#2 preflight scripts (db + cypress e2e tests) (#5622)
dimaMachina 7bda2e3
Merge branch 'main' into preflight-script
dimaMachina 2cb4e2d
Merge branch 'main' into preflight-script
kamilkisiela 1a8b261
Merge branch 'main' into preflight-script
dimaMachina 4e4bdde
refactor after merging with main
dimaMachina ee89ae2
prettier
dimaMachina cdda687
Merge branch 'main' into preflight-script
dimaMachina 2f36bfc
fixes
dimaMachina 790b24a
more
dimaMachina ac56106
Update cypress.config.ts [skip ci]
dimaMachina c9964e5
cleanup global variables
dimaMachina ed71480
add target_id as unique
dimaMachina b831de6
move to provider
dimaMachina 629a4ca
more tests
dimaMachina 82cb5bc
more
dimaMachina 5d46167
more
dimaMachina e2b22cb
Merge branch 'preflight-script' of github.com:kamilkisiela/graphql-hi…
dimaMachina 95cc44b
pnpm i + lint
dimaMachina b568fcf
fix migrations
dimaMachina 0bc7397
fix typecheck
dimaMachina 6b08723
typecheck
dimaMachina ffa0380
Update cypress/e2e/preflight-script.cy.ts [skip ci]
dimaMachina a45e9cc
Merge branch 'main' into preflight-script
dimaMachina 2f865e4
use path.parse(import.meta.url).base [skip ci]
dimaMachina f02835c
rename targetSlug to targetId and move to lab folder [skip ci]
dimaMachina ca55d5b
more
dimaMachina 6c735f9
use only 1 resolver updatePreflightScript with ON CONFLICT sql [skip ci]
dimaMachina ea79bc5
validate source code before inserting [skip ci]
dimaMachina c0f6488
remove `preflightScriptModule` and merge it with `labModule` [skip ci]
dimaMachina 58739cd
post message to main thread as soon as possible [skip ci]
dimaMachina 0be4397
add timeout 30s to terminate worker process [skip ci]
dimaMachina ab70d62
this is needed for now for cypress
dimaMachina 5838e82
make all tests pass
dimaMachina 6f5710f
update worker chunk name [skip-ci]
dimaMachina a60373b
Merge branch 'main' into preflight-script
dimaMachina e40e9da
apply review [skip-ci]
dimaMachina 85b24a4
add proxy [skip ci]
dimaMachina 58cad81
fixes for proxy [skip ci]
dimaMachina f5dbd49
refactor
dimaMachina af6519a
refactor
dimaMachina 3e38bb0
more refactoring
dimaMachina 1676dd0
type result
dimaMachina 6e9b7ab
add start/end running script and line/column number
dimaMachina ebefade
add ability stop script and clear console output
dimaMachina dd0db87
call handleStopScript if modal closed and script is run
dimaMachina 7cf4904
grant rights [skip ci]
dimaMachina 4dde658
stop worker [skip ci]
dimaMachina f992123
all cypress tests pass [skip ci]
dimaMachina 08a25f0
Merge branch 'main' into preflight-script
dimaMachina db92293
Merge branch 'main' into preflight-script
dimaMachina e22a428
Merge branch 'main' into preflight-script
dimaMachina 02707a9
simplify code structure for readability (#6022)
n1ru4l d9113e4
Merge remote-tracking branch 'origin/main' into preflight-script
n1ru4l 71bc1e0
refactor: single input field for mutation field
n1ru4l 83840c2
use seed script for cypress
n1ru4l 7244b44
ffs cypress
n1ru4l 85c8673
feat: lab worker dns per env
n1ru4l 7b4fefe
reuse integration-test environment variables and remove duplicated logic
n1ru4l cbca6d3
remove unused import
n1ru4l bee25f2
remove comment
n1ru4l c61bbdb
Merge remote-tracking branch 'origin/main' into preflight-script
n1ru4l 8cc19ec
we need da codegen for the e2e
n1ru4l 08f94fb
relax environment variable
n1ru4l 9c70421
require preflight script reporting readiness
n1ru4l 417b693
instantiate worker for each script run
n1ru4l ad56588
ooops
n1ru4l c7017be
fix import
n1ru4l a70beb6
try chrome
n1ru4l da9228e
fix url
n1ru4l c022299
error handling
n1ru4l 63a7e4f
Merge remote-tracking branch 'origin/main' into preflight-script
n1ru4l d2ca542
Prepare Vite and Fastify for more than one entry point (#6143)
kamilkisiela 895c545
isolate preflight worker into iframe. (#6146)
n1ru4l 661ee13
Merge remote-tracking branch 'origin/main' into preflight-script
n1ru4l 5b9cbc8
ensure
n1ru4l 51b37b0
lint god
n1ru4l 55ad962
less flaky tests
n1ru4l 1187c2f
cleanup
n1ru4l fc178c0
any
n1ru4l 46bc881
update dates
n1ru4l dec32b0
Revert "any"
n1ru4l ff7d725
Merge remote-tracking branch 'origin/main' into preflight-script
n1ru4l 4fece6b
update date
n1ru4l 5493d54
audit log event
n1ru4l 5a223a3
changeset
n1ru4l 5a9726b
heading
n1ru4l be33411
wif
n1ru4l File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
beforeEach(() => { | ||
cy.clearLocalStorage().then(async () => { | ||
cy.task('seedTarget').then(({ slug, refreshToken }: any) => { | ||
cy.setCookie('sRefreshToken', refreshToken); | ||
|
||
cy.visit(`/${slug}/laboratory`); | ||
cy.get('[aria-label*="Preflight Script"]').click(); | ||
}); | ||
}); | ||
}); | ||
|
||
/** Helper function for setting the text within a monaco editor as typing manually results in flaky tests */ | ||
function setMonacoEditorContents(editorCyName: string, text: string) { | ||
// wait for textarea appearing which indicates monaco is loaded | ||
cy.dataCy(editorCyName).find('textarea'); | ||
cy.window().then(win => { | ||
// First, check if monaco is available on the main window | ||
const editor = (win as any).monaco.editor | ||
.getEditors() | ||
.find(e => e.getContainerDomNode().parentElement.getAttribute('data-cy') === editorCyName); | ||
|
||
// If Monaco instance is found | ||
if (editor) { | ||
editor.setValue(text); | ||
} else { | ||
throw new Error('Monaco editor not found on the window or frames[0]'); | ||
} | ||
}); | ||
} | ||
|
||
function setEditorScript(script: string) { | ||
setMonacoEditorContents('preflight-script-editor', script); | ||
} | ||
|
||
describe('Preflight Script', () => { | ||
it('mini script editor is read only', () => { | ||
cy.dataCy('toggle-preflight-script').click(); | ||
// Wait loading disappears | ||
cy.dataCy('preflight-script-editor-mini').should('not.contain', 'Loading'); | ||
// Click | ||
cy.dataCy('preflight-script-editor-mini').click(); | ||
// And type | ||
cy.dataCy('preflight-script-editor-mini').within(() => { | ||
cy.get('textarea').type('🐝', { force: true }); | ||
}); | ||
cy.dataCy('preflight-script-editor-mini').should( | ||
'have.text', | ||
'Cannot edit in read-only editor', | ||
); | ||
}); | ||
}); | ||
|
||
describe('Preflight Script Modal', () => { | ||
const script = 'console.log("Hello_world")'; | ||
const env = '{"foo":123}'; | ||
|
||
beforeEach(() => { | ||
cy.dataCy('preflight-script-modal-button').click(); | ||
setMonacoEditorContents('env-editor', env); | ||
}); | ||
|
||
it('save script and environment variables when submitting', () => { | ||
setEditorScript(script); | ||
cy.dataCy('preflight-script-modal-submit').click(); | ||
cy.dataCy('env-editor-mini').should('have.text', env); | ||
cy.dataCy('toggle-preflight-script').click(); | ||
cy.dataCy('preflight-script-editor-mini').should('have.text', script); | ||
cy.reload(); | ||
cy.get('[aria-label*="Preflight Script"]').click(); | ||
cy.dataCy('env-editor-mini').should('have.text', env); | ||
cy.dataCy('preflight-script-editor-mini').should('have.text', script); | ||
}); | ||
|
||
it('logs show console/error information', () => { | ||
setEditorScript(script); | ||
cy.dataCy('run-preflight-script').click(); | ||
cy.dataCy('console-output').should('contain', 'Log: Hello_world (Line: 1, Column: 1)'); | ||
|
||
setEditorScript( | ||
`console.info(1) | ||
console.warn(true) | ||
console.error('Fatal') | ||
throw new TypeError('Test')`, | ||
); | ||
|
||
cy.dataCy('run-preflight-script').click(); | ||
// First log previous log message | ||
cy.dataCy('console-output').should('contain', 'Log: Hello_world (Line: 1, Column: 1)'); | ||
// After the new logs | ||
cy.dataCy('console-output').should( | ||
'contain', | ||
[ | ||
'Info: 1 (Line: 1, Column: 1)', | ||
'Warn: true (Line: 2, Column: 1)', | ||
'Error: Fatal (Line: 3, Column: 1)', | ||
'TypeError: Test (Line: 4, Column: 7)', | ||
].join(''), | ||
); | ||
}); | ||
|
||
it('script execution updates environment variables', () => { | ||
setEditorScript(`lab.environment.set('my-test', "TROLOLOL")`); | ||
|
||
cy.dataCy('run-preflight-script').click(); | ||
cy.dataCy('env-editor').should( | ||
'include.text', | ||
// replace space with | ||
'{ "foo": 123, "my-test": "TROLOLOL"}'.replaceAll(' ', '\xa0'), | ||
); | ||
}); | ||
|
||
it('`crypto-js` can be used for generating hashes', () => { | ||
setEditorScript('console.log(lab.CryptoJS.SHA256("🐝"))'); | ||
cy.dataCy('run-preflight-script').click(); | ||
cy.dataCy('console-output').should('contain', 'Info: Using crypto-js version:'); | ||
cy.dataCy('console-output').should( | ||
'contain', | ||
'Log: d5b51e79e4be0c4f4d6b9a14e16ca864de96afe68459e60a794e80393a4809e8', | ||
); | ||
}); | ||
|
||
it('scripts can not use `eval`', () => { | ||
setEditorScript('eval()'); | ||
cy.dataCy('preflight-script-modal-submit').click(); | ||
cy.get('body').contains('Usage of dangerous statement like eval() or Function("").'); | ||
}); | ||
|
||
it('invalid code is rejected and can not be saved', () => { | ||
setEditorScript('🐝'); | ||
cy.dataCy('preflight-script-modal-submit').click(); | ||
cy.get('body').contains("[1:1]: Illegal character '}"); | ||
}); | ||
}); | ||
|
||
describe('Execution', () => { | ||
it('header placeholders are substituted with environment variables', () => { | ||
cy.dataCy('toggle-preflight-script').click(); | ||
cy.get('[data-name="headers"]').click(); | ||
cy.get('.graphiql-editor-tool .graphiql-editor:last-child textarea').type( | ||
'{ "__test": "{{foo}} bar {{nonExist}}" }', | ||
{ | ||
force: true, | ||
parseSpecialCharSequences: false, | ||
}, | ||
); | ||
cy.dataCy('env-editor-mini').within(() => { | ||
cy.get('textarea').type('{"foo":"injected"}', { | ||
force: true, | ||
parseSpecialCharSequences: false, | ||
}); | ||
}); | ||
cy.intercept('/api/lab/foo/my-new-project/development', req => { | ||
expect(req.headers.__test).to.equal('injected bar {{nonExist}}'); | ||
}); | ||
cy.get('body').type('{ctrl}{enter}'); | ||
}); | ||
|
||
it('executed script updates update env editor and substitute headers', () => { | ||
cy.dataCy('toggle-preflight-script').click(); | ||
cy.get('[data-name="headers"]').click(); | ||
cy.get('.graphiql-editor-tool .graphiql-editor:last-child textarea').type( | ||
'{ "__test": "{{foo}}" }', | ||
{ | ||
force: true, | ||
parseSpecialCharSequences: false, | ||
}, | ||
); | ||
cy.dataCy('preflight-script-modal-button').click(); | ||
setMonacoEditorContents('preflight-script-editor', `lab.environment.set('foo', 92)`); | ||
cy.dataCy('preflight-script-modal-submit').click(); | ||
cy.intercept('/api/lab/foo/my-new-project/development', req => { | ||
expect(req.headers.__test).to.equal('92'); | ||
}); | ||
cy.get('.graphiql-execute-button').click(); | ||
}); | ||
|
||
it('disabled script is not executed', () => { | ||
cy.get('[data-name="headers"]').click(); | ||
cy.get('.graphiql-editor-tool .graphiql-editor:last-child textarea').type( | ||
'{ "__test": "{{foo}}" }', | ||
{ | ||
force: true, | ||
parseSpecialCharSequences: false, | ||
}, | ||
); | ||
cy.dataCy('preflight-script-modal-button').click(); | ||
setMonacoEditorContents('preflight-script-editor', `lab.environment.set('foo', 92)`); | ||
setMonacoEditorContents('env-editor', `{"foo":10}`); | ||
|
||
cy.dataCy('preflight-script-modal-submit').click(); | ||
cy.intercept('/api/lab/foo/my-new-project/development', req => { | ||
expect(req.headers.__test).to.equal('10'); | ||
}); | ||
cy.get('.graphiql-execute-button').click(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,8 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "es5", | ||
"lib": ["es5", "dom"], | ||
"target": "es2021", | ||
"lib": ["es2021", "dom"], | ||
"types": ["node", "cypress"] | ||
}, | ||
"include": ["**/*.ts"] | ||
"include": ["**/*.ts", "../integration-tests/testkit/**/*.ts"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -333,12 +333,10 @@ deployCloudFlareSecurityTransform({ | |
// Staging | ||
'staging.graphql-hive.com', | ||
'app.staging.graphql-hive.com', | ||
'lab-worker.staging.graphql-hive.com', | ||
'cdn.staging.graphql-hive.com', | ||
// Dev | ||
'dev.graphql-hive.com', | ||
'app.dev.graphql-hive.com', | ||
'lab-worker.dev.graphql-hive.com', | ||
Comment on lines
-338
to
-343
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no longer needed, we don't need to run on a different domain to isolate the worker. |
||
'cdn.dev.graphql-hive.com', | ||
], | ||
}); | ||
|
@@ -351,4 +349,4 @@ export const schemaApiServiceId = schema.service.id; | |
export const webhooksApiServiceId = webhooks.service.id; | ||
|
||
export const appId = app.deployment.id; | ||
export const publicIp = proxy!.status.loadBalancer.ingress[0].ip; | ||
export const publicIp = proxy.get()!.status.loadBalancer.ingress[0].ip; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,7 +34,6 @@ export function deployCloudFlareSecurityTransform(options: { | |
)} } and not http.host in { ${toExpressionList(options.ignoredHosts)} }`; | ||
|
||
// TODO: When Preflight PR is merged, we'll need to change this to build this host in a better way. | ||
const labHost = `lab-worker.${options.environment.rootDns}`; | ||
const monacoCdnDynamicBasePath: `https://${string}/` = `https://cdn.jsdelivr.net/npm/monaco-editor@${monacoEditorVersion}/`; | ||
const monacoCdnStaticBasePath: `https://${string}/` = `https://cdn.jsdelivr.net/npm/[email protected]/`; | ||
const crispHost = 'client.crisp.chat'; | ||
|
@@ -44,7 +43,6 @@ export function deployCloudFlareSecurityTransform(options: { | |
crispHost, | ||
stripeHost, | ||
gtmHost, | ||
labHost, | ||
'settings.crisp.chat', | ||
'*.ingest.sentry.io', | ||
'wss://client.relay.crisp.chat', | ||
|
@@ -57,7 +55,6 @@ export function deployCloudFlareSecurityTransform(options: { | |
const contentSecurityPolicy = ` | ||
default-src 'self'; | ||
frame-src ${stripeHost} https://game.crisp.chat; | ||
worker-src 'self' blob: ${labHost}; | ||
style-src 'self' 'unsafe-inline' ${crispHost} fonts.googleapis.com rsms.me ${monacoCdnDynamicBasePath} ${monacoCdnStaticBasePath}; | ||
script-src 'self' 'unsafe-eval' 'unsafe-inline' {DYNAMIC_HOST_PLACEHOLDER} ${monacoCdnDynamicBasePath} ${monacoCdnStaticBasePath} ${cspHosts}; | ||
connect-src 'self' * {DYNAMIC_HOST_PLACEHOLDER} ${cspHosts}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -100,6 +100,5 @@ export function deployProxy({ | |
service: usage.service, | ||
retriable: true, | ||
}, | ||
]) | ||
.get(); | ||
]); | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we now use the integration test seed here which uses client preset.