externalNumeric
Index
Constructors
Methods
Constructors
externalconstructor
Returns Numeric
Methods
staticexternalsum
Returns a
Question
that sums up the values provided and throws if any of the values is not anumber
.Adding static numbers
The most basic example of using the
Numeric.sum
method is to add up a few numbers.import { actorCalled, Numeric } from '@serenity-js/core'
import { Ensure, equals } from '@serenity-js/assertions'
await actorCalled('Zoé').attemptsTo(
Ensure.that(
Numeric.sum(1, 2, 3),
equals(6),
)
)The numbers can be provided individually, as an array, or as a combination of both.
import { actorCalled, Numeric } from '@serenity-js/core'
import { Ensure, equals } from '@serenity-js/assertions'
await actorCalled('Zoé').attemptsTo(
Ensure.that(
Numeric.sum([ 1, 2 ], 3, [ 4, 5 ]),
equals(15),
)
)Adding numbers returned by other questions
Apart from adding static numbers, you can also add numbers returned by other questions. This is particularly useful when you need to calculate the sum of numbers extracted from a list of UI elements or from an API response.
import { actorCalled, Numeric, Question } from '@serenity-js/core'
import { Ensure, equals } from '@serenity-js/assertions'
const myNumber = () =>
Question.about('my number', actor => 42)
const myArrayOfNumbers = () =>
Question.about('my array of numbers', actor => [ 1, 2, 3 ])
const myObjectWithNumbers = () =>
Question.about('my object with numbers', actor => ({ a: 1, b: 2, c: 3 }))
await actorCalled('Zoé').attemptsTo(
Ensure.that(
Numeric.sum(
myNumber(), // a question returning a number
myArrayOfNumbers(), // a question returning an array of numbers
),
equals(48),
),
Ensure.that(
Numeric.sum(
myObjectWithNumbers() // a question returning an object with numbers
.as(Object.values), // from which we extract the numeric values
),
equals(6),
),
)Of course, you can also mix and match static numbers with numbers returned by questions.
import { actorCalled, Numeric, Question } from '@serenity-js/core'
import { Ensure, equals } from '@serenity-js/assertions'
const myObjectWithNumbers = () =>
Question.about('my object with numbers', actor => ({ a: 1, b: 2, c: 3 }))
await actorCalled('Zoé').attemptsTo(
Ensure.that(
Numeric.sum(
myObjectWithNumbers().as(Object.values),
[ 4, 5 ],
6,
),
equals(21),
),
)Adding numbers extracted from a UI
To add numbers extracted from a UI:
- use the
PageElement
andPageElements
classes to identify the elements of interest, - use the
Text.of
orText.ofAll
questions to extract the text of the element or elements, - and then interpret this text as number using either the
.as(Number)
mapping function, or theNumeric.intValue()
orNumeric.floatValue()
meta-questions.
For example, we could calculate the sum of quantities of items in our example price list by specifying each element explicitly and mapping its text to
Number
:import { actorCalled, Numeric } from '@serenity-js/core'
import { Ensure, equals } from '@serenity-js/assertions'
import { Text } from '@serenity-js/web'
import { PriceList, PriceListItem } from './ui/price-list'
await actorCalled('Zoé').attemptsTo(
Ensure.that(
Numeric.sum(
Text.of(PriceListItem.quantity().of(PriceList.items().first())).as(Number),
Text.of(PriceListItem.quantity().of(PriceList.items().at(1))).as(Number),
Text.of(PriceListItem.quantity().of(PriceList.items().last())).as(Number),
),
equals(11),
),
)A more elegant approach would be to use the Serenity/JS Page Element Query Language (PEQL) to map each item in the collection to its quantity and then calculate the sum.
import { actorCalled, Numeric } from '@serenity-js/core'
import { Ensure, equals } from '@serenity-js/assertions'
import { Text } from '@serenity-js/web'
import { PriceList, PriceListItem } from './ui/price-list'
await actorCalled('Zoé').attemptsTo(
Ensure.that(
Numeric.sum(
PriceList.items() // get all the li.item elements
.eachMappedTo(
Text.of(PriceListItem.quantity()) // extract the text of the .quantity element
)
.eachMappedTo( // interpret the quantity as an integer value
Numeric.intValue(),
),
),
equals(11), // 5 apples, 4 apricots, 2 bananas
)
)Using PEQL allows us to express the intent more concisely and, for example, introduce helper functions that limit the scope of the operation to a subset of elements.
import { actorCalled, Expectation, Numeric, the } from '@serenity-js/core'
import { Ensure, equals, startsWith } from '@serenity-js/assertions'
import { PriceList, PriceListItem } from './ui/price-list'
const quantitiesOfItemsWhichName = (expectation: Expectation<string>) =>
PriceList.items() // get all the li.item elements
.where( // leave only those which name matches the expectation
Text.of(PriceListItem.name()),
expectation
)
.eachMappedTo(
Text.of(PriceListItem.quantity()) // extract the text of the .quantity element
)
.eachMappedTo( // interpret the quantity as an integer value
Numeric.intValue(),
)
.describedAs(the`quantities of items which name does ${ expectation }`)
await actorCalled('Zoé').attemptsTo(
Ensure.that(
Numeric.sum(
quantitiesOfItemsWhichName(startsWith('ap')), // apples and apricots
),
equals(9), // 5 apples, 4 apricots
)
)Learn more
View the
Numeric
API documentation for more details and examples.Parameters
externalrest...values: Answerable<number | number[]>[]
Returns QuestionAdapter<number>
- use the
staticexternaldifference
Returns a
Question
that calculates the difference between two numbers and throws if any of the values is not anumber
.Subtracting numbers
import { actorCalled, Numeric } from '@serenity-js/core'
import { Ensure, equals } from '@serenity-js/assertions'
import { Text } from '@serenity-js/web'
import { PriceList, PriceListItem } from './ui/price-list'
await actorCalled('Zoé').attemptsTo(
Ensure.that(
Numeric.difference(
Text.of(PriceListItem.quantity().of(PriceList.items().first())).as(Number), // 5 (apples)
2, // - 2
),
equals(3),
),
)Learn more
View the
Numeric
API documentation for more details and examples.Parameters
externalminuend: Answerable<number>
externalsubtrahend: Answerable<number>
Returns QuestionAdapter<number>
staticexternalceiling
Returns a
MetaQuestion
that calculates the ceiling of a number and throws if the value is not anumber
.Calculating the ceiling of a number
import { actorCalled, Numeric } from '@serenity-js/core'
import { Ensure, equals } from '@serenity-js/assertions'
import { Text } from '@serenity-js/web'
import { PriceList, PriceListItem } from './ui/price-list'
await actorCalled('Zoé').attemptsTo(
Ensure.that(
Numeric.ceiling().of(
Text.of(PriceListItem.price().of(PriceList.items().first())) // '£2.25' (apples)
.replace('£', '') // '2.25'
.as(Number.parseFloat), // 2.25
),
equals(3),
),
)Learn more
View the
Numeric
API documentation for more details and examples.Returns MetaQuestion<number, QuestionAdapter<number>>
staticexternalfloor
Returns a
MetaQuestion
that calculates the floor of a number and throws if the value is not anumber
.Calculating the floor of a number
import { actorCalled, Numeric } from '@serenity-js/core'
import { Ensure, equals } from '@serenity-js/assertions'
import { Text } from '@serenity-js/web'
import { PriceList, PriceListItem } from './ui/price-list'
await actorCalled('Zoé').attemptsTo(
Ensure.that(
Numeric.floor().of(
Text.of(PriceListItem.price().of(PriceList.items().first())) // '£2.25' (apples)
.replace('£', '') // '2.25'
.as(Number.parseFloat), // 2.25
),
equals(2),
),
)Learn more
View the
Numeric
API documentation for more details and examples.Returns MetaQuestion<number, QuestionAdapter<number>>
staticexternalmax
Returns a
Question
that calculates the maximum value in the lists of numbers provided and throws if any of the values is not anumber
.Calculating the maximum value
import { actorCalled, Numeric } from '@serenity-js/core'
import { Ensure, equals } from '@serenity-js/assertions'
import { Text } from '@serenity-js/web'
import { PriceList, PriceListItem } from './ui/price-list'
await actorCalled('Zoé').attemptsTo(
Ensure.that(
Numeric.max(
PriceList.items() // get all the li.item elements
.eachMappedTo(
Text.of(PriceListItem.quantity()) // extract the text of the .quantity element
)
.eachMappedTo( // interpret the quantity as an integer value
Numeric.intValue(),
),
),
equals(5), // 5 (apples)
)
)Learn more
View the
Numeric
API documentation for more details and examples.Parameters
externalrest...values: Answerable<number | number[]>[]
Returns QuestionAdapter<number>
staticexternalmin
Returns a
Question
that calculates the minimum value in the lists of numbers provided and throws if any of the values is not anumber
.Calculating the minimum value
import { actorCalled, Numeric } from '@serenity-js/core'
import { Ensure, equals } from '@serenity-js/assertions'
import { Text } from '@serenity-js/web'
import { PriceList, PriceListItem } from './ui/price-list'
await actorCalled('Zoé').attemptsTo(
Ensure.that(
Numeric.min(
PriceList.items() // get all the li.item elements
.eachMappedTo(
Text.of(PriceListItem.quantity()) // extract the text of the .quantity element
)
.eachMappedTo( // interpret the quantity as an integer value
Numeric.intValue(),
),
),
equals(2), // 2 (bananas)
)
)Learn more
View the
Numeric
API documentation for more details and examples.Parameters
externalrest...values: Answerable<number | number[]>[]
Returns QuestionAdapter<number>
staticexternalintValue
Returns a
MetaQuestion
that parses a stringvalue
and returns an integer of the specifiedbase
. Leading whitespace in the value to parse argument is ignored.Parsing a string as an integer
import { actorCalled, Numeric } from '@serenity-js/core'
import { Ensure, equals } from '@serenity-js/assertions'
import { Text } from '@serenity-js/web'
import { PriceList, PriceListItem } from './ui/price-list'
await actorCalled('Zoé').attemptsTo(
Ensure.that(
Numeric.intValue().of(
Text.of( // '5' (apples)
PriceListItem.quantity().of(
PriceList.items().first()
)
)
),
equals(5),
),
)Learn more
View the
Numeric
API documentation for more details and examples.Parameters
externaloptionalbase: Answerable<number>
An integer between 2 and 36 that represents the base in mathematical numeral systems of the string. If base is undefined or 0, it is assumed to be 10 except when the number begins with the code unit pairs 0x or 0X, in which case a radix of 16 is assumed.
Returns MetaQuestion<string, QuestionAdapter<number>>
staticexternalbigIntValue
Returns a
MetaQuestion
that parses a stringvalue
and returns aBigInt
. Leading whitespace in the value to parse argument is ignored.Parsing a string as a bigint
import { actorCalled, Numeric } from '@serenity-js/core'
import { Ensure, equals } from '@serenity-js/assertions'
import { Text } from '@serenity-js/web'
import { PriceList, PriceListItem } from './ui/price-list'
await actorCalled('Zoé').attemptsTo(
Ensure.that(
Numeric.bigIntValue().of(
Text.of( // '5' (apples)
PriceListItem.quantity().of(PriceList.items().first())
)
),
equals(BigInt('5')),
),
)Learn more
View the
Numeric
API documentation for more details and examples.Returns MetaQuestion<string, QuestionAdapter<bigint>>
staticexternalfloatValue
Returns a
MetaQuestion
that parses a stringvalue
and returns a floating-point number.Parsing a string as a floating point number
import { actorCalled, Numeric } from '@serenity-js/core'
import { Ensure, equals } from '@serenity-js/assertions'
import { Text } from '@serenity-js/web'
import { PriceList, PriceListItem } from './ui/price-list'
await actorCalled('Zoé').attemptsTo(
Ensure.that(
Numeric.floatValue().of(
Text.of( // '£2.25'
PriceListItem.price().of(PriceList.items().first())
).replace('£', '') // '2.25'
),
equals(2.25),
),
)Learn more
View the
Numeric
API documentation for more details and examples.Returns MetaQuestion<string, QuestionAdapter<number>>
Provides methods to perform calculations on numeric values returned by other questions.
Example
The examples in this section demonstrate interacting with an HTML widget representing a price list.
Lean Page Objects
To represent our example HTML widget, we follow the Lean Page Objects pattern to define the
PriceList
andPriceListItem
classes and use the Serenity/JS Page Element Query Language (PEQL) to identify the elements of interest.