Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Acceptance Test POC and Setup #41

Merged
merged 42 commits into from
Jun 23, 2021
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
a058659
chore: Add tests workspace and ignore cypress gens
slaymance Jun 11, 2021
02bc418
build(acceptance-tests): setup cypress testing and typescript suppport
slaymance Jun 11, 2021
5d587af
test(acceptance-tests): add sample test for SignIn
slaymance Jun 11, 2021
68a2a84
Update cucumber and cypress tests
slaymance Jun 16, 2021
7f8825b
Revert lock file changes
slaymance Jun 16, 2021
9ee1d35
Merge remote-tracking branch 'origin/main' into acceptance-tests
slaymance Jun 16, 2021
e52c9ae
Update lock file with package changes
slaymance Jun 16, 2021
99f880e
Fix conflict
slaymance Jun 17, 2021
13ab7d5
Merge remote-tracking branch 'origin/main' into acceptance-tests
slaymance Jun 18, 2021
c5164be
Move acceptance-tests to packages/e2e
ericclemmons Jun 18, 2021
4b5fcda
Merge branch 'main' of github.com:aws-amplify/amplify-ui into accepta…
ericclemmons Jun 18, 2021
b2e29ca
Use aws-amplify@latest for all packages
ericclemmons Jun 18, 2021
1271db5
Add aws-amplify-react for testing
ericclemmons Jun 18, 2021
4deafc1
Add @aws-amplify/ui-react-v1 for explicitly testing the previous version
ericclemmons Jun 18, 2021
8a49fd6
Update yarn.lock to match
ericclemmons Jun 18, 2021
b8859e1
Sign In with valid/invalid credentials tests
ericclemmons Jun 18, 2021
1ba2ac7
Ignore .env.local
ericclemmons Jun 18, 2021
cd85c1e
Merge remote-tracking branch 'origin/acceptance-tests' into acceptanc…
slaymance Jun 21, 2021
037de1a
Prototype CONTRIBUTING.md
ericclemmons Jun 21, 2021
aec2801
Merge remote-tracking branch 'origin/acceptance-tests' into acceptanc…
slaymance Jun 21, 2021
472699d
Update ignored files and lockfile
slaymance Jun 21, 2021
f44d245
Add Cypress env variables and use scenario outline
slaymance Jun 21, 2021
6b9eb06
Remove acceptance-tests workspace
slaymance Jun 21, 2021
ad53122
Rename test to use .steps.ts and type button name
slaymance Jun 21, 2021
5dc5c34
Revert feature steps to separate explicit scenarios
slaymance Jun 22, 2021
57f75c4
Render acceptance tests by convention
ericclemmons Jun 22, 2021
22c0e05
Merge branch 'acceptance-tests' of github.com:aws-amplify/amplify-ui …
ericclemmons Jun 22, 2021
12e4708
Add `key` to prevent warnings
ericclemmons Jun 22, 2021
62e8854
Reconfigure .gitignore options
slaymance Jun 23, 2021
2be7cd7
Rename tests directory to conventional "integration"
slaymance Jun 23, 2021
5f82de6
Replace dotenv with dotenv-safe
slaymance Jun 23, 2021
743b537
Revert changes to SignIn component
slaymance Jun 23, 2021
efd55fd
Rename example env file
slaymance Jun 23, 2021
133beb6
Remove unnecessary cypress-cucumber-preprocessor config option
slaymance Jun 23, 2021
4e91365
Update lockfile
slaymance Jun 23, 2021
05aea11
Remove ignored cypress dirs from root
slaymance Jun 23, 2021
663e4db
Fix path to feature tests
ericclemmons Jun 23, 2021
71a9d67
Type featureTests
ericclemmons Jun 23, 2021
60499a9
Remove example.json from fixtuers/
slaymance Jun 23, 2021
a014113
Organize imports
ericclemmons Jun 23, 2021
aed65c9
Amplify typo
ericclemmons Jun 23, 2021
e9795ee
Merge branch 'acceptance-tests' of github.com:aws-amplify/amplify-ui …
ericclemmons Jun 23, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
.DS_Store
.env
.env.local
*.log
node_modules
aws-exports.js
Expand Down
81 changes: 81 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Contributing

## Getting Started

1. Fork & Clone this repo
1. [`nvm install`](https://github.com/nvm-sh/nvm)
1. [`nvm use`](https://github.com/nvm-sh/nvm)
1. `yarn install`

## Documentation Development

1. Run the documentation via `yarn docs`
1. Visit <http://localhost:3000/>
1. Create/Update content based on the URL.

For example, the content for
http://localhost:3000/components/authenticator is located at [`docs/src/content/components/authenticator/index.mdx`](docs/src/content/components/authenticator/index.mdx)

Internally, this content is served by a single, Next.js [optional catch all route](https://nextjs.org/docs/routing/dynamic-routes#optional-catch-all-routes):
[`docs/src/pages/[[...slugs]].tsx`](docs/src/pages/[[...slugs]].tsx).

## React Development

1. `yarn docs` to run the development server
1. Create or Update an example at [`docs/src/pages/component/authenticator/examples/...`](docs/src/pages/component/authenticator/examples)

```js
// .../authenticator/examples/sign-in.ts
import { Authenticator } from "aws-amplify-react";
import { Amplify } from "aws-amplify";
import "@aws-amplify/ui/dist/style.css";

// **You will need to provide this file yourself**
ericclemmons marked this conversation as resolved.
Show resolved Hide resolved
import awsExports from "./aws-exports";

Amplify.configure(awsExports);

export default function Example() {
return <Authenticator />;
}
```

1. Visit your example (.e.g. <http://localhost:3000/docs/src/pages/component/authenticator/examples/sign-in>)
1. Make changes to [`@aws-amplify/ui-react`](packages/react) & save.

Next.js should automatically hot-reload your changes in the example.

### Documentation & Testing

1. Create or Update a `${feature}.feature` file (using [Gherkin](https://cucumber.io/docs/gherkin/reference/)) describing the behavior in [`packages/e2e/cypress/tests/acceptance/${slug}`](packages/e2e/cypress/tests/acceptance).

```gherkin
Feature: My new feature

Documentation-friendly description of this feature, why it exists, & how to use it.

Scenario: Example scenario using this feature
Given some "STARTING_POINT"
When I DO "SOMETHING"
And I DO SOMETHING "ELSE"
Then I see "THE DESIRED BEHAVIOR"
```

1. Create or Update the accompanying `${slug}.feature` tests (e.g. `packages/e2e/cypress/tests/acceptance/${slug}/${feature}/${feature}.ts`
1. Run `yarn workspace e2e dev` to load Cypress
1. Click on your updated `${feature}.feature` file to validate your changes

#### Vue Development

1. `yarn dev:vue`
1. Visit <http://localhost:3001/>

#### Angular Development

1. `yarn build:angular`, or `yarn build:angular:watch` for live development
1. `yarn dev:angular`.
1. Visit <http://localhost:4200/>

#### Flutter Development

1. see [packages/flutter/README.md](packages/flutter/README.md)
29 changes: 1 addition & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,5 @@
## Documentation

The latest documentation is found here:
> https://docs.amplify.aws/ui

## Contributing

### Getting Started

1. Fork & Clone this repo
1. [`nvm use`](https://github.com/nvm-sh/nvm)
1. `yarn install`

#### React Development

1. `yarn dev`
1. Visit <http://localhost:3000/>

#### Vue Development

1. `yarn dev:vue`
1. Visit <http://localhost:3001/>

#### Angular Development

1. `yarn build:angular`, or `yarn build:angular:watch` for live development
1. `yarn dev:angular`.
1. Visit <http://localhost:4200/>

#### Flutter Development

1. see [packages/flutter/README.md](packages/flutter/README.md)
> https://docs.amplify.aws/ui
2 changes: 1 addition & 1 deletion angular-docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"@angular/platform-browser": "~11.2.5",
"@angular/platform-browser-dynamic": "~11.2.5",
"@angular/router": "~11.2.5",
"aws-amplify": "^3.3.25",
"aws-amplify": "latest",
"ngx-markdown": "^11.1.2",
"rxjs": "~6.6.0",
"tslib": "^2.0.0",
Expand Down
4 changes: 4 additions & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@
"start": "next start"
},
"dependencies": {
"@aws-amplify/ui-react-v1": "npm:@aws-amplify/ui-react",
"@cucumber/gherkin": "^19.0.3",
"@cucumber/messages": "^16.0.1",
"@headlessui/react": "^1.2.0",
"@heroicons/react": "^1.0.1",
"@mdx-js/loader": "^1.5.1",
"@mdx-js/react": "^1.6.18",
"@moxy/next-compile-node-modules": "^2.0.2",
"@next/mdx": "^9.1.1",
"aws-amplify": "latest",
"aws-amplify-react": "latest",
"gray-matter": "^4.0.3",
"mdx-prism": "^0.3.3",
"next": "latest",
Expand Down
27 changes: 27 additions & 0 deletions docs/src/components/FeatureTests.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export function FeatureTests({ featureTests = [] }) {
ericclemmons marked this conversation as resolved.
Show resolved Hide resolved
if (!featureTests.length) {
return null;
}
ericclemmons marked this conversation as resolved.
Show resolved Hide resolved

return (
<>
<h2>Features</h2>

{featureTests.map(({ feature }) => (
<section key={feature.name}>
<h3>{feature.name}</h3>
<p>{feature.description}</p>

<h4>Examples</h4>
<ul>
{feature.children.map(({ scenario }) => (
<li key={scenario.name}>
<a href="#">{scenario.name}</a>
</li>
))}
</ul>
</section>
))}
</>
);
}
2 changes: 2 additions & 0 deletions docs/src/content/components/authenticator/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ function App() {
export default withAuthenticator(App)
```

<FeatureTests featureTests={featureTests} />

## Authenticator with Default Theme

Amplify UI provides simple, clean styles to get started with a great experience in two steps:
Expand Down
12 changes: 11 additions & 1 deletion docs/src/pages/[[...slugs]].tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { customComponents } from "@/components/customComponents";
import { Layout } from "@/components/Layout";
import { getContentPaths } from "@/utils/getContentPaths";
import { getFeatureTestsFromSlug } from "@/utils/getFeatureTestsFromSlug";
import { getPageFromSlug } from "@/utils/getPageFromSlug";
import { theme } from "@aws-amplify/ui-react";
import mdxPrism from "mdx-prism";
import { GetStaticPaths, GetStaticProps } from "next";
import { MDXRemote } from "next-mdx-remote";
import { serialize } from "next-mdx-remote/serialize";
import { FeatureTests } from "@/components/FeatureTests";
import * as components from "@aws-amplify/ui-react";
ericclemmons marked this conversation as resolved.
Show resolved Hide resolved

export default function Content({
featureTests = [],
frontmatter,
mdxSource,
componentPages,
Expand All @@ -23,7 +27,12 @@ export default function Content({
>
<MDXRemote
{...mdxSource}
components={{
...components,
ericclemmons marked this conversation as resolved.
Show resolved Hide resolved
FeatureTests,
}}
scope={{
featureTests,
theme,
customComponents,
}}
Expand Down Expand Up @@ -54,7 +63,7 @@ export const getStaticProps: GetStaticProps = async ({ params }) => {
});

const { content, frontmatter } = await getPageFromSlug(slug);

const featureTests = await getFeatureTestsFromSlug(slug);
eddiekeller marked this conversation as resolved.
Show resolved Hide resolved
const componentPagePaths = await getContentPaths("components/*/index.mdx");
const componentPages = await Promise.all(
componentPagePaths.map(getPageFromSlug).map(page => page.then(pluckMeta))
Expand Down Expand Up @@ -86,6 +95,7 @@ export const getStaticProps: GetStaticProps = async ({ params }) => {
props: {
frontmatter,
componentPages,
featureTests,
mdxSource,
primitivePages,
},
Expand Down
10 changes: 10 additions & 0 deletions docs/src/pages/components/authenticator/examples/sign-in.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Authenticator } from "aws-amplify-react";
import { Amplify } from "aws-amplify";
import "@aws-amplify/ui/dist/style.css";
import awsExports from "./aws-exports";

Amplify.configure(awsExports);

export default function Example() {
return <Authenticator />;
}
36 changes: 36 additions & 0 deletions docs/src/utils/getFeatureTestsFromSlug.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {
AstBuilder,
GherkinClassicTokenMatcher,
Parser,
} from "@cucumber/gherkin";
import { IdGenerator } from "@cucumber/messages";
import { readFile } from "fs/promises";
import glob from "glob";
import path from "path";

const parser = new Parser(
new AstBuilder(IdGenerator.uuid()),
new GherkinClassicTokenMatcher() // or GherkinInMarkdownTokenMatcher()
);

export async function getFeatureTestsFromSlug(slug: string) {
const cwd = path.join(
process.cwd(),
"../packages/e2e/cypress/tests/acceptance",
slug
);

const featurePaths = glob.sync("**.feature", { cwd });
const featureFiles = await Promise.all(
featurePaths.map(featurePath =>
readFile(path.resolve(cwd, featurePath), "utf-8")
)
);

const featureTests = featureFiles.map(featureFile =>
parser.parse(featureFile)
);

// Strip `undefined` properties because they're not JSON-serializable by Next.js
return JSON.parse(JSON.stringify(featureTests));
}
2 changes: 1 addition & 1 deletion packages/angular/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"@angular/platform-browser": "~11.2.4",
"@angular/platform-browser-dynamic": "~11.2.4",
"@angular/router": "~11.2.4",
"aws-amplify": "^3.3.25",
"aws-amplify": "latest",
"rxjs": "~6.6.0",
"tslib": "^2.0.0",
"zone.js": "~0.11.3"
Expand Down
4 changes: 4 additions & 0 deletions packages/e2e/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
INVALID_PASSWORD=
INVALID_USERNAME=
VALID_PASSWORD=
VALID_USERNAME=
3 changes: 3 additions & 0 deletions packages/e2e/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# testing
cypress/screenshots
cypress/videos
4 changes: 4 additions & 0 deletions packages/e2e/cypress.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"baseUrl": "http://localhost:3000/",
"testFiles": "**/*.feature"
}
5 changes: 5 additions & 0 deletions packages/e2e/cypress/fixtures/example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}
slaymance marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Feature: Sign In

Ampilfy's SignIn component uses AWS Cognito's authentication
service to provide a sign in experience to your application's
users.

Scenario: Sign in with invalid credentials
Given I'm at the sign in page
When I type an invalid username "INVALID_USERNAME"
And I type an invalid password "INVALID_PASSWORD"
And I click the "Sign In" button
Then I see "User does not exist"

Scenario: Sign in with valid credentials
Given I'm at the sign in page
When I type a valid username "VALID_USERNAME"
And I type a valid password "VALID_PASSWORD"
And I click the "Sign In" button
Then I see "Hello VALID_USERNAME"
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { And, Given, Then, When } from "cypress-cucumber-preprocessor/steps";

Given("I'm at the sign in page", () => {
cy.visit("/components/authenticator/examples/sign-in");
});

When("I type an invalid username {string}", (username: string) => {
cy.get("[data-test=username-input]").type(Cypress.env(username));
});

And("I type an invalid password {string}", (password: string) => {
cy.get("[data-test=sign-in-password-input]").type(Cypress.env(password));
});

And("I click the {string} button", (name: string) => {
cy.findByRole("button", { name }).click();
});

When("I type a valid username {string}", (username: string) => {
cy.get("[data-test=username-input]").type(Cypress.env(username));
});

And("I type a valid password {string}", (password: string) => {
cy.get("[data-test=sign-in-password-input]").type(Cypress.env(password));
});

Then("I see {string}", (message: string) => {
const [messageString, username] = message.split(" ");
cy.get("body").contains([messageString, Cypress.env(username)].join(" "));
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@React
Feature: withAuthenticator

`withAuthenticator` is an easy way to wrap your entire application with authentiation.

```js{1,9}
import { withAuthenticator } from "@aws-amplify/ui-react"

function App() {
return (
...
)
}

export default withAuthenticator(App)
```

Example: Show the "Sign In" screen by default
Given an application wrapped with withAuthenticator
When I am not authenticated
Then I see a "Sign In" button
Loading