Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
3cfb0c2
wip
lmiller1990 Oct 4, 2021
6c515b8
wip
lmiller1990 Oct 5, 2021
e3ef11a
wip
lmiller1990 Oct 5, 2021
df79dbe
pre-bundle deps
lmiller1990 Oct 5, 2021
240259f
Merge branch 'lmiller1990/fix-app-deps' into lmiller1990/spike-runner-2
lmiller1990 Oct 5, 2021
2fe90f6
wip
lmiller1990 Oct 5, 2021
2e18a14
wip: spec
lmiller1990 Oct 5, 2021
7aa3daa
clear iframe
lmiller1990 Oct 5, 2021
5edcbd7
wip: it kind of works
lmiller1990 Oct 5, 2021
264f1f9
wip, docs
lmiller1990 Oct 5, 2021
cabeaba
wip
lmiller1990 Oct 5, 2021
273cd66
update runner API
lmiller1990 Oct 6, 2021
3c3c691
wip
lmiller1990 Oct 6, 2021
e59feb3
remove comments
lmiller1990 Oct 6, 2021
5653188
do not render header
lmiller1990 Oct 6, 2021
e5bb592
revert some stuff
lmiller1990 Oct 6, 2021
3019505
remove test
lmiller1990 Oct 6, 2021
e1b58d3
update tests to work with react 17
lmiller1990 Oct 6, 2021
2914120
types
lmiller1990 Oct 6, 2021
eecce0b
wip
lmiller1990 Oct 6, 2021
f649fe0
revert react deps
lmiller1990 Oct 6, 2021
ebd1d21
move code around
lmiller1990 Oct 6, 2021
2bbfd29
add back hash change code
lmiller1990 Oct 6, 2021
961291e
lint
lmiller1990 Oct 6, 2021
f09b7c2
comment
lmiller1990 Oct 6, 2021
3441853
update readme
lmiller1990 Oct 6, 2021
d54a9ec
resolve conflict
lmiller1990 Oct 6, 2021
3676628
remove commet
lmiller1990 Oct 6, 2021
c20874a
revert yarn lock
lmiller1990 Oct 6, 2021
721538c
remove unused file
lmiller1990 Oct 6, 2021
dff4538
Delete HelloWorld1.spec.tsx
JessicaSachs Oct 6, 2021
972014c
Delete HelloWorld2.spec.tsx
JessicaSachs Oct 6, 2021
42fc18f
Merge remote-tracking branch 'origin/unified-desktop-gui' into lmille…
lmiller1990 Oct 7, 2021
54b2402
Merge branch 'lmiller1990/spike-runner-3' of https://github.com/cypre…
lmiller1990 Oct 8, 2021
bc16f33
merge in unified-desktop-gui
lmiller1990 Oct 8, 2021
cb5e4c5
update types
lmiller1990 Oct 8, 2021
4197f80
fix ui
lmiller1990 Oct 8, 2021
29bc749
fix bugs
lmiller1990 Oct 8, 2021
1057e92
fix test
lmiller1990 Oct 8, 2021
8579aab
remove dead code
lmiller1990 Oct 8, 2021
b07c940
more dead code
lmiller1990 Oct 8, 2021
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
25 changes: 20 additions & 5 deletions packages/app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,25 @@ This is the front-end for the Cypress App.

## Development

1. Use existing project to get a server (for example `cd packages/runner-ct && yarn cypress:open`)
2. It will open in a new browser on port 8080
3. Do `yarn start`. It will start the front-end for the new Cypress app
4. To back to the browser opened in step 2
5. Visit http://localhost:8080/__vite__/ for the new front-end powered by Vite (currently running the RunnerCt)
1. `yarn dev` (inside of `packages/app`)
2. It will open launchpad
3. Select Component Testing (current E2E is not fully working)
3. Open chrome (or another browser)
4. This launches the existing CT Runner. Change the URL to http://localhost:3000/__vite__/ (note the trailing `/`)
5. It should show the new Vite powered app

## Using existing, Vite-incompatible modules

Some of our modules, like `@packages/reporter`, `@packages/driver` and `@packages/runner-shared` cannot be easily
used with Vite due to circular dependencies and modules that do not have compatible ESM builds.

To work around this, when consuming existing code, it is bundled with webpack and made available under the
`window.UnifiedRunner` namespace. It is injected via [`injectBundle`](./src/runner/injectBundle.ts).

To add more code to the bundle, add it in the bundle root, `@packages/runner-ct/src/main.tsx` and attach it to
`window.UnifiedRunner`.

As a rule of thumb, avoid importing from the older, webpack based modules into this package. Instead, if you want to consume code from those older, webpack bundled modules, you should add them to the webpack root and consume them via `window.UnifiedRunner`. Ideally, update [`index.d.ts`](./index.d.ts) to add the types, as well.

### Icons

Expand Down Expand Up @@ -63,3 +77,4 @@ You can see this in the video with the Settings cog. It uses and `evenodd` fill
## Diagram

![](./unified-runner-diagram.png)]

4 changes: 2 additions & 2 deletions packages/app/cypress/integration/basic.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
describe('App', () => {
it('resolves the home page', () => {
cy.visit('http://localhost:5556')
cy.get('[href="#/runs"]').click()
cy.get('[href="#/settings"]').click()
cy.get('[href="/__vite__/runner"]').click()
cy.get('[href="/__vite__/settings"]').click()
})
})
78 changes: 78 additions & 0 deletions packages/app/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import type { Store } from './src/store'

interface ConnectionInfo {
automationElement: '__cypress-string',
randomString: string
}

export {}

/**
* The eventManager and driver are bundled separately
* by webpack. We cannot import them because of
* circular dependencies.
* To work around this, we build the driver, eventManager
* and some other dependencies using webpack, and consumed the dist'd
* source code.
*
* This is attached to `window` under the `UnifiedRunner` namespace.
*
* For now, just declare the types that we need to give us type safety where possible.
* Eventually, we should decouple the event manager and import it directly.
*/
declare global {
interface Window {
UnifiedRunner: {
/**
* decode config, which we receive as a base64 string
* This comes from Driver.utils
*/
decodeBase64: (base64: string) => Record<string, unknown>

/**
* Proxy event to the reporter via `Reporter.defaultEvents.emit`
*/
emit (evt: string, ...args: unknown[]): void

/**
* This is the eventManager which orchestrates all the communication
* between the reporter, driver, and server, as well as handle
* setup, teardown and running of specs.
*
* It's only used on the "Runner" part of the unified runner.
*/
eventManager: {
addGlobalListeners: (state: Store, connectionInfo: ConnectionInfo) => void
setup: (config: Record<string, unknown>) => void
initialize: ($autIframe: JQuery<HTMLIFrameElement>, config: Record<string, unknown>) => void
teardown: (state: Store) => Promise<void>
teardownReporter: () => Promise<void>
[key: string]: any
}

/**
* To ensure we are only a single copy of React
* We get a reference to the copy of React (and React DOM)
* that is used in the Reporter and Driver, which are bundled with
* webpack.
*
* Unfortunately, attempting to have React in a project
* using Vue causes mad conflicts because React'S JSX type
* is ambient, so we cannot actually type it.
*/
React: any
ReactDOM: any

/**
* Any React components or general code needed from
* runner-shared, reporter or driver are also bundled with
* webpack and made available via the window.UnifedRunner namespace.
*
* We cannot import the correct types, because this causes the linter and type
* checker to run on runner-shared and reporter, and it blows up.
*/
AutIframe: any
Reporter: any
}
}
}
11 changes: 8 additions & 3 deletions packages/app/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
<template>
<router-view v-slot="{ Component }">
<keep-alive>
<component :is="Component" />
</keep-alive>
<!--
TODO(lachlan): put this back after doing proper cleanup when unmounting the runner page
keep-alive works fine for Vue but has some weird effects on the React based Reporter
For now it's way more simple to just unmount and remount the components when changing page.
-->
<!-- <keep-alive> -->
<component :is="Component" />
<!-- </keep-alive> -->
Comment on lines +3 to +10
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmmm... this is concerning.

Copy link
Contributor Author

@lmiller1990 lmiller1990 Oct 7, 2021

Choose a reason for hiding this comment

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

We just never had the need to fully teardown everything, so that functionality didn't come "for free" with the existing code (think about it - we usually render the reporter, and never tear it down, in the existing runner). I think this should be an easy fix.

Can look into this in the mean time while you get your spec list PR ready.

</router-view>
</template>
10 changes: 5 additions & 5 deletions packages/app/src/layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
name="fade"
mode="out-in"
>
<keep-alive>
<component
:is="Component"
/>
</keep-alive>
<!-- <keep-alive> -->
<component
:is="Component"
/>
<!-- </keep-alive> -->
</transition>
</router-view>
</section>
Expand Down
6 changes: 2 additions & 4 deletions packages/app/src/navigation/SidebarNavigation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,13 @@
>
<router-link
v-for="item in navigation"
v-slot="{ href, isActive }"
v-slot="{ isActive }"
:key="item.name"
custom
:to="item.href"
>
<SidebarNavigationRow
:active="isActive"
:icon="item.icon"
:href="href"
>
{{ item.name }}
</SidebarNavigationRow>
Expand All @@ -43,7 +41,7 @@ import SettingsIcon from '~icons/cy/settings_x24'

const navigation = [
{ name: 'Specs', icon: SpecsIcon, href: '/' },
{ name: 'Runs', icon: CodeIcon, href: '/runs' },
{ name: 'Runs', icon: CodeIcon, href: '/runner' },
{ name: 'Settings', icon: SettingsIcon, href: '/settings' },
]

Expand Down
9 changes: 4 additions & 5 deletions packages/app/src/navigation/SidebarNavigationRow.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<template>
<a
href="#"
<div
:class="[active ? 'before:bg-jade-300' : 'before:bg-transparent']"
class="w-full
min-w-40px
Expand Down Expand Up @@ -43,16 +42,16 @@
<slot />
</span>
</span>
</a>
</div>
</template>

<script lang="ts" setup>
import type { FunctionalComponent, SVGAttributes } from 'vue'

withDefaults(defineProps <{
icon?: FunctionalComponent<SVGAttributes, {}>
icon: FunctionalComponent<SVGAttributes, {}>
// Currently active row (generally the current route)
active?: boolean
active: boolean
}>(), {
active: false,
icon: undefined,
Expand Down
20 changes: 19 additions & 1 deletion packages/app/src/pages/Index.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
<template>
<Specs />
<div>
<div v-if="query.fetching.value">
Loading...
</div>
<div v-else-if="query.data.value?.app?.activeProject">
<Specs :gql="query.data.value.app" />
</div>
</div>
</template>

<script setup lang="ts">
import { gql, useQuery } from '@urql/vue'
import Specs from './Specs.vue'
import { IndexDocument } from '../generated/graphql'

gql`
query Index {
app {
...Specs_Specs
}
}`

const query = useQuery({ query: IndexDocument })
</script>

<route>
Expand Down
54 changes: 35 additions & 19 deletions packages/app/src/pages/Runner/[...all].vue
Original file line number Diff line number Diff line change
@@ -1,33 +1,49 @@
<template>
<div>
<h2>Runs Page</h2>
<h4 v-if="!ready">
Loading
</h4>
<h4 v-else>
Error: TODO add gql backend for getting the base64Config into the browser
</h4>
<h2>Runner Page</h2>

<div v-once>
<div :id="RUNNER_ID" />
<div :id="REPORTER_ID" />
</div>
</div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { renderRunner } from '../../runner/renderRunner'
<script lang="ts" setup>
import { onMounted } from 'vue'
import type { SpecFile } from '@packages/types/src'
import { UnifiedRunnerAPI } from '../../runner'
import { REPORTER_ID, RUNNER_ID } from '../../runner/utils'
import { useRoute } from 'vue-router'

onMounted(() => {
UnifiedRunnerAPI.initialize(executeSpec)
})

const ready = ref(false)
const route = useRoute()

// @ts-ignore
window.__Cypress__ = true
function executeSpec () {
const absolute = route.hash.slice(1)

renderRunner(() => {
setTimeout(function () {
if (absolute) {
// @ts-ignore
window.Runner.start(document.getElementById('app'), '{{base64Config | safe}}')
}, 0)
execute({
absolute,
relative: `src/Basic.spec.tsx`,
name: `Basic.spec.tsx`,
})
}
}

ready.value = true
})
const execute = (spec?: SpecFile) => {
if (!spec) {
return
}

UnifiedRunnerAPI.executeSpec(spec)
}
</script>

<route>
{
name: "Runner"
Expand Down
50 changes: 28 additions & 22 deletions packages/app/src/pages/Specs.vue
Original file line number Diff line number Diff line change
@@ -1,36 +1,42 @@
<template>
<div>
<h2>Specs Page</h2>
<template v-if="query.data.value?.app">
<SpecsList :gql="query.data.value?.app" />
</template>
<p v-else>
Loading...
</p>
</div>
<h2>Specs Page</h2>

<SpecsList
v-if="props.gql"
:gql="props?.gql"
/>

<p v-else>
Loading...
</p>
</template>

<script lang="ts" setup>
import { gql } from '@urql/core'
import { useQuery } from '@urql/vue'
import { Specs_AppDocument } from '../generated/graphql'
import { gql } from '@urql/vue'
import SpecsList from '../specs/SpecsList.vue'
import { REPORTER_ID, RUNNER_ID } from '../runner/utils'
import type { Specs_SpecsFragment } from '../generated/graphql'

gql`
query Specs_App {
app {
...SpecsList
}
}
`

const query = useQuery({
query: Specs_AppDocument,
})
fragment Specs_Specs on App {
...Specs_SpecsList
}`

const props = defineProps<{
gql: Specs_SpecsFragment
}>()
</script>

<route>
{
name: "Specs Page"
}
</route>

<style>
iframe {
border: 5px solid black;
margin: 10px;
background: lightgray;
}
</style>
4 changes: 2 additions & 2 deletions packages/app/src/router/router.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { createWebHashHistory, createRouter as _createRouter } from 'vue-router'
import { createRouter as _createRouter, createWebHistory } from 'vue-router'
import generatedRoutes from 'virtual:generated-pages'
import { setupLayouts } from 'virtual:generated-layouts'

export const createRouter = () => {
const routes = setupLayouts(generatedRoutes)

return _createRouter({
history: createWebHashHistory(),
history: createWebHistory('/__vite__/'),
routes,
})
}
Loading