Skip to content
Permalink
Browse files
fix(protractor): The Clear interaction willl complain if used with an…
… element that cannot be cleared

Thanks to @Ethan-G for reporting the issue!
  • Loading branch information
jan-molak committed Sep 24, 2019
1 parent 01972de commit f7908a8e6142e66f5c7a70fe8811cdd3a732da05
Showing with 39 additions and 8 deletions.
  1. +16 −1 packages/protractor/spec/screenplay/interactions/Clear.spec.ts
  2. +23 −7 packages/protractor/src/screenplay/interactions/Clear.ts
@@ -1,8 +1,9 @@
import { expect, stage } from '@integration/testing-tools';
import { Ensure, equals } from '@serenity-js/assertions';
import { LogicError } from '@serenity-js/core';

import { by } from 'protractor';
import { Clear, Navigate, Target, Value } from '../../../src';
import { Clear, Navigate, Target, Text, Value } from '../../../src';
import { pageFromTemplate } from '../../fixtures';
import { UIActors } from '../../UIActors';

@@ -86,6 +87,20 @@ describe('Clear', () => {
Ensure.that(Value.of(Form.Field), equals('')),
));

/** @test {Clear} */
/** @test {Clear.theValueOf} */
it('complains if the element cannot be cleared', () => expect(Bernie.attemptsTo(
Navigate.to(pageFromTemplate(`
<html dir="rtl">
<body>
<div id="field">Hello World!</div>
</body>
</html>
`)),

Clear.theValueOf(Form.Field),
)).to.be.rejectedWith(LogicError, `The input field doesn't seem to have a 'value' attribute that could be cleared.`));

/** @test {Clear#toString} */
it('provides a sensible description of the interaction being performed', () => {
expect(Clear.theValueOf(Form.Field).toString())
@@ -1,4 +1,4 @@
import { AnswersQuestions, Interaction, Question, UsesAbilities } from '@serenity-js/core';
import { AnswersQuestions, Interaction, LogicError, Question, UsesAbilities } from '@serenity-js/core';
import { formatted } from '@serenity-js/core/lib/io';
import { ElementFinder, protractor } from 'protractor';
import { withAnswerOf } from '../withAnswerOf';
@@ -14,18 +14,34 @@ export class Clear extends Interaction {

performAs(actor: UsesAbilities & AnswersQuestions): PromiseLike<void> {
return withAnswerOf(actor, this.field, elf =>
elf.getAttribute('value').then(value =>
elf.sendKeys(
protractor.Key.END,
...this.times(value.length, protractor.Key.BACK_SPACE),
),
));
elf.getAttribute('value').then(value => {
if (! value) {
throw new LogicError(
`${ this.capitaliseFirstLetter(this.field.toString()) } doesn't seem to have a 'value' attribute that could be cleared.`,
);
}

return this.removeCharactersFrom(elf, value.length);
}));
}

toString(): string {
return formatted `#actor clears the value of ${ this.field }`;
}

private capitaliseFirstLetter(text: string) {
return text.charAt(0).toUpperCase() + text.substring(1);
}

private removeCharactersFrom(elf: ElementFinder, numberOfCharacters: number): PromiseLike<void> {
return numberOfCharacters === 0
? Promise.resolve(void 0)
: elf.sendKeys(
protractor.Key.END,
...this.times(numberOfCharacters, protractor.Key.BACK_SPACE),
);
}

private times(n: number, key: string) {
return Array.from(new Array(n)).map(() => key);
}

0 comments on commit f7908a8

Please sign in to comment.