Aurelia-testing: Failed to execute 'replaceChild' on 'Node': parameter 1 is not of type 'Node' - aurelia

I am using for the first time the aurelia-testing package to test my HTML code.
I seem to have followed the docs to set up my test as follows:
describe('Contextual Menu HTML View test suite', function () {
let component: ComponentTester;
beforeEach(function () {
component = StageComponent
.withResources('../../src/components/modal/contextual-menu')
.inView('<contextual-menu is-active.two-way="activateMenu"></contextual-menu>')
.boundTo({ activateMenu: false });
});
it('should not add the is-active class to the root element', async function () {
await component.create(bootstrap);
const rootElement = await waitForDocumentElement('.qa-contextual-menu');
expect(rootElement.classList.contains('is-active')).toBe(false);
});
afterEach(function () {
component.dispose();
});
});
I tried using just bind instead of two-way but that fails too.
I tried both with a document.querySelector and with waitForDocumentElement, both cases fail, but anyways I assume the error comes from earlier.
I am getting an error and I am not sure why. Could you put on the tracks to identify the root cause of the following:
TypeError: Failed to execute 'replaceChild' on 'Node': parameter 1 is not of type 'Node'.
at Object.convert (/Users/lemoustachiste/work/lm-frontend/node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/living/generated/Node.js:573:11)
at HTMLDivElement.replaceChild (/Users/lemoustachiste/work/lm-frontend/node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/living/generated/Node.js:292:31)
at NodeJsDom.replaceNode (/Users/lemoustachiste/work/lm-frontend/node_modules/aurelia-pal-nodejs/dist/nodejs-dom.js:95:29)
at makeElementIntoAnchor (/Users/lemoustachiste/work/lm-frontend/node_modules/aurelia-templating/dist/commonjs/aurelia-templating.js:2432:19)
at applyInstructions (/Users/lemoustachiste/work/lm-frontend/node_modules/aurelia-templating/dist/commonjs/aurelia-templating.js:2479:17)
at ViewFactory.create (/Users/lemoustachiste/work/lm-frontend/node_modules/aurelia-templating/dist/commonjs/aurelia-templating.js:2707:7)
at TemplatingEngine.enhance (/Users/lemoustachiste/work/lm-frontend/node_modules/aurelia-templating/dist/commonjs/aurelia-templating.js:5290:24)
at /Users/lemoustachiste/work/lm-frontend/node_modules/aurelia-framework/dist/commonjs/aurelia-framework.js:176:28
at new Promise (<anonymous>)
at Aurelia.enhance (/Users/lemoustachiste/work/lm-frontend/node_modules/aurelia-framework/dist/commonjs/aurelia-framework.js:174:12)
Thanks a lot

I am not a jest user. So I simply used the scaffolded TS jest skeleton app from aurelia-cli (au new jest-skeleton --unattended --select typescript,jest,vscode). And found that to be working.
It seems the you are missing the following configuration in your jest.config.js.
testEnvironment: "node",
After only adding that, the tests started working.

Related

Multiple connections with same name are created in e2e test of NestJs with in memory database

I have NestJs application with TypeORM configured with mysql. I want to have e2e(integration) test and for that reason I want to have in memory database in the tests which I configured this way:
{
type: 'sqlite',
database: ':memory:',
synchronize: true,
dropSchema: true,
entities: [`dist/**/*.entity{.ts,.js}`],
}
And the setup of the tests
beforeEach(async () => {
const moduleFixture: TestingModule =
await Test.createTestingModule({imports: [AppModule, UserModule]})
.overrideProvider(TypeOrmConfigService).useClass(MockTypeOrmConfigService)
.compile();
app = await moduleFixture.createNestApplication();
await app.init();
});
. When running the test I got
AlreadyHasActiveConnectionError: Cannot create a new connection named "default", because connection with such name already exist and it now has an active connection session.
at new AlreadyHasActiveConnectionError (/Users/user/workspace/app/src/error/AlreadyHasActiveConnectionError.ts:8:9)
at ConnectionManager.Object.<anonymous>.ConnectionManager.create (/Users/user/workspace/app/src/connection/ConnectionManager.ts:57:23)
at Object.<anonymous> (/Users/user/workspace/app/src/index.ts:228:35)
at step (/Users/user/workspace/app/node_modules/tslib/tslib.js:136:27)
at Object.next (/Users/user/workspace/app/node_modules/tslib/tslib.js:117:57)
at /Users/user/workspace/app/node_modules/tslib/tslib.js:110:75
at new Promise (<anonymous>)
at Object.__awaiter (/Users/user/workspace/app/node_modules/tslib/tslib.js:106:16)
at Object.createConnection (/Users/user/workspace/app/node_modules/typeorm/index.js:186:20)
at rxjs_1.defer (/Users/user/workspace/app/node_modules/#nestjs/typeorm/dist/typeorm-core.module.js:151:29)
(node:19140) UnhandledPromiseRejectionWarning: AlreadyHasActiveConnectionError: Caught error after test environment was torn down
If I move the setup from beforeEach in beforeAll block it's ok, but I'm afraid that when I create several specs the error will come back. How should be handled properly?
EDIT:
The problem was that each test is making a setup of the application and so creates a new connection.The solution was to use "keepConnectionAlive: true," in order all tests to reuse same connection.
keepCOnnectionAlive: true is the way to go
Using keepConnectionAlive: true produced the following error for me.
Jest did not exit one second after the test run has completed.
This usually means that there are asynchronous operations that weren't
stopped in your tests. Consider running Jest with
--detectOpenHandles to troubleshoot this issue.
Adding the below to each e2e test fixed my issue:
afterEach(async () => {
await app.close();
});
Base on 0xCAP's answer, you can do something like this also.
// jest.setup.ts
jest.mock("/path/to/database/config/object", () => {
const { databaseConfig, ...rest } = jest.requireActual("/path/to/database/config/object")
return {
...rest,
databaseConfig: {
...databaseConfig,
keepConnectionAlive: true // replace old config
}
}
})
// jest.config.js
module.exports = {
...other options
setupFilesAfterEnv: ["jest.setup.ts"],
}

Why does an expectation in $nextTick never fail?

I need to use $nextTick in order to test some parts of my program. Somehow, it breaks my tests and make them success all the time - even when they should fail.
A minimal test sample would look like this:
import App from "./App";
import { shallowMount } from "#vue/test-utils";
it("should fail", () => {
const wrapper = shallowMount(App);
wrapper.vm.$nextTick(() => {
expect(1).toBe(3);
done();
});
});
You can find a sandbox example here
If you open the console, you should find the following error messages:
[Vue warn]: Error in nextTick: "Error: expect(received).toBe(expected)
Error: expect(received).toBe(expected)
Why does the test success? Why are the errors ignored? How do I use $nextTick properly if note like so?
In order to wait until Vue.js has finished updating the DOM after a
data change, you can use Vue.nextTick(callback) immediately after the
data is changed. The callback will be called after the DOM has been
updated.
I can not see any trigger that change DOM in your test. And you missed done argument in test callback
For example in the following this is wrapper.find('button').trigger('click')
it('fetches async when a button is clicked', (done) => {
const wrapper = shallowMount(Foo)
wrapper.find('button').trigger('click')
wrapper.vm.$nextTick(() => {
expect(wrapper.vm.value).toBe('value')
done()
})
})

How to create unit test cases with Vue, Karma, browserify

I am trying to build some unit test cases to my existing Vue project.
I found some documents there but not useful especially for testing on functions such as Watch, Promise and Then.
Is there any specific and detailed guide line on unit testing with Vue and these plugins?
The target vue has defined a function named test.
const vm = new Vue(target).$mount();
vm.test("message");
But the error message is vm.test is not a function
I do not know why I could not use the function defined in the target.vue.
Meanwhile once I use the test function to change some data, the target vue will update the data automatically.
But it seems that Vue.nextTick does not work on this situation.
Could someone help me on this point?
Thank you very much for your help.
Hellocomponent
export default {
name: 'hello',
data () {
return {
msg: 'Welcome to Your Vue.js App',
test: 'Testing'
}
}
}
Hello.spec.js //for testing Hello.vue
describe('Hello', () => {
it('set correct default data', () => {
expect(typeof Hello.data).to.equal('function')
assert.typeOf(Hello.data, 'function')
const defaultdata = Hello.data()
expect(defaultdata.test).to.be.a('string')
expect(defaultdata.test).to.equal('Testing')
})
})
This is test case of Hello component of vue.js which is created automatically when new template is created. This is using Karma+Mocha+Chai.

How can I spy or mock methods in Vue with sinon?

I'm trying to create a unit test for my app based in Vue and vue-cli with webpack template.
I read Vue documentation, vue-loader, vue-cli and vue-template/webpack (an more!). When I try to make a unit test for my component, I use this.
const Constructor = Vue.extend(MovieList)
vm = new Constructor({
propsData: {
criteria
},
methods: {
fetch: sandbox.spy()
}
}).$mount()
And test this:
expect(vm.fetch).to.be.called
But I get this error:
✗ should be called fetch
TypeError: { [Function: boundFn] _length: 0 } is not a spy or a call to a spy!
at assertCanWorkWith (/home/jmanuelrosa/Developer/personales/vue-course/movues/node_modules/sinon-chai/lib/sinon-chai.js:43:19)
at Assertion. (/home/jmanuelrosa/Developer/personales/vue-course/movues/node_modules/sinon-chai/lib/sinon-chai.js:70:13)
at Assertion.addProperty (/home/jmanuelrosa/Developer/personales/vue-course/movues/node_modules/chai/chai.js:4240:29)
at Context. (webpack:///test/unit/specs/MovieList.spec.js:74:39 <- index.js:14910:39)
Never worked with sinon but doc says:
sinon.spy(vm, "fetch");
expect(vm.fetch).toHaveBeenCalled();
http://sinonjs.org/releases/v2.1.0/spies/
Are you calling fetch upon component created? sometimes you need to manually trigger methods.

mocha 'after' fails saying it can't find 'app'

Ok, my mocha tests will pass if I comment out the 'before' and 'after' methods. I am sure that both of my errors are related to each other.
The 'after' method fails stating app.close isn't a function. The 'before' method fails saying it cant find 'app' on my line 7 (clearing server cache).
I am completely out of options or ideas. I would like to be able to start and stop my server at my command. This is the first time that I have attempted to include any type of 'before/after' methods to my mocha testing. working code below, but with my failing portion commented out. Any suggestions??
var request = require('supertest');
var app = require('../../server');
describe('server', function() {
before(function () {
//var app = require('../../server')();
//delete require.cache[require.resolve('app')];
});
after(function () {
//app.close();
});
describe('basic comms', function() {
it('responds to root route', function testSlash(done) {
request(app)
.get('/')
.expect('Content-type', /json/)
//.expect(res.message).to.equal('Hello World!')
.expect(200, done);
});
it('404 everything else', function testPath(done) {
//console.log('testing 404 response');
request(app)
.get('/foo/bar')
.expect(404, done);
});
});
});
In before you require your app in a different way than in line 2. Why would you not use already required app?
Example:
before(function () {
// here you can use app from line 2
});
Regarding app.close, where did you find this function?
Check Express docs:
http://expressjs.com/en/4x/api.html#app
To close express server, you can use this approach:
how to properly close node-express server?