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

Abstract locatorFor logic #4

Closed
srleecode opened this issue Jan 5, 2021 · 3 comments
Closed

Abstract locatorFor logic #4

srleecode opened this issue Jan 5, 2021 · 3 comments
Labels
enhancement New feature or request

Comments

@srleecode
Copy link
Contributor

I have two related suggestions:

Allow the harness creation to be done with a selector object

It is often the case that you want to select not just a component, but a particular instance of that component. Some examples are:

  • data-cy: selecting a table component with a particular data-cy attribute
  • index: selecting the second table component
  • css: selecting a table component with a particular css class or id
  • text: selecting a button component with particular text in it.

It would be useful if the harness creation allowed passing an object like the below.

interface SelectorOptions {
    dataCy?: string;
    css?: string;
    index?: number;
    text?: string;
}

Abstract verbose test harness logic

The testing harness by default needs properties for the locatorFor etc. We can abstract some of this. Ideally part of that would be creating functions to take a SelectorOptions object and do all the locatorFor logic that is required. A quick draft of something it might look like is:

class CypressComponentTestHarness extends ComponentHarness {
  protected find(selectorOptions: SelectorOptions) {
    return this.locatorForOptional(`[data-cy="${selectorOptions.dataCy}"]`)();
  }
  protected findElement(selectorOptions: SelectorOptions) {
    return this.find(selectorOptions).then((e) => (e as any).element);
  }
  protected call(selectorOptions: SelectorOptions, operation: (e) => this) {
    return this.find(selectorOptions)
      .then((e) => operation(e))
      .then(() => this);
  }

  protected map(selectorOptions: SelectorOptions, operation: (e) => this) {
    return this.find(selectorOptions).then((e) => operation(e));
  }
}

See the below test harness to see how it is used.
https://github.com/srlee309/component-commands-example/blob/master/libs/example/form/.cypress/src/support/component-test-harness.ts

@edbzn edbzn added the enhancement New feature or request label Jan 5, 2021
@edbzn
Copy link
Member

edbzn commented Jan 5, 2021

Hi @srlee309, really appreciate your feedback, thank you! That's something we were thinking about. I really like how you abstracted the locatorFor logic. Would you want to create a PR for that? Maybe we can iterate over it, but that's a good starting point. What do you think @yjaaidi ?

@yjaaidi
Copy link
Member

yjaaidi commented Jan 5, 2021

Hi @srlee309, thank you for your suggestion.
Actually, you can already use HarnessPredicate to achieve this.
Cf. https://material.angular.io/cdk/test-harnesses/overview#filtering-harness-instances-with-harnesspredicate

This would look something like:

export class TitleHarness extends ComponentHarness {
  ...

  static with(
    options: BaseHarnessFilters
  ): HarnessPredicate<TitleHarness> {
    return new HarnessPredicate(TitleHarness, options);
  }
}

...

getHarness(TitleHarness.with({ selector: '...' })

I totally agree that the HarnessPredicate and ComponentHarness implementation are not very convenient. Cf. angular/components#20871

The goal of this library is to provide a way of using existing harnesses with Cypress, but we are planning to release another library (in this repo) that will make harness writing easier.
We are still not sure if we will extend ComponentHarness or provide a completely different approach that could be framework agnostic.

I will close this issue and add a reference to it in a new issue about harness abstraction in general.

@yjaaidi
Copy link
Member

yjaaidi commented Jan 5, 2021

I just opened the issue. @srlee309 if you have any suggestions & ideas, we'd be glad to hear them 😊

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

No branches or pull requests

3 participants