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

chore: add logic to dynamically load studio functionality #31033

Open
wants to merge 15 commits into
base: develop
Choose a base branch
from

Conversation

ryanthemanuel
Copy link
Collaborator

@ryanthemanuel ryanthemanuel commented Feb 6, 2025

Additional details

This PR lays the groundwork for being able to dynamically load studio functionality. There are no current functional changes with this PR (which is why it's a chore), but this work will eventually drive updates to the Studio UI, bug fixes for Studio, and AI recommendations for how to modify specs.

This PR:

  • Sets up environment variables (CYPRESS_ENABLE_CLOUD_STUDIO and CYPRESS_LOCAL_APP_STUDIO_PATH) as development placeholders to enable logic that pulls a bundle from the cloud that contains both frontend and backend code that will eventually drive studio functionality
    • The bundle is delivered in a similar manner to protocol code
    • The bundle is signed and verified to ensure no tampering
  • When the bundle is downloaded, it is extracted to a temp directory where the server logic is incorporated into the rest of the existing app server
    • This server logic adds new routes that can then handle front end requests for studio code that will drive the UI
    • These front end files are set up using module federation to allow us to import as normal dependencies and then vite figures out what routes are necessary to load the assets

Steps to test

The best way to test this is to:

  • Clone the cypress-services repo
    • Run yarn
    • Run yarn watch in packages/app-studio
  • Set CYPRESS_LOCAL_APP_STUDIO_PATH to the path to the cypress-services/packages/app-studio/dist/development directory
  • Clone the cypress repo
    • Run yarn
    • Run yarn cypress:open

Then you can open a specific project and should be able to see the console log of Studio loaded as an indication that everything is synced up properly.

How has the user experience changed?

PR Tasks

@ryanthemanuel ryanthemanuel self-assigned this Feb 6, 2025
@ryanthemanuel ryanthemanuel changed the title chore: add logic to dynamically load new studio functionality chore: add logic to dynamically load studio functionality Feb 6, 2025
Copy link

cypress bot commented Feb 6, 2025

cypress    Run #60366

Run Properties:  status check passed Passed #60366  •  git commit 29f089cf91: Merge branch 'develop' into ryanm/chore/add_internal_studio
Project cypress
Branch Review ryanm/chore/add_internal_studio
Run status status check passed Passed #60366
Run duration 15m 46s
Commit git commit 29f089cf91: Merge branch 'develop' into ryanm/chore/add_internal_studio
Committer Ryan Manuel
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 1
Tests that did not run due to a developer annotating a test with .skip  Pending 28
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 762
View all changes introduced in this branch ↗︎
UI Coverage  62.5%
  Untested elements 31  
  Tested elements 55  
Accessibility  96.23%
  Failed rules  0 critical   4 serious   1 moderate   0 minor
  Failed elements 194  

@ryanthemanuel ryanthemanuel requested a review from mschile February 7, 2025 16:05
guides/studio-development.md Outdated Show resolved Hide resolved
@AtofStryker AtofStryker self-requested a review February 11, 2025 18:44
packages/graphql/src/schemaTypes/objectTypes/gql-Query.ts Outdated Show resolved Hide resolved
packages/server/lib/cloud/api/get_app_studio.ts Outdated Show resolved Hide resolved
await appStudio.setup({ script, studioPath, studioHash })

return appStudio
} catch (error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we type the error here since anything can throw and make sure we pass the right type into createInErrorManager?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our ts rules require any or unknown so I'm going to specify any.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on this pattern? 634109a (#31033)

return manager
}

async setup ({ script, studioPath, studioHash }: { script: string, studioPath: string, studioHash?: string }): Promise<void> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
async setup ({ script, studioPath, studioHash }: { script: string, studioPath: string, studioHash?: string }): Promise<void> {
setup ({ script, studioPath, studioHash }: { script: string, studioPath: string, studioHash?: string }): Promise<void> {

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


try {
return this._appStudio[method].apply(this._appStudio, args)
} catch (error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar to above, it is worth typing the error to say something like unknown to make sure we handle/cast it correctly? It might be overkill if we know what we are dealing with error wise.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on this pattern? 634109a (#31033)

packages/server/test/unit/cloud/api/get_app_studio_spec.ts Outdated Show resolved Hide resolved
packages/server/test/unit/project_spec.js Outdated Show resolved Hide resolved
@@ -109,6 +109,16 @@ const getProtocolFileSource = async (protocolFilePath) => {
return fileContents.replaceAll('process.env.CYPRESS_LOCAL_PROTOCOL_PATH', 'undefined')
}

const getStudioFileSource = async (studioFilePath) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const getStudioFileSource = async (studioFilePath) => {
const getStudioFileSource = async (studioFilePath: string) => {

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a js file.

@@ -117,6 +127,14 @@ const validateProtocolFile = async (protocolFilePath) => {
}
}

const validateStudioFile = async (studioFilePath) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const validateStudioFile = async (studioFilePath) => {
const validateStudioFile = async (studioFilePath: string) => {

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a js file

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants