This project incorporates ideas from https://github.com/gkubisa/elm-app-boilerplate and https://github.com/xolvio/automated-testing-best-practices to provide an elm app boilerplate intended for development in conformity with Konstantin Kudryashov’s Modelling by Example BDD/DDD methodology.
The broader project will incorporate a purely static site hosted on GitHub Pages (this repo) plus a backend (yet to be developed).
1. Start the development server
npm run dev
2. Start the mock GraphQL server
npm run api:mock
3. Start the end-to-end tests
npm run test:e2e:watch
4. Start the unit tests
npm run test:unit:watch
This uses Apollo’s graphql-server to provide a simple GraphQL backend which returns static data for queries/mutations.
The live version of the site sends requests to a GraphQL API, but until a backend is provided there will obviously be no save/load functionality.
- When the development server is started, a browser window should open at
localhost:3000
showing the app. - The app can also be accessed on the local network at the address displayed in the development server terminal window.
- The BrowserSync control panel can be found at the same address on port
3001
. (E.g. use your phone as a BrowserSync controller!)
- Add a feature file in
features
. - Cucumber will give you boilerplate code to put as your step definitions in
./test-e2e/step-definitions
. Double check the regular expressions, then implement the steps. End-to-end tests should fail. - Add an elm test suite for the feature in
./test-unit/[AppName]Test
. Write tests which will help you pass the currently failing aspect of the end-to-end tests. Tests should fail. - Write elm code in
./elm/[AppName]
to pass the tests.
Features are written in Gherkin and should be specific regarding the domain language, and unspecific regarding the technical implementation. That is, use concrete details about the example situations your feature should deal with and the feedback it should provide, but not about how the feature gets from input to output.
Ideally feature files should be written with so little implementation specificity that they can be reused for e.g. end-to-end and api tests, just with different step definitions.
Given
steps are for setup and should ideally manipulate state directly rather than using the API under development.When
steps are for calling the functions under test.Then
steps are for making assertions on the final state.
In addition, relevant variables can be stored in or accessed from the browser context.
In end-to-end tests, interactions with pages should be defined in page objects, rather than directly in the step definitions.
There should be one for each different page. Page objects extend a Base page class, which defines common methods such as visiting the page or typing text into an element.
When you’re ready to deploy what you have in ./dev
:
- Switch your environment: change
./src/Env/Current.elm
to import fromEnv.Production
instead ofEnv.Development
. - Recompile with production environment: rerun
npm run dev
if it isn’t already running. - Deploy by running this script:
npm run deploy:straight
This will copy your ./dev
directory into ./dist
, apply some compression, and push to your gh-pages
branch. You can also use npm run deploy:mangle
to make your scripts less readable, although there’s no point if you’re pushing the source code to a public repo as in this example.