Skip to content

feat: implement spec list tree #18901

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

Merged
merged 10 commits into from
Nov 16, 2021
Merged

feat: implement spec list tree #18901

merged 10 commits into from
Nov 16, 2021

Conversation

ImCesar
Copy link
Contributor

@ImCesar ImCesar commented Nov 12, 2021

Create the tree view for the spec runner

Demo

file.tree.demo.mov

PR Tasks

  • Have tests been added/updated?
  • Has the original issue or this PR been tagged with a release in ZenHub?
  • Has a PR for user-facing changes been opened in cypress-documentation?
  • Have API changes been updated in the type definitions?
  • Have new configuration options been added to the cypress.schema.json?

@ImCesar ImCesar requested review from JessicaSachs and a team November 12, 2021 22:30
@cypress-bot
Copy link
Contributor

cypress-bot bot commented Nov 12, 2021

Thanks for taking the time to open a PR!

@CLAassistant
Copy link

CLAassistant commented Nov 12, 2021

CLA assistant check
All committers have signed the CLA.

@ImCesar ImCesar force-pushed the feat-spec-list-branch branch from 25b912c to ba5c01a Compare November 12, 2021 22:46
@cypress
Copy link

cypress bot commented Nov 12, 2021



Test summary

18647 2 216 7Flakiness 3


Run details

Project cypress
Status Failed
Commit 5edcf67
Started Nov 16, 2021 12:39 AM
Ended Nov 16, 2021 12:50 AM
Duration 11:23 💡
OS Linux Debian - 10.9
Browser Multiple

View run in Cypress Dashboard ➡️


Failures

Run group: 5x-driver-chrome (Linux, Chrome )
commands/assertions_spec.js Failed
1 ... > language chainers err > throws err when assertion contains only one language chainer: and
Run group: 2x-desktop-gui (Linux, Electron )
settings_spec.js Failed
1 Settings > file preference panel > loads preferred editor and available editors

Flakiness

commands/net_stubbing_spec.ts Flakiness
1 network stubbing > waiting and aliasing > can timeout waiting on a single request using "alias.request"
2 network stubbing > waiting and aliasing > can timeout waiting on a single request using "alias.request"
cypress/proxy-logging-spec.ts Flakiness
1 ... > works with forceNetworkError

This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Dashboard

Copy link
Contributor

@lmiller1990 lmiller1990 left a comment

Choose a reason for hiding this comment

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

I left some comments! I tested it out, works great. I also noticed we were missing some types so I added them and pushed here: 4dd17c2. Hopefully this is okay.

/>
<i-cy-folder_x16 class="mr-8px w-16px h-16px" />
<template
v-for="(directory, idx) in directories || []"
Copy link
Contributor

Choose a reason for hiding this comment

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

We can avoid this check with withDefaults:

withDefaults(
  defineProps<{ directories: string [] }>(),
  directories: []
)

name: '',
}
before(() => {
cy.fixture('found-specs').then((foundSpecs) => specs = foundSpecs)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you need to do return cy.fixture. In mocha, if return a promise from before, it will wait for the promise to resolve. As it stands, I think this would be race condition.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's never necessary to return commands or manually await them. Cypress will always wait for the queue to finish before proceeding from the hook. Commands are promise-like, but not true promises, and even .then is a command.

Copy link
Contributor

Choose a reason for hiding this comment

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

Cool, good to know, thanks @chrisbreiding

}
}

const rootEl: Ref<HTMLElement | undefined> = ref()
Copy link
Contributor

Choose a reason for hiding this comment

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

Can be more concise; I think you can just do

const rootEl: Ref<HTMLElement> = ref()

undefined is implied by the lack of an initial value

Copy link
Contributor

Choose a reason for hiding this comment

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

I get Type 'Ref<HTMLElement | undefined>' is not assignable to type 'Ref<HTMLElement>'. Type 'HTMLElement | undefined' is not assignable to type 'HTMLElement'. when I try this.

Copy link
Contributor

@lmiller1990 lmiller1990 Nov 15, 2021

Choose a reason for hiding this comment

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

Oh, my bad, you don't need Ref:

const rootEl = ref<HTMLElement>()

should suffice

Edit: I changed it to this and it's working:

const rootEl = ref<HTMLUListElement>()

We can also type the specific type of element, in this case HTMLUListElement

const onRowClick = (row: UseCollapsibleTreeNode<SpecTreeNode>, idx) => {
selectedItem.value = idx
if (row.isLeaf) {
router.push({ path: 'runner', query: { file: row.data?.relative } })
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this ? make sense? Can we ever push to runner when file is null? Eg, should we be doing something like:

if (row.isLeaf) {
  if (!file.data?.relative) {
     return
  }
  router.push({ path: 'runner', query: { file: row.data?.relative } })
}

Copy link
Contributor

Choose a reason for hiding this comment

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

That's more of a limitation as to how we typed the row. If the node is a leaf node, it's guaranteed to have a spec on the data property. I'll see if I can tweak the types a bit more so it's happy, otherwise I'll add your check.


const specTree = computed(() => buildSpecTree(props.specs))
const collapsible = computed(() => useCollapsibleTree(specTree.value, { dropRoot: true }))
const filteredTree = computed(() => collapsible.value.tree.filter(((item) => !item.hidden.value)))
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems specTree and collapsible is only used by filteredTree. That means we create three computed properties, but really we only want one? Should this be:

const filteredTree = computed(() => {
  const specTree = buildSpecTree(props.specs))
  const collapsible = useCollapsibleTree(specTree.value, { dropRoot: true }))
  collapsible.value.tree.filter(((item) => !item.hidden.value))
})

Also, I don't think buildSpecTree should return an object with a value property. It makes it looks like it's returning a ref (because of the .value property). I was expecting to see a return type of Ref - but looking at the function, it's just a regular JS object with a non-reactive property that happens to be called value, unless I'm missing something?

Copy link
Contributor

@ZachJW34 ZachJW34 Nov 15, 2021

Choose a reason for hiding this comment

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

I tried this but it breaks the collapsing functionality. I believe it's because the computed properties referenced from collapsible are defined inside another computed property so Vue doesn't properly track the changes.

And you're right, .value is confusing, I'll change it to .name

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah I noticed when I tried the refactor... This computed in a computed is a bit weird, I wonder if there's a better way.

options.expandInitially = options.expandInitially || true
const collapsibleTree = buildTree(tree, options)
const collapsibleTree = buildTree<T>(tree, options)

const expand = (matches?) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see anywhere in the code base that expand or reveal is called with an argument - what is matches? Is this used?

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see a use for it but @JessicaSachs might have an opinion, maybe for future functionality?

Comment on lines 16 to 20
<template v-else>
<div class="text-white">
FileTree not implemented
</div>
<InlineSpecListTree
:specs="specs.map(spec => spec.node)"
/>
</template>
Copy link
Contributor

Choose a reason for hiding this comment

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

Why use a <template> here if there is only going to be one element?
Same above.

Copy link
Contributor

Choose a reason for hiding this comment

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

Fixed!

@lmiller1990 lmiller1990 changed the base branch from unified-desktop-gui to 10.0-release November 16, 2021 00:01
@lmiller1990 lmiller1990 merged commit 651b91b into 10.0-release Nov 16, 2021
@lmiller1990 lmiller1990 deleted the feat-spec-list-branch branch November 16, 2021 13:18
tgriesser added a commit that referenced this pull request Nov 16, 2021
* 10.0-release:
  feat: Use plugins on config files (#18798)
  BREAKING CHANGE: trigger major bump
  BREAKING CHANGE: trigger major bump
  fix: fix cypress/package.json crasher
  fix(breaking): change circle.yml to release binary
  fix: build-prod-ui deps before build-prod packages
  feat: implement spec list tree (#18901)
  chore: adding 10.0-release to the circle.yml build script (#18926)
tgriesser added a commit that referenced this pull request Nov 17, 2021
* 10.0-release:
  feat: improve vite DX (#18937)
  feat: Use plugins on config files (#18798)
  BREAKING CHANGE: trigger major bump
  BREAKING CHANGE: trigger major bump
  fix: fix cypress/package.json crasher
  fix(breaking): change circle.yml to release binary
  fix: build-prod-ui deps before build-prod packages
  feat: implement spec list tree (#18901)
  chore: adding 10.0-release to the circle.yml build script (#18926)
  feat(app): remove __vite__ route and default to unified runner (#18909)
  fix: app layout + specs list review (#18862)
  feat(app): show previous versions (#18838)
  feat: scaffold integration files in app (#18763)
  feat: add footer to the settings (#18867)
  fix: Exit when both --e2e and --component flags are passed in (#18855)
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.

6 participants