This repository has been archived by the owner on Mar 6, 2024. It is now read-only.
RFC: Improve the type system around options in widgets #334
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
When a user exposed an element using the
factory
, it created a find function that had one parameter ofFindElementOptions
. This has an ancestor ofunknown
andoptions
ofUnknownOptions
. Within a widget, this makes sense, but external to a widget, these options should be known. In the case of Cypress, the ancestor is a string, and in the case of Angular the ancestor is a DebugElement.This problem also happens if a user tries to take in options that are passed to a call to
click
. There was no way for these options to be type safe. They were always unknown.Solution
It should be possible for these options to be type safe. In a
stepdef
file, we know we are dealing with Cypress, and in aspec
we know we are dealing with Angular.To accomplish this, the solution was to make the type of the options conditional on the type of entity being returned. Meaning, the type of
FindElementOptions
is now conditional on the typeT
passed in. If it is aChainable
, it gives a Cypress options interface; if it is aTestElement
it gives an Angular options interface.This now means two things:
{ timeout: x }
to a method will throw a type error. This makes sense because widget should not know about the options they accept. If a method needs a changed timeout, these options must be passed from the caller as aWidgetActionOptions<T>
. Before because these options were not type safe, passingtimeout
within a widget would not throw an error.In concrete terms,
findDataExporter({ options: { timeout: 10000 } })
is valid from a stepdef, but invalid from a unit test. The type ofancestor
is also known and type checked.Example:
Here's a widget that has a few methods that use this new object:
From a stepdef, using this widget would look like:
From a unit test, using this widget would look like:
Cons
FindElementOptions
needs to know about the different types of widgets so that it can infer which options type to create. This violates some OOP, but is acceptable in my opinion.Other Options
O1
andO2
which is not ideal.Ex:
Screenshots (if applicable)
Does this PR introduce a breaking change?
FindCypressWidgetOptions
is no longer an exported type.