diff --git a/ghost/admin/app/templates/components/gh-theme-table.hbs b/ghost/admin/app/templates/components/gh-theme-table.hbs index d015c57f37..83a5faff24 100644 --- a/ghost/admin/app/templates/components/gh-theme-table.hbs +++ b/ghost/admin/app/templates/components/gh-theme-table.hbs @@ -1,28 +1,28 @@ -
+
{{#if sortedThemes}} {{#each sortedThemes as |theme|}} -
+
-

{{theme.label}}

-

Version {{theme.version}}

+

{{theme.label}}

+

Version {{theme.version}}

{{!--Delete--}} {{#if theme.isDeletable}} - Delete + Delete {{/if}} {{!--Download--}} - Download + Download {{!--Active Label / Activate Button--}} {{#if theme.active}} - Active + Active {{else}} - + Activate {{/if}} diff --git a/ghost/admin/tests/acceptance/settings/design-test.js b/ghost/admin/tests/acceptance/settings/design-test.js index 69ba53323c..20cf8da3e9 100644 --- a/ghost/admin/tests/acceptance/settings/design-test.js +++ b/ghost/admin/tests/acceptance/settings/design-test.js @@ -245,14 +245,14 @@ describe('Acceptance: Settings - Design', function () { // lists available themes (themes are specified in mirage/fixtures/settings) andThen(() => { expect( - find('.theme-list-item').length, + find(testSelector('theme-id')).length, 'shows correct number of themes' ).to.equal(3); expect( - find('.theme-list-item:contains("Blog")').hasClass('theme-list-item--active'), + find(`${testSelector('theme-active', 'true')} ${testSelector('theme-title')}`).text().trim(), 'Blog theme marked as active' - ); + ).to.equal('Blog (default)'); }); // theme upload displays modal @@ -473,14 +473,14 @@ describe('Acceptance: Settings - Design', function () { ).to.match(/"Test 1 - 0\.1" uploaded successfully/); expect( - find('.theme-list-item').length, + find(testSelector('theme-id')).length, 'number of themes in list grows after upload' ).to.equal(4); expect( - find('.theme-list-item:contains("Test 1 - 0.1")').hasClass('theme-list-item--active'), - 'newly uploaded theme is active' - ).to.be.false; + find(`${testSelector('theme-active', 'true')} ${testSelector('theme-title')}`).text().trim(), + 'newly uploaded theme is not active' + ).to.equal('Blog (default)'); }); click(`.fullscreen-modal ${testSelector('close-button')}`); @@ -490,32 +490,32 @@ describe('Acceptance: Settings - Design', function () { click(`.fullscreen-modal ${testSelector('activate-now-button')}`); andThen(() => { expect( - find('.theme-list-item').length, + find(testSelector('theme-id')).length, 'number of themes in list grows after upload and activate' ).to.equal(5); expect( - find('.theme-list-item:contains("Test 2 - 0.1")').hasClass('theme-list-item--active'), + find(`${testSelector('theme-active', 'true')} ${testSelector('theme-title')}`).text().trim(), 'newly uploaded+activated theme is active' - ).to.be.true; + ).to.equal('Test 2'); }); // theme activation switches active theme - click('.theme-list-item:contains("Blog") a:contains("Activate")'); + click(`${testSelector('theme-id', 'casper')} ${testSelector('theme-activate-button')}`); andThen(() => { expect( - find('.theme-list-item:contains("Test 2 - 0.1")').hasClass('theme-list-item--active'), + find(`${testSelector('theme-id', 'test-2')} .apps-card-app`).hasClass('theme-list-item--active'), 'previously active theme is not active' ).to.be.false; expect( - find('.theme-list-item:contains("Blog")').hasClass('theme-list-item--active'), + find(`${testSelector('theme-id', 'casper')} .apps-card-app`).hasClass('theme-list-item--active'), 'activated theme is active' ).to.be.true; }); // theme deletion displays modal - click('.theme-list-item:contains("Test 1") a:contains("Delete")'); + click(`${testSelector('theme-id', 'test-1')} ${testSelector('theme-delete-button')}`); andThen(() => { expect( find(testSelector('delete-theme-modal')).length, @@ -533,7 +533,7 @@ describe('Acceptance: Settings - Design', function () { }); // confirming theme deletion closes modal and refreshes list - click('.theme-list-item:contains("Test 1") a:contains("Delete")'); + click(`${testSelector('theme-id', 'test-1')} ${testSelector('theme-delete-button')}`); click(`.fullscreen-modal ${testSelector('delete-button')}`); andThen(() => { expect( @@ -544,12 +544,12 @@ describe('Acceptance: Settings - Design', function () { andThen(() => { expect( - find('.theme-list-item').length, + find(testSelector('theme-id')).length, 'number of themes in list shrinks after delete' ).to.equal(4); expect( - find('.theme-list-item .name').text(), + find(testSelector('theme-title')).text(), 'correct theme is removed from theme list after deletion' ).to.not.match(/Test 1/); }); @@ -564,7 +564,7 @@ describe('Acceptance: Settings - Design', function () { }); }); }); - click('.theme-list-item:contains("Test 2") a:contains("Delete")'); + click(`${testSelector('theme-id', 'test-2')} ${testSelector('theme-delete-button')}`); click(`.fullscreen-modal ${testSelector('delete-button')}`); andThen(() => { expect( diff --git a/ghost/admin/tests/integration/components/gh-theme-table-test.js b/ghost/admin/tests/integration/components/gh-theme-table-test.js index 74a576dbee..de194a1fd0 100644 --- a/ghost/admin/tests/integration/components/gh-theme-table-test.js +++ b/ghost/admin/tests/integration/components/gh-theme-table-test.js @@ -6,6 +6,7 @@ import hbs from 'htmlbars-inline-precompile'; import $ from 'jquery'; import sinon from 'sinon'; import run from 'ember-runloop'; +import testSelector from 'ember-test-selectors'; describe('Integration: Component: gh-theme-table', function() { setupComponentTest('gh-theme-table', { @@ -29,55 +30,55 @@ describe('Integration: Component: gh-theme-table', function() { deleteTheme=(action actionHandler) }}`); - expect(this.$('.theme-list').length, '.theme-list is present').to.equal(1); - expect(this.$('.theme-list-item').length, 'number of rows').to.equal(4); + expect(this.$(testSelector('themes-list')).length, 'themes list is present').to.equal(1); + expect(this.$(testSelector('theme-id')).length, 'number of rows').to.equal(4); - let packageNames = this.$('.theme-list-item-body .name').map((i, name) => { + let packageNames = this.$(testSelector('theme-title')).map((i, name) => { return $(name).text().trim(); }).toArray(); expect( packageNames, - 'themes are ordered by label, casper has "default", package versions are shown' + 'themes are ordered by label, casper has "default"' ).to.deep.equal([ - 'Casper - 1.3.1 (default)', - 'Daring - 0.1.4', + 'Casper (default)', + 'Daring', 'foo', - 'Lanyon - 1.1.0' + 'Lanyon' ]); expect( - this.$('.theme-list-item:contains("Daring")').hasClass('theme-list-item--active'), + this.$(testSelector('theme-active', 'true')).find(testSelector('theme-title')).text().trim(), 'active theme is highlighted' - ).to.be.true; + ).to.equal('Daring'); expect( - this.$('.theme-list-item:not(:contains("Daring"))').find('a:contains("Activate")').length === 3, + this.$(testSelector('theme-activate-button')).length === 3, 'non-active themes have an activate link' ).to.be.true; expect( - this.$('.theme-list-item:contains("Daring")').find('a:contains("Activate")').length === 0, + this.$(testSelector('theme-active', 'true')).find(testSelector('theme-activate-button')).length === 0, 'active theme doesn\'t have an activate link' ).to.be.true; expect( - this.$('a:contains("Download")').length, + this.$(testSelector('theme-download-button')).length, 'all themes have a download link' ).to.equal(4); expect( - this.$('.theme-list-item:contains("foo")').find('a:contains("Delete")').length === 1, + this.$(testSelector('theme-id', 'foo')).find(testSelector('theme-delete-button')).length === 1, 'non-active, non-casper theme has delete link' ).to.be.true; expect( - this.$('.theme-list-item:contains("Casper")').find('a:contains("Delete")').length === 0, + this.$(testSelector('theme-id', 'casper')).find(testSelector('theme-delete-button')).length === 0, 'casper doesn\'t have delete link' ).to.be.true; expect( - this.$('.theme-list-item--active').find('a:contains("Delete")').length === 0, + this.$(testSelector('theme-active', 'true')).find(testSelector('theme-delete-button')).length === 0, 'active theme doesn\'t have delete link' ).to.be.true; }); @@ -101,7 +102,7 @@ describe('Integration: Component: gh-theme-table', function() { }}`); run(() => { - this.$('.theme-list-item:contains("Bar") a:contains("Delete")').click(); + this.$(`${testSelector('theme-id', 'Bar')} ${testSelector('theme-delete-button')}`).click(); }); expect(deleteAction.calledOnce).to.be.true; @@ -127,7 +128,7 @@ describe('Integration: Component: gh-theme-table', function() { }}`); run(() => { - this.$('.theme-list-item:contains("Foo") a:contains("Download")').click(); + this.$(`${testSelector('theme-id', 'Foo')} ${testSelector('theme-download-button')}`).click(); }); expect(downloadAction.calledOnce).to.be.true; @@ -153,7 +154,7 @@ describe('Integration: Component: gh-theme-table', function() { }}`); run(() => { - this.$('.theme-list-item:contains("Bar") a:contains("Activate")').click(); + this.$(`${testSelector('theme-id', 'Bar')} ${testSelector('theme-activate-button')}`).click(); }); expect(activateAction.calledOnce).to.be.true; @@ -178,7 +179,7 @@ describe('Integration: Component: gh-theme-table', function() { deleteTheme=(action actionHandler) }}`); - let packageNames = this.$('.theme-list-item-body .name').map((i, name) => { + let packageNames = this.$(testSelector('theme-title')).map((i, name) => { return $(name).text().trim(); }).toArray(); @@ -186,11 +187,11 @@ describe('Integration: Component: gh-theme-table', function() { packageNames, 'themes are ordered by label, folder names shown for duplicates' ).to.deep.equal([ - 'Casper - 1.3.1 (another)', - 'Casper - 1.3.1 (default)', - 'Casper - 1.3.1 (mine)', - 'Daring - 0.1.4 (daring)', - 'Daring - 0.1.4 (daring-0.1.5)', + 'Casper (another)', + 'Casper (default)', + 'Casper (mine)', + 'Daring (daring)', + 'Daring (daring-0.1.5)', 'foo' ]); });