Fixed editor not loading in Admin acceptance tests
closes https://linear.app/tryghost/issue/PLG-176 The editor files were previously stubbed for testing because we didn't have a way to load the externally-hosted files. This made testing slow and difficult because the only way to test the Admin integration was via Ghost's e2e browser tests. - unstubbed the editor globals so `fetchKoenigLexical()` actually tries to import the external assets - updated `ember-cli-build` to copy the Koenig UMD file over to the assets directory in development/test builds - updated `environment.js` to set the required filename for the default asset import to successfully hit the test environment hosted files - updated lexical editor acceptance tests to demonstrate the editor loads successfully for new and existing posts
This commit is contained in:
parent
2627dd6aa0
commit
fc501add94
@ -66,10 +66,17 @@ module.exports = function (environment) {
|
|||||||
ENV.APP.rootElement = '#ember-testing';
|
ENV.APP.rootElement = '#ember-testing';
|
||||||
ENV.APP.autoboot = false;
|
ENV.APP.autoboot = false;
|
||||||
|
|
||||||
// Withuot manually setting this, pretender won't track requests
|
// Without manually setting this, pretender won't track requests
|
||||||
ENV['ember-cli-mirage'] = {
|
ENV['ember-cli-mirage'] = {
|
||||||
trackRequests: true
|
trackRequests: true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// We copy the dynamically loaded editor file into the ghost assets
|
||||||
|
// directory in the dev/test env so that tests can load it. We need to
|
||||||
|
// set the config appropriately here so that the fetchKoenigLexical
|
||||||
|
// utility creates the right URL
|
||||||
|
ENV.editorFilename = 'koenig-lexical.umd.js';
|
||||||
|
ENV.editorHash = 'test';
|
||||||
}
|
}
|
||||||
|
|
||||||
return ENV;
|
return ENV;
|
||||||
|
@ -254,5 +254,11 @@ module.exports = function (defaults) {
|
|||||||
app.import('vendor/codemirror/lib/codemirror.js', {type: 'test'});
|
app.import('vendor/codemirror/lib/codemirror.js', {type: 'test'});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (app.env === 'development' || app.env === 'test') {
|
||||||
|
// pull dynamic imports into the assets folder so that they can be lazy-loaded in tests
|
||||||
|
// also done in development env so http://localhost:4200/tests works
|
||||||
|
app.import('node_modules/@tryghost/koenig-lexical/dist/koenig-lexical.umd.js', {outputFile: 'ghost/assets/koenig-lexical/koenig-lexical.umd.js'});
|
||||||
|
}
|
||||||
|
|
||||||
return app.toTree();
|
return app.toTree();
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import loginAsRole from '../../helpers/login-as-role';
|
import loginAsRole from '../../helpers/login-as-role';
|
||||||
import {blur, click, currentURL, fillIn, find, waitUntil} from '@ember/test-helpers';
|
import {blur, click, currentURL, fillIn, find, waitFor, waitUntil} from '@ember/test-helpers';
|
||||||
import {enableLabsFlag} from '../../helpers/labs-flag';
|
import {enableLabsFlag} from '../../helpers/labs-flag';
|
||||||
import {expect} from 'chai';
|
import {expect} from 'chai';
|
||||||
import {invalidateSession} from 'ember-simple-auth/test-support';
|
import {invalidateSession} from 'ember-simple-auth/test-support';
|
||||||
@ -18,15 +18,21 @@ describe('Acceptance: Lexical editor', function () {
|
|||||||
|
|
||||||
it('redirects to signin when not authenticated', async function () {
|
it('redirects to signin when not authenticated', async function () {
|
||||||
await invalidateSession();
|
await invalidateSession();
|
||||||
|
|
||||||
await visit('/editor/post/');
|
await visit('/editor/post/');
|
||||||
expect(currentURL(), 'currentURL').to.equal('/signin');
|
expect(currentURL(), 'currentURL').to.equal('/signin');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('new post', function () {
|
describe('with new post', function () {
|
||||||
// TODO: test it actually loads the editor
|
|
||||||
it('loads editor', async function () {
|
it('loads editor', async function () {
|
||||||
await visit('/editor/post/');
|
await visit('/editor/post/');
|
||||||
expect(currentURL(), 'currentURL').to.equal('/editor/post/');
|
expect(currentURL(), 'currentURL').to.equal('/editor/post/');
|
||||||
|
|
||||||
|
await waitFor('[data-secondary-instance="false"] [data-lexical-editor]');
|
||||||
|
// find the placeholder div
|
||||||
|
const xpath = '//div[text()="Begin writing your post..."]';
|
||||||
|
const match = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
|
||||||
|
expect(match.singleNodeValue).to.exist;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can leave editor without unsaved changes modal', async function () {
|
it('can leave editor without unsaved changes modal', async function () {
|
||||||
@ -72,7 +78,16 @@ describe('Acceptance: Lexical editor', function () {
|
|||||||
it('saves on content change');
|
it('saves on content change');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('existing post', function () {
|
describe('with existing post', function () {
|
||||||
|
it('loads editor', async function () {
|
||||||
|
const post = this.server.create('post', {lexical: '{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"This is a test","type":"extended-text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}'});
|
||||||
|
await visit(`/editor/post/${post.id}`);
|
||||||
|
expect(currentURL(), 'currentURL').to.equal(`/editor/post/${post.id}`);
|
||||||
|
await waitFor('[data-secondary-instance="false"] [data-lexical-editor]');
|
||||||
|
// find the post content
|
||||||
|
expect(find('[data-secondary-instance="false"] [data-lexical-editor]')).to.contain.text('This is a test');
|
||||||
|
});
|
||||||
|
|
||||||
it('does not save post on title blur', async function () {
|
it('does not save post on title blur', async function () {
|
||||||
const post = this.server.create('post', {status: 'published'});
|
const post = this.server.create('post', {status: 'published'});
|
||||||
const originalTitle = post.title;
|
const originalTitle = post.title;
|
||||||
|
@ -33,7 +33,8 @@ describe('Acceptance: Post revisions', function () {
|
|||||||
postStatus: 'draft',
|
postStatus: 'draft',
|
||||||
author: post.authors.models[0],
|
author: post.authors.models[0],
|
||||||
createdAt: moment(post.updatedAt).subtract(1, 'hour'),
|
createdAt: moment(post.updatedAt).subtract(1, 'hour'),
|
||||||
reason: 'explicit_save'
|
reason: 'explicit_save',
|
||||||
|
lexical: '{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"New body","type":"extended-text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}'
|
||||||
});
|
});
|
||||||
this.server.create('post-revision', {
|
this.server.create('post-revision', {
|
||||||
post,
|
post,
|
||||||
@ -45,11 +46,10 @@ describe('Acceptance: Post revisions', function () {
|
|||||||
postStatus: 'draft',
|
postStatus: 'draft',
|
||||||
author: post.authors.models[0],
|
author: post.authors.models[0],
|
||||||
createdAt: moment(post.updatedAt).subtract(1, 'day'),
|
createdAt: moment(post.updatedAt).subtract(1, 'day'),
|
||||||
reason: 'initial_revision'
|
reason: 'initial_revision',
|
||||||
|
lexical: '{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Old body","type":"extended-text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}'
|
||||||
});
|
});
|
||||||
|
|
||||||
// this.timeout(0);
|
|
||||||
|
|
||||||
await visit(`/editor/post/${post.id}`);
|
await visit(`/editor/post/${post.id}`);
|
||||||
|
|
||||||
// open post history menu
|
// open post history menu
|
||||||
@ -109,7 +109,8 @@ describe('Acceptance: Post revisions', function () {
|
|||||||
postStatus: 'draft',
|
postStatus: 'draft',
|
||||||
author: post.authors.models[0],
|
author: post.authors.models[0],
|
||||||
createdAt: moment(post.updatedAt).subtract(1, 'hour'),
|
createdAt: moment(post.updatedAt).subtract(1, 'hour'),
|
||||||
reason: 'explicit_save'
|
reason: 'explicit_save',
|
||||||
|
lexical: '{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"New body","type":"extended-text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}'
|
||||||
});
|
});
|
||||||
this.server.create('post-revision', {
|
this.server.create('post-revision', {
|
||||||
post,
|
post,
|
||||||
@ -118,7 +119,8 @@ describe('Acceptance: Post revisions', function () {
|
|||||||
postStatus: 'draft',
|
postStatus: 'draft',
|
||||||
author: post.authors.models[0],
|
author: post.authors.models[0],
|
||||||
createdAt: moment(post.updatedAt).subtract(1, 'day'),
|
createdAt: moment(post.updatedAt).subtract(1, 'day'),
|
||||||
reason: 'initial_revision'
|
reason: 'initial_revision',
|
||||||
|
lexical: '{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Old body","type":"extended-text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}'
|
||||||
});
|
});
|
||||||
|
|
||||||
await visit(`/editor/post/${post.id}`);
|
await visit(`/editor/post/${post.id}`);
|
||||||
|
@ -8,12 +8,6 @@ import chai from 'chai';
|
|||||||
import chaiDom from 'chai-dom';
|
import chaiDom from 'chai-dom';
|
||||||
chai.use(chaiDom);
|
chai.use(chaiDom);
|
||||||
|
|
||||||
// stub loaded external module to avoid loading of external dep
|
|
||||||
window['@tryghost/koenig-lexical'] = {
|
|
||||||
KoenigComposer: () => null,
|
|
||||||
KoenigEditor: () => null
|
|
||||||
};
|
|
||||||
|
|
||||||
setApplication(Application.create(config.APP));
|
setApplication(Application.create(config.APP));
|
||||||
|
|
||||||
registerWaiter();
|
registerWaiter();
|
||||||
|
Loading…
Reference in New Issue
Block a user