From 4c695f0e259c26baa1b17486e8f33b9f9d72e5c8 Mon Sep 17 00:00:00 2001 From: Charles Lowell Date: Wed, 8 Jul 2020 12:41:29 -0500 Subject: [PATCH] When Interactor promise resolves, it implies success Our DSL requires that for a assertions, they either be a return type of `void` or `Promise`. This makes sense since assertions represent the end of the line, and cannot contribute anything back to their environment. They either succeed or fail. However, this mean that instead of being able to write: ```ts test("My Test") .assertion("has a submit button", () => Link("Submit").exists()) ``` we have to explicitly throw away the return value of the promise: ```ts test("My Test") .assertion("has a submit button", async () => { await Link("Submit").exists(); }); ``` This converts all assertions like `exists()`, `absent()`, and friends to merely resolve if the condition is met, not actually return anything. This makes sense since the binary choice of pass or fail hinges purely on whether the promise resolves or rejects. So we don't need any further information. --- .changeset/resolved-implies-success.md | 6 ++++ packages/interactor/src/interactor.ts | 13 ++++---- .../interactor/test/create-interactor.test.ts | 32 +++++++++---------- 3 files changed, 28 insertions(+), 23 deletions(-) create mode 100644 .changeset/resolved-implies-success.md diff --git a/.changeset/resolved-implies-success.md b/.changeset/resolved-implies-success.md new file mode 100644 index 000000000..37f72dfad --- /dev/null +++ b/.changeset/resolved-implies-success.md @@ -0,0 +1,6 @@ +--- +"@bigtest/interactor": minor +--- +Drop resolve value from interactions and assertions. If the promise +resolves, that means it was successful. in other words, the type of +`exists()` is now `() => Promise`, not `() => Promise` diff --git a/packages/interactor/src/interactor.ts b/packages/interactor/src/interactor.ts index e0dca7366..d07878f60 100644 --- a/packages/interactor/src/interactor.ts +++ b/packages/interactor/src/interactor.ts @@ -61,23 +61,22 @@ export class Interactor> }); } - exists(): Interaction { + exists(): Interaction { return interaction(`${this.description} exists`, () => { return converge(() => { this.unsafeSyncResolve(); - return true; }); }); } - absent(): Interaction { + absent(): Interaction { return interaction(`${this.description} does not exist`, () => { return converge(() => { try { this.unsafeSyncResolve(); } catch(e) { if(e.name === 'NoSuchElementError') { - return true; + return; } } throw new NotAbsentError(`${this.description} exists but should not`); @@ -85,13 +84,13 @@ export class Interactor> }); } - is(filters: FilterImplementation): Interaction { + is(filters: FilterImplementation): Interaction { let filter = new Filter(this.specification, filters); return interaction(`${this.description} matches filters: ${filter.description}`, () => { return converge(() => { let element = this.unsafeSyncResolve(); if(filter.matches(element)) { - return true; + return; } else { throw new FilterNotMatchingError(`${this.description} does not match filters: ${filter.description}`); } @@ -99,7 +98,7 @@ export class Interactor> }); } - has(filters: FilterImplementation): Interaction { + has(filters: FilterImplementation): Interaction { return this.is(filters); } } diff --git a/packages/interactor/test/create-interactor.test.ts b/packages/interactor/test/create-interactor.test.ts index 5961422d8..9edd732d7 100644 --- a/packages/interactor/test/create-interactor.test.ts +++ b/packages/interactor/test/create-interactor.test.ts @@ -63,7 +63,7 @@ describe('@bigtest/interactor', () => {

Foo Bar

`); - await expect(Link('Foo Bar').exists()).resolves.toEqual(true); + await expect(Link('Foo Bar').exists()).resolves.toBeUndefined(); await expect(Link('Blah').exists()).rejects.toHaveProperty('message', 'link "Blah" does not exist'); }); @@ -72,7 +72,7 @@ describe('@bigtest/interactor', () => {

Foo Bar

`); - await expect(Link.byTitle('Monkey').exists()).resolves.toEqual(true); + await expect(Link.byTitle('Monkey').exists()).resolves.toBeUndefined(); await expect(Link.byTitle('Zebra').exists()).rejects.toHaveProperty('message', 'link with title "Zebra" does not exist'); }); @@ -86,7 +86,7 @@ describe('@bigtest/interactor', () => { `); - await expect(Link('Foo Bar').exists()).resolves.toEqual(true); + await expect(Link('Foo Bar').exists()).resolves.toBeUndefined(); }); it('can return description', () => { @@ -100,7 +100,7 @@ describe('@bigtest/interactor', () => {

Foo Bar

`); - await expect(Link('Blah').absent()).resolves.toEqual(true); + await expect(Link('Blah').absent()).resolves.toBeUndefined(); await expect(Link('Foo Bar').absent()).rejects.toHaveProperty('message', 'link "Foo Bar" exists but should not'); }); @@ -114,7 +114,7 @@ describe('@bigtest/interactor', () => { `); - await expect(Link('Foo Bar').absent()).resolves.toEqual(true); + await expect(Link('Foo Bar').absent()).resolves.toBeUndefined(); }); it('can return description', () => { @@ -133,8 +133,8 @@ describe('@bigtest/interactor', () => { `); - await expect(Div("foo").find(Link("Foo")).exists()).resolves.toEqual(true); - await expect(Div("bar").find(Link("Bar")).exists()).resolves.toEqual(true); + await expect(Div("foo").find(Link("Foo")).exists()).resolves.toBeUndefined(); + await expect(Div("bar").find(Link("Bar")).exists()).resolves.toBeUndefined(); await expect(Div("foo").find(Link("Bar")).exists()).rejects.toHaveProperty('message', 'link "Bar" within div "foo" does not exist'); await expect(Div("bar").find(Link("Foo")).exists()).rejects.toHaveProperty('message', 'link "Foo" within div "bar" does not exist'); @@ -175,10 +175,10 @@ describe('@bigtest/interactor', () => { Foo `); - await expect(Div("test").find(Div("foo").find(Link("Foo"))).exists()).resolves.toEqual(true); + await expect(Div("test").find(Div("foo").find(Link("Foo"))).exists()).resolves.toBeUndefined(); await expect(Div("test").find(Div("foo").find(Link("Bar"))).exists()).rejects.toHaveProperty('message', 'link "Bar" within div "foo" within div "test" does not exist'); - await expect(Div("test").find(Div("foo")).find(Link("Foo")).exists()).resolves.toEqual(true); + await expect(Div("test").find(Div("foo")).find(Link("Foo")).exists()).resolves.toBeUndefined(); await expect(Div("test").find(Div("foo")).find(Link("Bar")).exists()).rejects.toHaveProperty('message', 'link "Bar" within div "foo" within div "test" does not exist'); }); }); @@ -189,7 +189,7 @@ describe('@bigtest/interactor', () => { `); - await expect(TextField('Email').is({ value: 'jonas@example.com' })).resolves.toEqual(true); + await expect(TextField('Email').is({ value: 'jonas@example.com' })).resolves.toBeUndefined(); await expect(TextField('Email').is({ value: 'incorrect@example.com' })).rejects.toHaveProperty('message', 'text field "Email" does not match filters: with value "incorrect@example.com"'); }); }); @@ -200,7 +200,7 @@ describe('@bigtest/interactor', () => { `); - await expect(TextField('Email').has({ value: 'jonas@example.com' })).resolves.toEqual(true); + await expect(TextField('Email').has({ value: 'jonas@example.com' })).resolves.toBeUndefined(); await expect(TextField('Email').has({ value: 'incorrect@example.com' })).rejects.toHaveProperty('message', 'text field "Email" does not match filters: with value "incorrect@example.com"'); }); }); @@ -257,7 +257,7 @@ describe('@bigtest/interactor', () => { `); await Div("foo").find(Link('Foo Bar')).click(); - await expect(Header('Hello!').exists()).resolves.toEqual(true); + await expect(Header('Hello!').exists()).resolves.toBeUndefined(); }); it('can return description of interaction', () => { @@ -275,8 +275,8 @@ describe('@bigtest/interactor', () => { `); - await expect(TextField('Email').exists()).resolves.toEqual(true); - await expect(TextField('Email', { value: 'jonas@example.com' }).exists()).resolves.toEqual(true); + await expect(TextField('Email').exists()).resolves.toBeUndefined(); + await expect(TextField('Email', { value: 'jonas@example.com' }).exists()).resolves.toBeUndefined(); await expect(TextField('Email', { value: 'incorrect@example.com' }).exists()).rejects.toHaveProperty('message', 'text field "Email" with value "incorrect@example.com" does not exist'); }); @@ -288,7 +288,7 @@ describe('@bigtest/interactor', () => { await expect(TextField('Password').exists()).rejects.toHaveProperty('message', 'text field "Password" does not exist'); await expect(TextField('Password', { enabled: true }).exists()).rejects.toHaveProperty('message', 'text field "Password" which is enabled does not exist'); - await expect(TextField('Password', { enabled: false }).exists()).resolves.toEqual(true); + await expect(TextField('Password', { enabled: false }).exists()).resolves.toBeUndefined(); }); it('can apply multiple filters', async () => { @@ -299,7 +299,7 @@ describe('@bigtest/interactor', () => { await expect(TextField('Password', { enabled: false, value: 'incorrect' }).exists()).rejects.toHaveProperty('message', 'text field "Password" which is not enabled and with value "incorrect" does not exist'); await expect(TextField('Password', { enabled: true, value: 'test1234' }).exists()).rejects.toHaveProperty('message', 'text field "Password" which is enabled and with value "test1234" does not exist'); - await expect(TextField('Password', { enabled: false, value: 'test1234' }).exists()).resolves.toEqual(true); + await expect(TextField('Password', { enabled: false, value: 'test1234' }).exists()).resolves.toBeUndefined(); }); }); })