The selection list usage is somewhat improved - but different - than the earlier usage in Storyteller 1-2. Referring to a named list versus supplying the actual values inline is now two distinctly different usages (SelectionList
vs. SelectionValues
). In addition, Storyteller 3 now supports lists of "display/value" pairs to make more readable specification text.
Storyteller allows you to create user-defined lists of valid values to a Cell for an improved editor experience. These lists can be defined directly on a Cell or referenced by list name to values defined at either the containing Fixture
level or from a custom ISystem.
Defining Lists Directly to a Cell
You can add selection lists directly to a cell with the [SelectionList(name of list)]
or [SelectionValues(value1, value2, ...)]
attributes for grammars that call methods:
public void DoSomething(
[SelectionValues("Tom", "Todd")] string name,
[SelectionList("Numbers")]int x, int y)
{
}
You can also use the SelectionList()
and SelectionValues()
methods on ICellExpression
to add selection values to other kinds of grammars:
public IGrammar OrderedDetailsAre()
{
return VerifySetOf(getDetails)
.Titled("The Ordered details should be")
.Ordered()
// Use this syntax if you want to customize
// the cells in this SetVerification grammar
.Comparisons(_ =>
{
_.Compare(o => o.Amount).DefaultValue("100").Header("The Amount");
_.Compare(o => o.Date)
// Adding a selection list by display/value
.SelectionOptions(
new Option("Today", "TODAY"),
new Option("Yesterday", "TODAY-1"),
new Option("Tomorrow", "TODAY+1")
);
_.Compare(o => o.Name)
.Header("The Name")
// Simple value list
.SelectionValues("Hank", "Tom", "Alice");
// Simply refer to a selection list
// defined elsewhere by name
_.Compare(o => o.Part)
.SelectionList("Parts");
});
}
As of Storyteller 4.1, you can also add any of the attributes on the Type of an argument being passed to a grammar.
Here's an example from the Storyteler.Selenium addon (may still be forthcoming when you read this):
[SelectionList(ScreenFixture.ElementsListName)]
public class NamedElement
{
public string Name { get; }
public NamedElement(string name)
{
Name = name;
}
}
In the case above, NamedElement
refers to a Selenium element in a list in each selenium-aware Fixture class. To make the selection list for the Fixture appear in the editor, I added the [SelectionList]
attribute directly to the
NamedElement
class.
A grammar that uses this is shown below:
[FormatAs("Click {element}")]
public void Click(NamedElement element)
{
forElement(element).Click();
}
Fixture Wide Lists
You can also define named option lists to a Fixture class like this:
public SelectionValuesFixture()
{
AddSelectionValues("Names", "Jeremy", "Monte", "Max");
}
System Wide Lists
Lists can also be defined or built in a custom ISystem
like this:
public CellHandling Start()
{
var handling = CellHandling.Basic();
// Adding a system wide list.
handling.AddSystemLevelList("positions", new[] {"LB", "OL", "DL", "WR", "RB"});
// This is where you can register a custom runtime conversion
handling.RegisterRuntimeConversion<PlayerConverter>();
return handling;
}
What does it look like?
In usage, using a selection list looks like this in the specification editor:
Player Positions | ||
---|---|---|
Player | Position | |
Justin Houston | ||
Add Row |