Login Test with Ember Test - testing

I have write a ember test file for a login formular. The redirect Page is a Dashboard with a Time Ticker Sidebar. Now, when i tested this, i became a test time out after 60000ms. Can i exclude the Time Ticker Component in ember test?
My Test Code:
import {test} from 'qunit';
import moduleForAcceptance from 'frontend/tests/helpers/module-for-acceptance';
moduleForAcceptance('Acceptance | Login', {
integration: true
});
test('visiting /user_session/new', function (assert) {
visit('/user_session/new');
fillIn('input#login-email', 'test#example.de');
fillIn('input#login-password', 'blabla');
click('button.btn-primary');
let done = assert.async();
andThen(() => {
Ember.run.later(null, () => {
assert.equal(currentURL(), '/dashboard', 'redirects to the dashboard');
done();
}, 1000);
});
});
The Time Ticker Component:
import Ember from 'ember';
export default Ember.Component.extend({
tagName: 'time',
date: moment().format('DD.MM.YYYY'),
time: Ember.computed('value', function() {
return moment().format('HH:mm:ss');
}),
didInsertElement: function() {
this.tick();
},
tick: function() {
this.set('nextTick', Ember.run.later(this, function() {
this.notifyPropertyChange('value');
this.tick();
}, 1000));
},
willDestroyElement: function() {
Ember.run.cancel(this.get('nextTick'));
}
});

Wrap ticking mechanism in a service and use that service in your component.
During test, mock that service and inject the mock in your component. Although mocking in acceptence test is not a good thing for me, I can go with mocking approach in this scenario.
Also you can consider using ember-moment's live update in your pages. It provides the live update of time. Here there is.

Related

How to call mirage server before application starts in StencilJS

I am working on a StencilJS project where I have to use MirageJS to make fake API data.
How to call server before StencilJS application loads.
In react we can call makeServer() in the index.ts file, but in the stencil, we don't have such a file.
How can we call this to start the mirage server, Please can someone suggest the correct way.
Below is my server.ts file
mirage/server.ts
import { createServer, Model } from 'miragejs';
import { auditFactory } from './factories';
import { processCollectionRequest } from './utils';
export const makeServer = async ({ environment = 'development' } = {}) => {
console.log('started server');
return createServer({
environment,
factories: {
people: auditFactory,
},
models: {
people: Model,
},
routes() {
this.namespace = '/api/v1';
this.get('/peoples', function (schema, request) {
let res = processCollectionRequest(schema, request, 'peoples', this);
// remove factory properties not in spec
res.items.forEach(e => ['associatedResourceId', 'associatedResourceName', 'associatedResourceType'].forEach(p => delete e[p]));
return res;
});
},
seeds(server) {
server.createList('audit', 20);
},
});
};
I'm not familiar with MirageJS so I might be off, but can you use globalScript (https://stenciljs.com/docs/config) and then run your Mirage server there?

#golevelup/nestjs-rabbitmq CircleCI issue, timed out

I am creating a microservice in NestJS. Now I want to use RabbitMQ to send messages to another service.
I created the functionality and it works perfectly fine. But the problem comes up when I want to merge it and the CircleCI test is running. After 10 minutes I get the message:
Too long with no output (exceeded 10m0s): context deadline exceeded
This happens only on the service with the producer. The consuming service works fine.
Can someone explain why this happens and how I can fix this?
RabbitMQ is imported in the GraphQLModule below.
#Module({
imports: [
GraphQLFederationModule.forRoot({
autoSchemaFile: true,
context: ({ req }) => ({ req }),
}),
DatabaseModule,
AuthModule,
RabbitmqModule,
],
providers: [UserResolver, FamilyResolver, AuthResolver],
})
export class GraphQLModule {}
RabbitmqModule:
import { Global, Module } from '#nestjs/common';
import { ConfigService } from '#nestjs/config';
import { RabbitMQModule } from '#golevelup/nestjs-rabbitmq';
import { UserProducer } from './producers/user.producer';
#Global()
#Module({
imports: [
RabbitMQModule.forRootAsync(RabbitMQModule, {
useFactory: async (config: ConfigService) => ({
exchanges: [
{
name: config.get('rabbitMQ.exchange'),
type: config.get('rabbitMQ.exchangeType'),
},
],
uri: config.get('rabbitMQ.url'),
connectionInitOptions: { wait: false },
}),
inject: [ConfigService],
}),
],
providers: [UserProducer],
exports: [UserProducer],
})
export class RabbitmqModule {}
The CircleCI output:
UPDATE:
It crashes when it starts seeding the database. It seeds the database correctly but when it is done, it doesn't stop the app. This happens on my PC too, not only in CircleCi.
The following script is called:
import { NestFactory } from '#nestjs/core';
import { SeedService } from '../src/database/service/seed.service';
import { AppModule } from '../src/app/app.module';
async function bootstrap() {
const app = await NestFactory.createApplicationContext(AppModule);
try {
await app.get(SeedService).seed();
} catch (error) {
throw error;
} finally {
await app.close();
}
}
bootstrap();
But this doesn't close the app correctly. When I log before and after await app.close() it logs both.
It's hard to tell without knowing a little bit more about your scenario. What is it that the task in Circle CI is trying to accomplish? From the screenshot it looks like you may be attempting to use this script to apply database migrations?
If you boot up the entire microservice like this it's going to hold the process open waiting for potential messages to come through. Are you calling app.close() anywhere in your script? You will need to terminate the process appropriately once your script is completed or refactor this to not require booting up the whole service like this

Nuxt Ava End-to-End Testing Store Configuration

Given the example official Nuxt end-to-end test example using Ava:
import test from 'ava'
import { Nuxt, Builder } from 'nuxt'
import { resolve } from 'path'
// We keep a reference to Nuxt so we can close
// the server at the end of the test
let nuxt = null
// Init Nuxt.js and start listening on localhost:4000
test.before('Init Nuxt.js', async t => {
const rootDir = resolve(__dirname, '..')
let config = {}
try { config = require(resolve(rootDir, 'nuxt.config.js')) } catch (e) {}
config.rootDir = rootDir // project folder
config.dev = false // production build
config.mode = 'universal' // Isomorphic application
nuxt = new Nuxt(config)
await new Builder(nuxt).build()
nuxt.listen(4000, 'localhost')
})
// Example of testing only generated html
test('Route / exits and render HTML', async t => {
let context = {}
const { html } = await nuxt.renderRoute('/', context)
t.true(html.includes('<h1 class="red">Hello world!</h1>'))
})
// Close the Nuxt server
test.after('Closing server', t => {
nuxt.close()
})
How can you use Nuxt or Builder to configure/access the applications Vuex store? The example Vuex store would look like:
import Vuex from "vuex";
const createStore = () => {
return new Vuex.Store({
state: () => ({
todo: null
}),
mutations: {
receiveTodo(state, todo) {
state.todo = todo;
}
},
actions: {
async nuxtServerInit({ commit }, { app }) {
console.log(app);
const todo = await app.$axios.$get(
"https://jsonplaceholder.typicode.com/todos/1"
);
commit("receiveTodo", todo);
}
}
});
};
export default createStore;
Currently trying to run the provided Ava test, leads to an error attempting to access #nuxtjs/axios method $get:
TypeError {
message: 'Cannot read property \'$get\' of undefined',
}
I'd be able to mock $get and even $axios available on app in Vuex store method nuxtServerInit, I just need to understand how to access app in the test configuration.
Thank you for any help you can provide.
Just encountered this and after digging so many tutorial, I pieced together a solution.
You have essentially import your vuex store into Nuxt when using it programmatically. This is done by:
Importing Nuxt's config file
Adding to the config to turn off everything else but enable store
Load the Nuxt instance and continue your tests
Here's a working code (assuming your ava and dependencies are set up)
// For more info on why this works, check this aweomse guide by this post in getting this working
// https://medium.com/#brandonaaskov/how-to-test-nuxt-stores-with-jest-9a5d55d54b28
import test from 'ava'
import jsdom from 'jsdom'
import { Nuxt, Builder } from 'nuxt'
import nuxtConfig from '../nuxt.config' // your nuxt.config
// these boolean switches turn off the build for all but the store
const resetConfig = {
loading: false,
loadingIndicator: false,
fetch: {
client: false,
server: false
},
features: {
store: true,
layouts: false,
meta: false,
middleware: false,
transitions: false,
deprecations: false,
validate: false,
asyncData: false,
fetch: false,
clientOnline: false,
clientPrefetch: false,
clientUseUrl: false,
componentAliases: false,
componentClientOnly: false
},
build: {
indicator: false,
terser: false
}
}
// We keep a reference to Nuxt so we can close
// the server at the end of the test
let nuxt = null
// Init Nuxt.js and start listening on localhost:5000 BEFORE running your tests. We are combining our config file with our resetConfig using Object.assign into an empty object {}
test.before('Init Nuxt.js', async (t) => {
t.timeout(600000)
const config = Object.assign({}, nuxtConfig, resetConfig, {
srcDir: nuxtConfig.srcDir, // don't worry if its not in your nuxt.config file. it has a default
ignore: ['**/components/**/*', '**/layouts/**/*', '**/pages/**/*']
})
nuxt = new Nuxt(config)
await new Builder(nuxt).build()
nuxt.listen(5000, 'localhost')
})
// Then run our tests using the nuxt we defined initially
test.serial('Route / exists and renders correct HTML', async (t) => {
t.timeout(600000) // Sometimes nuxt's response is slow. We increase the timeont to give it time to render
const context = {}
const { html } = await nuxt.renderRoute('/', context)
t.true(html.includes('preload'))
// t.true(true)
})
test.serial('Route / exits and renders title', async (t) => {
t.timeout(600000)
const { html } = await nuxt.renderRoute('/', {})
const { JSDOM } = jsdom // this was the only way i could get JSDOM to work. normal import threw a functione error
const { document } = (new JSDOM(html)).window
t.true(document.title !== null && document.title !== undefined) // simple test to check if site has a title
})
Doing this should work. HOWEVER, You may still get some errors
✖ Timed out while running tests. If you get this you're mostly out of luck. I thought the problem was with Ava given that it didn't give a descriptive error (and removing any Nuxt method seemed to fix it), but so far even with the above snippet sometimes it works and sometimes it doesn't.
My best guess at this time is that there is a delay on Nuxt's side using either renderRouter or renderAndGetWindow that ava doesn't wait for, but on trying any of these methods ava almost immediately "times out" despite the t.timeout being explicitly set for each test. So far my research has lead me to checking the timeout for renderAndGetWindow (if it exists, but the docs doesn't indicate such).
That's all i've got.

Unit testing HTTP request with Vue, Axios, and Mocha

I'm really struggling trying to test a request in VueJS using Mocha/Chai-Sinon, with Axios as the request library and having tried a mixture of Moxios and axios-mock-adaptor. The below examples are with the latter.
What I'm trying to do is make a request when the component is created, which is simple enough.
But the tests either complain about the results variable being undefined or an async timout.
Am I doing it right by assigning the variable of the getData() function? Or should Ireturn` the values? Any help would be appreciated.
Component
// Third-party imports
import axios from 'axios'
// Component imports
import VideoCard from './components/VideoCard'
export default {
name: 'app',
components: {
VideoCard
},
data () {
return {
API: '/static/data.json',
results: null
}
},
created () {
this.getData()
},
methods: {
getData: function () {
// I've even tried return instead of assigning to a variable
this.results = axios.get(this.API)
.then(function (response) {
console.log('then()')
return response.data.data
})
.catch(function (error) {
console.log(error)
return error
})
}
}
}
Test
import Vue from 'vue'
import App from 'src/App'
import axios from 'axios'
import MockAdapter from 'axios-mock-adapter'
let mock = new MockAdapter(axios)
describe('try and load some data from somewhere', () => {
it('should update the results variable with results', (done) => {
console.log('test top')
mock.onGet('/static/data.json').reply(200, {
data: {
data: [
{ id: 1, name: 'Mexican keyboard cat' },
{ id: 2, name: 'Will it blend?' }
]
}
})
const VM = new Vue(App).$mount
setTimeout(() => {
expect(VM.results).to.be.null
done()
}, 1000)
})
})
I am not sure about moxios mock adaptor, but I had a similar struggle. I ended up using axios, and moxios, with the vue-webpack template. My goal was to fake retreiving some blog posts, and assert they were assigned to a this.posts variable.
Your getData() method should return the axios promise like you said you tried - that way, we have some way to tell the test method the promise finished. Otherwise it will just keep going.
Then inside the success callback of getData(), you can assign your data. So it will look like
return axios.get('url').then((response) {
this.results = response
})
Now in your test something like
it('returns the api call', (done) => {
const vm = Vue.extend(VideoCard)
const videoCard = new vm()
videoCard.getData().then(() => {
// expect, assert, whatever
}).then(done, done)
)}
note the use of done(). That is just a guide, you will have to modify it depending on what you are doing exactly. Let me know if you need some more details. I recommend using moxios to mock axios calls.
Here is a good article about testing api calls that helped me.
https://wietse.loves.engineering/testing-promises-with-mocha-90df8b7d2e35#.yzcfju3qv
So massive kudos to xenetics post above, who helped in pointing me in the right direction.
In short, I was trying to access the data incorrectly, when I should have been using the $data property
I also dropped axios-mock-adaptor and went back to using moxios.
I did indeed have to return the promise in my component, like so;
getData: function () {
let self = this
return axios.get(this.API)
.then(function (response) {
self.results = response.data.data
})
.catch(function (error) {
self.results = error
})
}
(Using let self = this got around the axios scope "problem")
Then to test this, all I had to do was stub the request (after doing the moxios.install() and moxios.uninstall for the beforeEach() and afterEach() respectively.
it('should make the request and update the results variable', (done) => {
moxios.stubRequest('./static/data.json', {
status: 200,
responseText: {
data: [
{ id: 1, name: 'Mexican keyboard cat' },
{ id: 2, name: 'Will it blend?' }
]
}
})
const VM = new Vue(App)
expect(VM.$data.results).to.be.null
VM.getData().then(() => {
expect(VM.$data.results).to.be.an('array')
expect(VM.$data.results).to.have.length(2)
}).then(done, done)
})

How to test Ember.Router

I would like to test my router which for the sake of simplicity looks as follows:
// app.router.js
import Ember from 'ember';
import config from './config/environment';
const Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('sessions', function() {
this.route('login');
this.route('logout');
});
this.route('profile');
});
export default Router;
Is it possible to unit-test it?
I tried using acceptance tests but I was not successful:
import Ember from 'ember';
import { test } from 'qunit';
import moduleForAcceptance from 'transformed-admin/tests/helpers/module-for-acceptance';
import startApp from 'transformed-admin/tests/helpers/start-app';
moduleForAcceptance('Acceptance | configuration', {
beforeEach: function() {
this.application = startApp();
},
afterEach: function() {
Ember.run(this.application, 'destroy');
}
});
test('should map routes correctly', function(assert) {
visit('/');
const app = this.application;
andThen(function() {
app.Router.detect("profile"); // false
app.Router.detect("Profile"); // false
const a = app.Router.extend({});
a.detect("profile"); // false
a.detect("Profile"); // false
});
});
What are the best practices here? Do you test Router.map() at all? Or do you rely on testing of concrete routes as a guarantee that the Router.map() is written correctly?
Not quite sure what you want to do. You could write acceptance tests for each route if you want to make sure that they are visible:
import { test } from 'qunit';
import moduleForAcceptance from 'people/tests/helpers/module-for-acceptance';
moduleForAcceptance('Acceptance | login');
test('visiting /', function(assert) {
visit('/');
andThen(function() {
assert.equal(currentURL(), '/index');
assert.equal(currentPath(), 'index');
});
});
test('visiting /profile', function(assert) {
visit('/profile');
andThen(function() {
assert.equal(currentURL(), '/profile');
assert.equal(currentPath(), 'profile');
});
});
You could also write unit tests for your routes.
You should not test Ember.js internals. Ember.Router is covered by tests. You should test your application specific logic (eg. handling a specific action in a route by unit test) and behavior (eq. a specific route exists by acceptance test).