Cleaning up and reorganizing

As you can see, the auto-generated Vue application contains code examples, which we don't need. Let's clean them up before committing to the repository.

Let's start from App.vue by removing the <img> tag and the #app CSS inside <style>, making the file look like this:

<template>
<div id="app">
<router-view/>
</div>
</template>

<script>
export default {
name: 'App'
}
</script>

<style>
</style>

In the future, we will add global styles inside the <style> tag of App.vue.

Now, let's delete components/HelloWorld.vue, views/About.vue, and views/Home.vue. Once these files are deleted, and if you have the frontend running, the webpack will complain about this deletion. And, you can see an error message: Failed to compile with 2 errors, in the console. It is because Home.vue and About.vue are referenced in router.js. And webpack monitors the src directory. Any change to the .js files, .vue files, or assets inside of this directory will trigger a compilation of the application. Let's fix this by removing the reference and change router.js to the following:

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: []
})

Now, the compilation finished and webpack automatically updated the page, which is blank now. That's a good base for us to implement TaskAgile. We will talk about more about router.js later.

Now, remember the lesson that we learned when we created the backend scaffold—no commit before all of the tests pass locally.

Let's run the test on the frontend with the command, npm test. Undoubtedly, it failed. Both the unit test in HelloWorld.spec.js and the e2e test in test.js are expecting contents of HelloWorld.vue, which we have deleted. To fix this, one option is to delete these test files, which will work. The other option is to create a Vue component and change the tests accordingly.

Let's take the second option. And, since we're practicing TDD in the book, we won't write the Vue component first. We will create test files and then write the actual component. Before we start practicing TDD, let's describe a little bit about the Vue component that we will create.

As we know, our TaskAgile application is an SPA. So, when we say a page in TaskAgile, we mean a logical page, for example, the login page, the register page, and so on. And we will create a Vue component for each page and put them into the front-end/src/views folder. These components will be named in such a way as LoginPage.vue and RegisterPage.vue. Inside the original front-end/src/components folder, we will put components that will be shared between pages, for instances, buttons, and modal windows.

For now, we will write a simple front-end/src/views/LoginPage.vue as a placeholder. In this Vue component, we will simply put a heading inside a <div> wrapper, which looks like this: <div><h1>TaskAgile</h1></div>. Now, we know how the page will look. Let's change the tests.

We will need to rename the unit test file, HelloWord.spec.js, to LoginPage.spec.js and change it to be like the following:

1. import Vue from 'vue'
2. import LoginPage from '@/views/LoginPage'
3.
4. describe('LoginPage.vue', () => {
5. it('should render correct contents', () => {
6. const Constructor = Vue.extend(LoginPage)
7. const vm = new Constructor().$mount()
8. expect(vm.$el.querySelector('h1').textContent)
9. .toEqual('TaskAgile')
10. })
11.})

As you can see, line 1 is an import of Vue itself. And line 2 is importing the LoginPage.vue that we are testing against. Line 4 is using Jest's describe(name, fn) API to create a test suite that groups related tests together. In our case, we only have one test right now, that is, the one listed from line 5 to line 10. The it(name, fn, timeout) function is an alias of Jest's API, test(name, fn, timeout). The first argument is the test name. The second argument is a function that contains the expectations to test. The third argument is a timeout in milliseconds, which is optional. And, when not provided, the default timeout is five seconds. In line 6, we create a LoginPage subclass of the Vue. And in line 7, we create a Vue instance of LoginPage and then mount it programmatically. Once the $mount() method is invoked, you can think of this Vue instance as though it has been rendered on the page. In line 8, we use Jest's API, expect().toEqual(), to assert that the text content of <h1> tag on the page is of the 'TaskAgile' value. vm.$el is the root DOM element that the Vue instance, vm, manages. In our case, it is the <div> wrapper, which is an instance of JavaScript built-in class, Element. The .querySelector('h1') method is used to find the <h1> element.

Now, let's work on the end-to-end test by starting with renaming the test file from test.js to login.e2e.js, and changing the tests to be like the following:

1. module.exports = {
2. 'login test': function (browser) {
3. browser
4. .url(process.env.VUE_DEV_SERVER_URL + 'login')
5. .waitForElementVisible('#app', 5000)
6. .assert.containsText('h1', 'TaskAgile')
7. .end()
8. }
9. }

As you can see in line 1, it is a definition of Node.js module. And we write the Nightwatch tests inside that module. A Nightwatch test can contain multiple steps and, in our case, we have only one step, which is named 'login test'. Each step is actually a method of the module, which accepts a parameter, browser, which is provided by Nightwatch for controlling the browser. In line 4, we call the .url() method to open the login page that is served from the development server, which is started by @vue/cli-service. In line 5, the waitForElementVisible() method is to assert that the #app element will be visible in five seconds. In line 6, we use Nightwatch's assert API to check the <h1> element contains the text 'TaskAgile', which is the same assertion we used in LoginPage.spec.js. The .end() method in line 7 is used to close the test and for the Selenium session to be properly closed.

This Nightwatch test is quite straightforward, but also brittle. For example, if we change the HTML from <h1> to <h2> or something else. The test will break, even though we still have the 'TaskAgile' text on the page. A better way to write E2E tests is to use Page Objects, which is a popular pattern of writing end-to-end tests. And, it is the approach we will use in this book. For now, let's we will leave our first E2E test as it is now.

Now, if you run the npm test command, without any doubt, it fails. It's time to write the actual code. Let's create the front-end/src/views/LoginPage.vue file, which looks like the following:

1. <template>
2. <div>
3. <h1>TaskAgile</h1>
4. </div>
5. </template>
6.
7. <script>
8. export default {
9. name: 'LoginPage'
10.}
11.</script>

As you can see, it is quite simple and has only a <h1> tag. But it is good enough to pass our unit test. Now, if we run npm test again, we can see the unit test has passed, but not the E2E test because we haven't provided a route for LoginPage.vue yet.

Let's make changes to front-end/src/router.js as the following, so that the LoginPage.vue can be rendered:

...
import LoginPage from '@/views/LoginPage'
...
export default new Router({
...
routes: [{
path: '/login',
name: 'LoginPage',
component: LoginPage
}]
})

As you can see, we put the login page at the path '/login' root. We will talk in detail about how the router works later in this chapter. For now, let's run npm test to see how things work. When you see output similar to the following, it means both the unit test and E2E tests have passed:

...
Test Suites: 1 passed, 1 total
...
Running: login test
...
OK. 2 assertions passed. (4.746s)

Now, let's commit the changes and push it to origin, as shown in Figure 8.7:

Figure 8.7: Creating the frontend scaffold commit
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.37.10