DOES IT
WORK
ALL TOGETHER
https://upload.wikimedia.org/wikipedia/commons/0/07/HTS_Systems_UPS_Ground_shipments.jpg
https://twitter.com/gdinwiddie/status/690726656449839104
ACCEPTANCE
tests in SPA
WHAT
HOW
EXAMPLE
WHAT
HOW
EXAMPLE
Pieces work together (routing, components, services, server comunication)
Acceptance
Integration
Unit
Acceptance
Unit
Integration
Testing Triangle
SPA Testing
WHAT
HOW
EXAMPLE
Mirage
Mock
Test Helpers
ember-simple-auth
Page
Object
ES8
WHAT
HOW
EXAMPLE
Pieces work together (routing, components, services, server comunication)
// tests/acceptance/mail-logs-test.js
import { describe, it, beforeEach, afterEach } from 'mocha';
import { expect } from 'chai';
import { before, after } from 'cl-app/tests/helpers/module-for-acceptance-authenticated';
describe('Acceptance | mail logs', function() {
it('/mail-logs works', async function() {
beforeEach(before);
afterEach(after);
// LISTING
// ADD
// EDIT
});
});
// tests/helpers/module-for-acceptance-authenticated.js
import startApp from 'cl-app/tests/helpers/start-app';
import destroyApp from 'cl-app/tests/helpers/destroy-app';
import { authenticateSession } from 'cl-app/tests/helpers/ember-simple-auth';
const sessionData = {
idToken: 1
};
let application;
export function before() {
application = startApp();
authenticateSession(application, sessionData);
}
export function after() {
destroyApp(application);
}
// tests/acceptance/mail-logs-test.js
// ...
describe('Acceptance | mail logs', function() {
it('/mail-logs works', async function() {
// ...
// LISTING
expect(currentURL()).to.equal('/mail-logs');
expect(page.mailLogCount).to.equal(10);
// ADD
// EDIT
});
});
// tests/acceptance/mail-logs-test.js
// ...
import page from 'cl-app/tests/pages/mail-logs';
describe('Acceptance | mail logs', function() {
it('/mail-logs works', async function() {
// ...
server.createList('mailLog', 10);
await page.visit();
// LISTING
expect(currentURL()).to.equal('/mail-logs');
expect(page.mailLogCount).to.equal(10);
// ADD
// EDIT
});
});
// tests/pages/mail-logs.js
import {
clickable,
count,
create,
fillable,
text,
visitable
} from 'ember-cli-page-object';
const rows = 'tbody > tr';
export default create({
visit: visitable('/mail-logs'),
mailLogCount: count(rows),
});
// tests/acceptance/mail-logs-test.js
// ...
describe('Acceptance | mail logs', function() {
it('/mail-logs works', async function() {
// ...
// LISTING
// ...
server.create('category', { name: 'office' });
server.create('company', { name: 'selleo inc.' });
// ADD
await page
.formNew()
.fillExternalNumber('200-212-123')
.selectCompany('selleo')
.selectCategory('office')
.submit();
expect(page.mailLogCount).to.equal(11);
expect(page.onMailLog(10).text).to.include('200-212-123');
expect(server.db.mailLogs[10].externalNumber).to.equal('200-212-123');
// EDIT
});
});
import { clickable, count, create, fillable, text, visitable } from 'ember-cli-page-object';
const newForm = '.card-header';
const rows = 'tbody > tr';
const expandedRow = `${rows}.lt-expanded-row`;
export default create({
// ...
formNew() {
return this._form(newForm);
},
_form(scope) {
return create({
scope,
fillExternalNumber: fillable('input', { at: 1 }),
fillCompany: fillable('input', { at: 2 }),
fillCategory: fillable('input', { at: 4 }),
clickFirstSuggestion: clickable('.md-autocomplete-suggestions li', { resetScope: true }),
selectCompany(company) {
return this.fillCompany(company).clickFirstSuggestion();
},
selectCategory(category) {
return this.fillCategory(category).clickFirstSuggestion();
},
submit: clickable('button')
});
}
});
import { describe, it, beforeEach, afterEach } from 'mocha';
import { expect } from 'chai';
import { before, after } from 'cl-app/tests/helpers/module-for-acceptance-authenticated';
import page from 'cl-app/tests/pages/mail-logs';
describe('Acceptance | mail logs', function() {
this.timeout(7000);
beforeEach(before);
afterEach(after);
it('/mail-logs works', async function() {
server.create('category', { name: 'office' });
server.create('company', { name: 'selleo inc.' });
server.createList('mailLog', 10);
await page.visit();
// LISTING
expect(currentURL()).to.equal('/mail-logs');
expect(page.mailLogCount).to.equal(10);
// ADD
await page.formNew()
.fillExternalNumber('200-212-123')
.selectCompany('selleo')
.selectCategory('office')
.submit();
expect(page.mailLogCount).to.equal(11);
expect(page.onMailLog(10).text).to.include('200-212-123');
expect(server.db.mailLogs[10].externalNumber).to.equal('200-212-123');
// EDIT
await page.onMailLog(1).click()
.formEdit()
.fillExternalNumber('300-323-234')
.submit();
expect(page.onMailLog(1).text).to.include('300-323-234');
expect(server.db.mailLogs[1].externalNumber).to.equal('300-323-234');
});
});
https://twitter.com/gdinwiddie/status/690726656449839104
Mirage
Mock
Test Helpers
ember-simple-auth
Page
Object
ES8
# config/application.rb
require_relative 'boot'
# require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
# require "active_job/railtie"
require "active_record/railtie"
# require "action_controller/railtie"
# require "action_mailer/railtie"
# require "action_view/railtie"
# require "action_cable/engine"
# require "sprockets/railtie"
# require "rails/test_unit/railtie"
# app/controllers/application_controller.rb
class ApplicationController < JSONAPI::ResourceControllerMetal
include Knock::Authenticable
before_action :authenticate_user
# it's for knock only, and this is very naive implementation of head method
def head(type, options = {}) ... end
end
Acceptance Testing JavaScript Apps
By Michał Czyż
Acceptance Testing JavaScript Apps
HaXorZ
- 1,286