-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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: Debug run navigation #26017
feat: Debug run navigation #26017
Conversation
Passing run #44988 ↗︎
Details:
This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. |
098d920
to
ad04e03
Compare
ad04e03
to
a72fb46
Compare
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.
@lmiller1990 I wanted to get you this feedback. When a new build is running, I am getting GQL errors and still looking into what is causing that.
<li | ||
v-for="run of groupByCommit[sha]" | ||
:key="run?.runNumber!" | ||
class="flex ml-6px mr-12px p-10px pl-30px hocus:bg-indigo-50 cursor-pointer rounded relative ring-3 ring-white ring-inset" |
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.
What is the need for the "ring" styles here? It causes the dashed line to get broken up.
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.
class="relative my-8px" | ||
data-cy="debug-historical-runs" | ||
> | ||
<div class="w-5px left-[15px] absolute border-dashed border-l-0 border-y-0 border-2 border-r-gray-100 h-full" /> |
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.
Instead of adding a DIV here for the dashed line which is not semantically correct inside a ul
, you can add these same classes to a before
pseudo element on the ul
above.
It would be something like:
before:(content-DEFAULT h-full w-5px border-2 border-dashed border-l-0 border-y-0 border-r-gray-100 left-[15px] absolute)
Also, one option to have it match the design more closely would be to remove the h-full
and use a top
and bottom
offset instead.
before:(content-DEFAULT top-20px bottom-10px w-5px border-2 border-dashed border-l-0 border-y-0 border-r-gray-100 left-[15px] absolute)
const current = computed(() => cloudProject.value?.current) | ||
|
||
const latestIsCurrentlySelected = computed(() => { | ||
return latest.value?.commitInfo?.sha === current.value?.commitInfo?.sha |
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.
This should be comparing run numbers, not shas here.
return latest.value?.commitInfo?.sha === current.value?.commitInfo?.sha | |
return latest.value?.runNumber === current.value?.runNumber |
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.
Thanks!
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.
Still testing and going over the code, seems mostly working as expected so far, left some comments/questions.
@@ -1,11 +1,12 @@ | |||
import { gql } from '@urql/core' |
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.
Note for reviewers
Above file packages/data-context/src/sources/RelevantRunSpecsDataSource.ts
is "Large diffs are not rendered by default" but it's a really critical part of this PR - make sure you expand it and take a look!
} | ||
|
||
return SPECS_EMPTY_RETURN | ||
const filter = (run: PartialCloudRunWithId) => { |
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.
When is run.id
not going to be equal to runId
? It looks like this is what causes
function subscribed (value: any) {
//optional filter for stream of data
if (opts?.filter && !opts.filter(value)) {
return
}
// We can get events here before next() is called setting up the deferred promise
To return early - but I think I'm still missing what this does - I'm fairly sure it's to unsubscribe the subscription when the run is no longer running, but I am still figuring out the entirely flow.
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.
I have added some JSDocs to the DataEmitterActions.subscribeTo
method to better describe the options. This filter is a predicate to allow for filtering the values being "emitted" for a subscription. Since there can be multiple "subscriptions" tied to the same "event", I needed a way to only send certain values back on certain subscriptions.
In the Run Navigation use case, there could be multiple running builds in the Cloud at one time that the component wants to subscribe to. The backend query will combine them together and execute one query to the Cloud using the cloudNodesById
field. When the result comes back, the code iterates over each CloudRun
returned to check the cache to see if it changes. If it has changed and an event is sent to the emitter, the filter
will only send through the runs with the matching id
to the correct upstream (i.e. front end) subscription.
if (!this.#poller) { | ||
this.#poller = new Poller(this.ctx, 'relevantRunSpecChange', this.#pollingInterval, async () => { | ||
const runs = this.ctx.relevantRuns.runs | ||
createQuery (infos: GraphQLResolveInfo[]) { |
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.
This is pretty clean - it looks like unless someone has to change something significant, this code should be set and forget - it won't really need to be revisited, which is great!
I'm still not 100% sold on dynamically generating the query, since we lose the declarative nature of GraphQL, which is really nice (you can just copy+paste the code into the Graphical interface and run the query, no longer possible here) but I do think this is the best option we have right now.
|
||
const selections = newFieldNode.selectionSet?.selections! | ||
|
||
return { |
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.
Nice job figuring this out 💯
{ runNumber: 5, status: 'RUNNING', commitInfo: { sha: FAKE_SHAS[2] } }, | ||
{ runNumber: 4, status: 'FAILED', commitInfo: { sha: FAKE_SHAS[1] } }, | ||
{ runNumber: 1, status: 'PASSED', commitInfo: { sha: FAKE_SHAS[0] } }, | ||
], | ||
}, | ||
}, | ||
} |
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.
Not reltaed to this file but I found out that
When I am on the spec page this will show the old status until the new run is completed done - eg, if my run takes 10 min, even if the first test fails, I won't know until the entire run finishes. Is that correct, or should this start auto upadating? Potential bug in polling logic for the Sidebar subscription?
The updates on the debug page are working as expected.
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.
Not reltaed to this file but I found out that
When I am on the spec page this will show the old status until the new run is completed done - eg, if my run takes 10 min, even if the first test fails, I won't know until the entire run finishes. Is that correct, or should this start auto upadating? Potential bug in polling logic for the Sidebar subscription?
The updates on the debug page are working as expected.
This is the expected behavior at this time. There is another initiative called In-App Run Notifications to address providing better feedback to the user about Cloud runs when you are not on the Debug page or not looking at the Cypress app at all.
mostly works great, found one small bug with the time incrementing incorrectly after runs complete in some situations: https://www.loom.com/share/5cd609f2ff59433e8c9b8795cc1ba957?highlightComment=11609224&t=435 That video is really long so I'll gather up all the feedback that was actually useful and add it here, mostly around a11y, and a little bit around the legibility of the UI, nothing blocking apart from the bug. |
> | ||
<component | ||
:is="isCurrentRun ? 'div': 'button'" | ||
:aria-label="t('debugPage.switchToRun', {runNumber: gql.runNumber})" |
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.
This aria label has some problems. I think there needs to be a computed
for the runNumber
to populate, as it's probably just evaluated once on render, meaning we have an empty run number in the label.
But when this renders a button, the presence of aria-label
prevents the internal content from being exposed to screen readers, the label becomes the accessible name. When it's a div and not interactive this doesn't seem to be a problem. Loom.
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.
A click hander on a div is fine if there is a button inside that can emit a click and be the focus target for keyboard users, even if the visual style makes the whole row look selected.
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.
I follow all of your feedback. I will create a follow up issue for this. I can see where we also make use of the HeadlessUI radio group component to get better keyboard navigation in that page you mention in the loom.
Looking into this, but unable to replicate in the tests yet. |
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.
Looks good in my local testing, going to approve assuming items already identified will be resolved/answered. Just seeing some cleanup items
@marktnoonan I fixed the issue with the time counting up not stopping when the run completes that you noted in your loom. Can you give it another test? |
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.
Everything looked good in my local testing. nice 🎉
Co-authored-by: Adam Stone-Lord <adams@cypress.io>
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.
✅
@@ -182,22 +194,30 @@ const props = withDefaults(defineProps<{ | |||
isLoading?: boolean | |||
commitsAhead?: number | |||
online?: boolean | |||
currentCommitInfo?: InstanceType<typeof DebugRunNavigation>['$props']['currentCommitInfo'] | null |
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.
Hadn't seen this to extract the prop types, neat trick!
|
||
return relevantRunsHaveNotLoaded || (currentRunIsChanging && (queryIsBeingFetched || waitingForRunToFetchFromTheCloud)) | ||
}) | ||
|
||
watchEffect(() => { | ||
//console.log('query for debug', query.data.value, relevantRuns.value.commitShas) |
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.
Should we remove this? Surprised linting is okay.
Additional details
There are two main parts to this PR:
DebugRunNavigation
component and its childDebugRunNavigationRow
componentRelevantRunsDataSource
andRelevantRunSpecsDataSource
to support itThe other changes all involve refactoring various parts of the code for reuse, and some general UI fixes/improvements that were found will testing this feature.
Steps to test
You can see various states of this component by opening the App for existing projects (like our own Cypress project), but the easiest way to test will be to have your own Cloud project that you can easily record local runs against.
Scenarios to test:
How has the user experience changed?
The Debug page will now show a new component at the top when scenarios allow for changing between different runs for debugging.
See the linked issue #25899 for screenshots and details.
PR Tasks
cypress-documentation
?type definitions
?