Testing a sample React application with Siesta
===============

In this guide, we'll describe how to test a Vue application with Siesta. As a sample application, we'll use 
[Vuestic Admin Dashboard](https://github.com/epicmaxco/vuestic-admin). It is built with [vue-cli3](https://cli.vuejs.org/)
- a modern web application framework.  

This application has no tests as-is. We'll add a few sample tests for the individual components and an end-to-end test for the application as whole.
We've seen tests for other Vue apps uses virtual DOM and runs in Node.js, however, following the Siesta philosophy, 
our tests will run in real browsers - the same environment end user operates in.    

In the following "Live example" sections there are instructions how to complete the setup of the example and examine it "live" in the browser.

The 'Setup details' section, contains the detailed description of all changes, made to the "stock" Vuestic Admin Dashboard app.


Live example
------------

The sample Vue application is bundled in the Siesta examples in the directory `examples-browser/vue-vuestic-admin-dashboard`. It is also available
as a git repository, forked from the original app: [git://git.assembla.com/bryntum.siesta-vuestic-admin-example.git]()

To complete the setup, switch to the example folder in console, and run:

    > npm install
    
Then to launch the server-side part of the example:

    > npm run serve

This command will perform a development build and the app will be available at `http://localhost:8081`:

{@img images/vuestic-admin-app.jpg}

If you open the `http://localhost:8081/tests/siesta.html` you'll see Siesta's web interface, from which you can launch individual tests.

{@img images/siesta-web-interface.jpg}

There are 2 groups of tests - "Individual components" and "Black box". This is a <a href="#!/guide/testing_strategy">recommended strategy</a> 
for testing your web application, which has the best ROI for time in our experience.  


Setup details
--------------

Ok, we start with the "stock" [Vuestic Admin Dashboard](https://github.com/epicmaxco/vuestic-admin) app, freshly cloned to some 
directory on your machine, which is assumed to be a current directory for the all console commands we'll use.

###Preparations

Install the `@vue/cli` globally, per the app's installation instructions:

    > npm install -g @vue/cli

Then, we add dependency on [siesta-lite](https://www.npmjs.com/package/siesta-lite) and some other packages to `package.json`:

```json
    "devDependencies": {
        ...
        
        "siesta-lite": "^5.2.0",
        
        "webpack-watched-glob-entries-plugin": "^2.1.2",
        "lodash": "^4.17.11",
        "vue-cli-plugin-multi-compiler": "^0.1.0",
    }
``` 

Then, we install all dependencies:

    > npm install 


### Siesta project creation

Now, lets follow in general the <a href="#!/guide/getting_started_browser">Getting started with Siesta in browser environment</a> guide and create the
Siesta project file as the `/tests/siesta.js`:

```javascript
const project = new Siesta.Project.Browser()

project.configure({
  title: 'Vuestic Admin Dashboard test suite',
})

project.plan(
  {
    // Tests in this group, exercises individual components
    group: 'Individual components tests',

    // our entry page for Siesta tests
    pageUrl: '../entry.html',

    items: [
      'components/color_picker.t.js',
    ],
  },
  {
    // This is end-to-end tests group, access application as a "black box"
    // they open the `index.html` page using the `pageUrl` config
    // and then executes as a script on that page
    group: 'Black box tests',

    pageUrl: '../index.html',

    items: [
      'blackbox-app/sanity.t.js',
    ],
  },
)

project.start()
```

We'll see shortly, what is the `entry.html` page, which is used for testing individual components. The `index.html` page, the 2nd group is refering
to, is the main page of the application.

We'll also need a HTML wrapper for the Siesta web interface, lets save it as `/tests/siesta.html`

```html
<!DOCTYPE html>
<html>
    <head>
        <!-- Recommended set of pragmas, required for IE11 compatibility-->
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

        <!-- Siesta web interface -->
        <link rel="stylesheet" type="text/css" href="../static/siesta-lite/resources/css/siesta-all.css">
        <script type="text/javascript" src="../static/siesta-lite/siesta-all.js"></script>

        <script type="text/javascript" src="siesta.js"></script>

    </head>

    <body>
    </body>
</html>
```

We'll see shortly, how the "static/siesta-lite" folder will be made available to the Siesta web interface page.


### Plugging into Vue and Webpack configuration

Now lets tweak the app configuration in the `/vue.config.js`. First of all, we'll add the `baseUrl` option, to allow access from arbitrary folder
and not only from the root:

```js
module.exports = {
  ...
  baseUrl: './',
  ...
}
```
 
Then we add an instance of `copy-webpack-plugin`, to copy the static files of the Siesta web interface to the `/static` folder:

```js
const CopyWebpackPlugin = require('copy-webpack-plugin')
...

module.exports = {
  ...
  configureWebpack: {
    plugins: [
      // copy Siesta files and web interface resources
      new CopyWebpackPlugin([
        {
          from: path.resolve(__dirname, 'node_modules/siesta-lite/resources'),
          to: 'static/siesta-lite/resources',
        },
        {
          from: path.resolve(__dirname, 'node_modules/siesta-lite/siesta-all.js'),
          to: 'static/siesta-lite/siesta-all.js',
        },
        {
          from: path.resolve(__dirname, 'tests/siesta.html'),
          to: 'tests/siesta.html',
        },
        {
          from: path.resolve(__dirname, 'tests/siesta.js'),
          to: 'tests/siesta.js',
        },
      ])
    ]
  }
  ...
}
```

We now have the entry files to the Siesta web interface. The end-to-end tests will already work, as they just open the main page of the app (`index.html`)
and operates on it. 

However, to be able to test the individual source files from the application, we need to setup the transpilation of the test's source files. 

For that, to not interfere with the application setup, we will need an additional Webpack pipeline configuration. Vue cli does not support
[this feature](https://github.com/vuejs/vue-cli/issues/2613) out of the box, but only through the 
[vue-cli-plugin-multi-compiler](https://github.com/jkzing/vue-cli-plugin-multi-compiler) plugin (which we've already added to the project): 

```js
module.exports = {
  ...
  pluginOptions: {
    configureMultiCompilerWebpack: webpackConfig => {
      // `webpackConfig` here is the one resolved by vue cli.
      // (**after** executing `configureWebpack` and `chainWebpack`)
      const cloneDeep = require('lodash.clonedeep')
      const transpileTestsConfig = cloneDeep(webpackConfig)

      transpileTestsConfig.entry = WebpackWatchedGlobEntries.getEntries(
        [
          path.resolve(__dirname, 'tests/**/*.t.js'),
        ]
      )

      transpileTestsConfig.output.filename = 'tests/[name].js'

      transpileTestsConfig.plugins.push(new WebpackWatchedGlobEntries())

      // return an array to invoke webpack multi-compiler mode
      return [webpackConfig, transpileTestsConfig]
    }
  }
  ...
}
```

The plugin configuration function (`configureMultiCompilerWebpack` above), receives the "final" version of the Webpack configuration
object, which is used by Vue cli to build our app. We then create a deep clone of it using `lodash.clonedeep` and add 
[WebpackWatchedGlobEntries](https://www.npmjs.com/package/webpack-watched-glob-entries-plugin) plugin. It creates a separate
entry for every Siesta test file, given a glob pattern: `tests/**/*.t.js`. 

We also setup an output name, so that the transpiled files of our test suite matches the original filesystem structure.

The experiment also showed, that, since this application uses chunked loading, every test also needs to start with the page, that includes
"vendor" and "common" chunks. We add additional entry to the `pages` config:

```js
module.exports = {
  ...  
  pages: {
    index: { ... },
    siesta: {
      entry: 'tests/entry.js',
      template: 'tests/entry.html',
      filename: 'entry.html',
      inject: false,
      chunks: ['chunk-vendors', 'chunk-common'],
    }
  }
  ...
}
```
Where the `/tests/entry.html` is simply an empty HTML page:

```html
<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
  </body>
</html>
```  

and `/tests/entry.js` is an empty JavaScript file.  
  

### Open Siesta web interface

Now, you can launch the Webpack development server of this app with:

    > npm run serve
    
And the Siesta web interface will be available at [http://localhost:8081/tests/siesta.html]()


Conclusion
----------

As you can see, Siesta can be plugged into the Vue application in a very straightforward way. You should be able
to follow the same approach in your application.  

If you will encounter any issues or problems with your Vue testing, please let us know in the forums below, and we'll try to help you.

Happy testing!


Buy this product
---------

Visit our store: <https://bryntum.com/store/siesta>


Support
---------

Ask question in our community forum: <https://www.bryntum.com/forum/viewforum.php?f=20>

Subscribers can post expedited questions in Premium Forum: <https://www.bryntum.com/forum/viewforum.php?f=21>

Please report any bugs through the web interface at <https://www.assembla.com/spaces/bryntum/support/tickets>


See also
---------

Siesta web-page: <https://bryntum.com/products/siesta>

Other Bryntum products: <https://bryntum.com/products>



Attribution
---------

This software contains icons from the following icon packs (licensed under Creative Common 2.5/3.0 Attribution licenses)

- <http://www.famfamfam.com/lab/icons/silk/>
- <http://led24.de/iconset/>
- <http://p.yusukekamiyamane.com/>
- <http://rrze-icon-set.berlios.de/index.html>
- <http://www.smashingmagazine.com/2009/05/20/flavour-extended-the-ultimate-icon-set-for-web-designers/>
- <http://www.doublejdesign.co.uk/products-page/icons/super-mono-icons/>
- <http://pixel-mixer.com/>

Thanks a lot to the authors of the respective icons packs.


COPYRIGHT AND LICENSE
---------

Copyright (c) 2009-2018, Bryntum & Nickolay Platonov

All rights reserved.
