0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-03 23:00:14 -05:00

Trim title in editor on blue/focusOut

closes #3040, fixes #3038
- Properly trim title
- Re-add casper test/adjust where necessary
- Rename gh-focus-input component
This commit is contained in:
Fabian Becker 2014-06-23 17:50:28 +00:00
parent d135930344
commit a5900d34ff
5 changed files with 121 additions and 111 deletions

View file

@ -1,7 +0,0 @@
var FocusInput = Ember.TextField.extend({
becomeFocused: function () {
this.$().val(this.$().val()).focus();
}.on('didInsertElement')
});
export default FocusInput;

View file

@ -0,0 +1,13 @@
var TrimFocusInput = Ember.TextField.extend({
setFocus: function () {
this.$().val(this.$().val()).focus();
}.on('didInsertElement'),
focusOut: function () {
var text = this.$().val();
this.$().val(text.trim());
}
});
export default TrimFocusInput;

View file

@ -4,7 +4,7 @@ var Post = DS.Model.extend(ValidationEngine, {
validationType: 'post', validationType: 'post',
uuid: DS.attr('string'), uuid: DS.attr('string'),
title: DS.attr('string'), title: DS.attr('string', {defaultValue: ''}),
slug: DS.attr('string'), slug: DS.attr('string'),
markdown: DS.attr('string', {defaultValue: ''}), markdown: DS.attr('string', {defaultValue: ''}),
html: DS.attr('string'), html: DS.attr('string'),

View file

@ -1,6 +1,6 @@
<header> <header>
<section class="box entry-title"> <section class="box entry-title">
{{gh-focus-input type="text" id="entry-title" placeholder="Your Post Title" value=title tabindex="1"}} {{gh-trim-focus-input type="text" id="entry-title" placeholder="Your Post Title" value=title tabindex="1"}}
</section> </section>
</header> </header>

View file

@ -2,12 +2,12 @@
// Test the editor screen works as expected // Test the editor screen works as expected
/*globals casper, __utils__, url, testPost */ /*globals casper, __utils__, url, testPost */
CasperTest.emberBegin("Ghost editor functions correctly", 14, function suite(test) { CasperTest.emberBegin('Ghost editor functions correctly', 15, function suite(test) {
casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() { casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() {
test.assertTitle("Ghost Admin", "Ghost admin has no title"); test.assertTitle('Ghost Admin', 'Ghost admin has no title');
test.assertUrlMatch(/ghost\/ember\/editor\/$/, 'Landed on the correct URL'); test.assertUrlMatch(/ghost\/ember\/editor\/$/, 'Landed on the correct URL');
test.assertExists(".entry-markdown", "Ghost editor is present"); test.assertExists('.entry-markdown', 'Ghost editor is present');
test.assertExists(".entry-preview", "Ghost preview is present"); test.assertExists('.entry-preview', 'Ghost preview is present');
}); });
// Part 1: Test saving with no data - title is required // Part 1: Test saving with no data - title is required
@ -48,18 +48,22 @@ CasperTest.emberBegin("Ghost editor functions correctly", 14, function suite(tes
}, testPost.title, 'Title is correct'); }, testPost.title, 'Title is correct');
}, casper.failOnTimeout(test, 'Post was not successfully created')); }, casper.failOnTimeout(test, 'Post was not successfully created'));
// TODO: uncomment when fixed in #3040
// Part 3: Test title trimming // Part 3: Test title trimming
// var untrimmedTitle = ' test title ', var untrimmedTitle = ' test title ',
// trimmedTitle = 'test title'; trimmedTitle = 'test title';
//
// casper.then(function populateTitle() { casper.then(function populateTitle() {
// casper.sendKeys('#entry-title', untrimmedTitle); // Clear element
// casper.evaluate(function () {
// test.assertEvalEquals(function () { $('#entry-title').val('');
// return $('#entry-title').val(); });
// }, trimmedTitle, 'Entry title should match expected value.'); casper.sendKeys('#entry-title', untrimmedTitle);
// }); casper.click('#entry-markdown-content');
test.assertEvalEquals(function () {
return $('#entry-title').val();
}, trimmedTitle, 'Entry title should match expected value.');
});
// Part 4: Word count and plurality // Part 4: Word count and plurality
casper.then(function checkZeroPlural() { casper.then(function checkZeroPlural() {
@ -84,14 +88,14 @@ CasperTest.emberBegin("Ghost editor functions correctly", 14, function suite(tes
}); });
// TODO: Expand markdown tests to cover more markdown, and keyboard shortcuts // TODO: Expand markdown tests to cover more markdown, and keyboard shortcuts
CasperTest.emberBegin("Markdown in editor works", 4, function suite(test) { CasperTest.emberBegin('Markdown in editor works', 4, function suite(test) {
casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() { casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() {
test.assertTitle("Ghost Admin", "Ghost admin has no title"); test.assertTitle('Ghost Admin', 'Ghost admin has no title');
test.assertUrlMatch(/ghost\/ember\/editor\/$/, 'Landed on the correct URL'); test.assertUrlMatch(/ghost\/ember\/editor\/$/, 'Landed on the correct URL');
}); });
casper.then(function testImage() { casper.then(function testImage() {
casper.writeContentToCodeMirror("![sometext]()"); casper.writeContentToCodeMirror('![sometext]()');
}); });
casper.waitForSelectorTextChange('.entry-preview .rendered-markdown', function onSuccess() { casper.waitForSelectorTextChange('.entry-preview .rendered-markdown', function onSuccess() {
@ -105,144 +109,144 @@ CasperTest.emberBegin("Markdown in editor works", 4, function suite(test) {
}); });
}); });
CasperTest.emberBegin("Image Uploads", 17, function suite(test) { CasperTest.emberBegin('Image Uploads', 17, function suite(test) {
casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() { casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() {
test.assertTitle("Ghost Admin", "Ghost admin has no title"); test.assertTitle('Ghost Admin', 'Ghost admin has no title');
test.assertUrlMatch(/ghost\/ember\/editor\/$/, 'Landed on the correct URL'); test.assertUrlMatch(/ghost\/ember\/editor\/$/, 'Landed on the correct URL');
}); });
// Test standard image upload modal // Test standard image upload modal
casper.then(function () { casper.then(function () {
casper.writeContentToCodeMirror("![]()"); casper.writeContentToCodeMirror('![]()');
}); });
function assertEmptyImageUploaderDisplaysCorrectly() { function assertEmptyImageUploaderDisplaysCorrectly() {
test.assertExists(".entry-preview .js-upload-target", "Upload target exists"); test.assertExists('.entry-preview .js-upload-target', 'Upload target exists');
test.assertExists(".entry-preview .js-fileupload", "File upload target exists"); test.assertExists('.entry-preview .js-fileupload', 'File upload target exists');
test.assertExists(".entry-preview .image-url", "Image URL button exists"); test.assertExists('.entry-preview .image-url', 'Image URL button exists');
} }
casper.waitForSelector(".entry-preview .js-drop-zone.image-uploader", assertEmptyImageUploaderDisplaysCorrectly); casper.waitForSelector('.entry-preview .js-drop-zone.image-uploader', assertEmptyImageUploaderDisplaysCorrectly);
// Test image URL upload modal // Test image URL upload modal
casper.thenClick(".entry-preview .image-uploader a.image-url"); casper.thenClick('.entry-preview .image-uploader a.image-url');
casper.waitForSelector(".image-uploader-url", function onSuccess() { casper.waitForSelector('.image-uploader-url', function onSuccess() {
test.assertExists(".image-uploader-url .url.js-upload-url", "Image URL uploader exists") test.assertExists('.image-uploader-url .url.js-upload-url', 'Image URL uploader exists')
test.assertExists(".image-uploader-url .button-save.js-button-accept", "Image URL accept button exists") test.assertExists('.image-uploader-url .button-save.js-button-accept', 'Image URL accept button exists')
test.assertExists(".image-uploader-url .image-upload", "Back to normal image upload style button exists") test.assertExists('.image-uploader-url .image-upload', 'Back to normal image upload style button exists')
}); });
// Test image source location // Test image source location
casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() { casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() {
test.assertTitle("Ghost Admin", "Ghost admin has no title"); test.assertTitle('Ghost Admin', 'Ghost admin has no title');
test.assertUrlMatch(/ghost\/ember\/editor\/$/, 'Landed on the correct URL'); test.assertUrlMatch(/ghost\/ember\/editor\/$/, 'Landed on the correct URL');
}); });
var testFileLocation = "test/file/location"; var testFileLocation = 'test/file/location';
casper.then(function () { casper.then(function () {
var markdownImageString = "![](" + testFileLocation + ")"; var markdownImageString = '![](' + testFileLocation + ')';
casper.writeContentToCodeMirror(markdownImageString); casper.writeContentToCodeMirror(markdownImageString);
}); });
casper.waitForSelector(".entry-preview .js-drop-zone.pre-image-uploader", function onSuccess() { casper.waitForSelector('.entry-preview .js-drop-zone.pre-image-uploader', function onSuccess() {
var imageJQuerySelector = ".entry-preview img.js-upload-target[src='" + testFileLocation + "']" var imageJQuerySelector = '.entry-preview img.js-upload-target[src="' + testFileLocation + '"]';
test.assertExists(imageJQuerySelector, "Uploaded image tag properly links to source location"); test.assertExists(imageJQuerySelector, 'Uploaded image tag properly links to source location');
}); });
// Test cancel image button // Test cancel image button
casper.thenClick(".pre-image-uploader a.image-cancel.js-cancel"); casper.thenClick('.pre-image-uploader a.image-cancel.js-cancel');
casper.waitForSelector(".entry-preview .js-drop-zone.image-uploader", assertEmptyImageUploaderDisplaysCorrectly); casper.waitForSelector('.entry-preview .js-drop-zone.image-uploader', assertEmptyImageUploaderDisplaysCorrectly);
// Test image url source location // Test image url source location
casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() { casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() {
test.assertTitle("Ghost Admin", "Ghost admin has no title"); test.assertTitle('Ghost Admin', 'Ghost admin has no title');
test.assertUrlMatch(/ghost\/ember\/editor\/$/, 'Landed on the correct URL'); test.assertUrlMatch(/ghost\/ember\/editor\/$/, 'Landed on the correct URL');
}); });
casper.then(function () { casper.then(function () {
casper.writeContentToCodeMirror("![]()"); casper.writeContentToCodeMirror('![]()');
}); });
casper.waitForSelector(".entry-preview .js-drop-zone.image-uploader", function onSuccess() { casper.waitForSelector('.entry-preview .js-drop-zone.image-uploader', function onSuccess() {
casper.thenClick(".entry-preview .image-uploader a.image-url"); casper.thenClick('.entry-preview .image-uploader a.image-url');
}); });
var imageURL = "random.url"; var imageURL = 'random.url';
casper.waitForSelector(".image-uploader-url", function onSuccess() { casper.waitForSelector('.image-uploader-url', function onSuccess() {
casper.sendKeys(".image-uploader-url input.url.js-upload-url", imageURL); casper.sendKeys('.image-uploader-url input.url.js-upload-url', imageURL);
casper.thenClick(".js-button-accept.button-save"); casper.thenClick('.js-button-accept.button-save');
}); });
casper.waitForSelector(".entry-preview .js-drop-zone.pre-image-uploader", function onSuccess() { casper.waitForSelector('.entry-preview .js-drop-zone.pre-image-uploader', function onSuccess() {
var imageJQuerySelector = ".entry-preview img.js-upload-target[src='" + imageURL + "']" var imageJQuerySelector = '.entry-preview img.js-upload-target[src="' + imageURL + '"]'
test.assertExists(imageJQuerySelector, "Uploaded image tag properly links to inputted image URL"); test.assertExists(imageJQuerySelector, 'Uploaded image tag properly links to inputted image URL');
}); });
}); });
CasperTest.emberBegin("Tag editor", 7, function suite(test) { CasperTest.emberBegin('Tag editor', 7, function suite(test) {
casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() { casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() {
test.assertTitle("Ghost Admin", "Ghost admin has no title"); test.assertTitle('Ghost Admin', 'Ghost admin has no title');
test.assertUrlMatch(/ghost\/ember\/editor\/$/, 'Landed on the correct URL'); test.assertUrlMatch(/ghost\/ember\/editor\/$/, 'Landed on the correct URL');
}); });
var tagName = "someTagName"; var tagName = 'someTagName';
casper.then(function () { casper.then(function () {
test.assertExists("#entry-tags", "should have tag label area"); test.assertExists('#entry-tags', 'should have tag label area');
test.assertExists("#entry-tags .tag-label", "should have tag label icon"); test.assertExists('#entry-tags .tag-label', 'should have tag label icon');
test.assertExists("#entry-tags input.tag-input", "should have tag input area"); test.assertExists('#entry-tags input.tag-input', 'should have tag input area');
casper.sendKeys("#entry-tags input.tag-input", tagName); casper.sendKeys('#entry-tags input.tag-input', tagName);
casper.sendKeys("#entry-tags input.tag-input", casper.page.event.key.Enter); casper.sendKeys('#entry-tags input.tag-input', casper.page.event.key.Enter);
}); });
var createdTagSelector = "#entry-tags .tags .tag"; var createdTagSelector = '#entry-tags .tags .tag';
casper.waitForSelector(createdTagSelector, function onSuccess() { casper.waitForSelector(createdTagSelector, function onSuccess() {
test.assertSelectorHasText(createdTagSelector, tagName, "typing enter after tag name should create tag"); test.assertSelectorHasText(createdTagSelector, tagName, 'typing enter after tag name should create tag');
}); });
casper.thenClick(createdTagSelector); casper.thenClick(createdTagSelector);
casper.waitWhileSelector(createdTagSelector, function onSuccess() { casper.waitWhileSelector(createdTagSelector, function onSuccess() {
test.assert(true, "clicking the tag should delete the tag"); test.assert(true, 'clicking the tag should delete the tag');
}); });
}); });
CasperTest.emberBegin("Post settings menu", 30, function suite(test) { CasperTest.emberBegin('Post settings menu', 30, function suite(test) {
casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() { casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() {
test.assertTitle("Ghost Admin", "Ghost admin has no title"); test.assertTitle('Ghost Admin', 'Ghost admin has no title');
test.assertUrlMatch(/ghost\/ember\/editor\/$/, 'Landed on the correct URL'); test.assertUrlMatch(/ghost\/ember\/editor\/$/, 'Landed on the correct URL');
}); });
casper.then(function () { casper.then(function () {
test.assertExists("#publish-bar a.post-settings", "icon toggle should exist"); test.assertExists('#publish-bar a.post-settings', 'icon toggle should exist');
test.assertNotVisible("#publish-bar .post-settings-menu", "popup menu should not be visible at startup"); test.assertNotVisible('#publish-bar .post-settings-menu', 'popup menu should not be visible at startup');
test.assertExists(".post-settings-menu input#url", "url field exists"); test.assertExists('.post-settings-menu input#url', 'url field exists');
test.assertExists(".post-settings-menu input.post-setting-date", "publication date field exists"); test.assertExists('.post-settings-menu input.post-setting-date', 'publication date field exists');
test.assertExists(".post-settings-menu input.post-setting-static-page", "static page checkbox field exists"); test.assertExists('.post-settings-menu input.post-setting-static-page', 'static page checkbox field exists');
test.assertExists(".post-settings-menu a.delete", "delete post button exists") test.assertExists('.post-settings-menu a.delete', 'delete post button exists')
}); });
casper.thenClick("#publish-bar a.post-settings"); casper.thenClick('#publish-bar a.post-settings');
casper.waitUntilVisible("#publish-bar .post-settings-menu", function onSuccess() { casper.waitUntilVisible('#publish-bar .post-settings-menu', function onSuccess() {
test.assert(true, "popup menu should be visible after clicking post-settings icon"); test.assert(true, 'popup menu should be visible after clicking post-settings icon');
test.assertNotVisible(".post-settings-menu a.delete", "delete post btn shouldn't be visible on unsaved drafts"); test.assertNotVisible('.post-settings-menu a.delete', 'delete post btn shouldn\'t be visible on unsaved drafts');
}); });
casper.thenClick("#publish-bar a.post-settings"); casper.thenClick('#publish-bar a.post-settings');
casper.waitWhileVisible("#publish-bar .post-settings-menu", function onSuccess() { casper.waitWhileVisible('#publish-bar .post-settings-menu', function onSuccess() {
test.assert(true, "popup menu should not be visible after clicking post-settings icon"); test.assert(true, 'popup menu should not be visible after clicking post-settings icon');
}); });
// Enter a title and save draft so converting to/from static post // Enter a title and save draft so converting to/from static post
// will result in notifications and 'Delete This Post' button appears // will result in notifications and 'Delete This Post' button appears
casper.then(function (){ casper.then(function (){
casper.sendKeys("#entry-title", "aTitle"); casper.sendKeys('#entry-title', 'aTitle');
casper.thenClick(".js-publish-button"); casper.thenClick('.js-publish-button');
}); });
casper.waitForSelector('.notification-success', function waitForSuccess() { casper.waitForSelector('.notification-success', function waitForSuccess() {
@ -256,14 +260,14 @@ CasperTest.emberBegin("Post settings menu", 30, function suite(test) {
casper.waitWhileSelector('.notification-success'); casper.waitWhileSelector('.notification-success');
casper.thenClick("#publish-bar a.post-settings"); casper.thenClick('#publish-bar a.post-settings');
casper.waitUntilVisible("#publish-bar .post-settings-menu", function onSuccess() { casper.waitUntilVisible('#publish-bar .post-settings-menu', function onSuccess() {
test.assert(true, "post settings menu should be visible after clicking post-settings icon"); test.assert(true, 'post settings menu should be visible after clicking post-settings icon');
}); });
casper.waitUntilVisible(".post-settings-menu a.delete", function onSuccess() { casper.waitUntilVisible('.post-settings-menu a.delete', function onSuccess() {
test.assert(true, "delete post button should be visible for saved drafts"); test.assert(true, 'delete post button should be visible for saved drafts');
}); });
// Test change permalink // Test change permalink
@ -314,10 +318,10 @@ CasperTest.emberBegin("Post settings menu", 30, function suite(test) {
casper.waitWhileSelector('.notification-success'); casper.waitWhileSelector('.notification-success');
// Test Static Page conversion // Test Static Page conversion
casper.thenClick("#publish-bar a.post-settings"); casper.thenClick('#publish-bar a.post-settings');
casper.waitUntilVisible("#publish-bar .post-settings-menu", function onSuccess() { casper.waitUntilVisible('#publish-bar .post-settings-menu', function onSuccess() {
test.assert(true, "post settings menu should be visible after clicking post-settings icon"); test.assert(true, 'post settings menu should be visible after clicking post-settings icon');
}); });
casper.thenClick('.post-settings-menu .post-setting-static-page'); casper.thenClick('.post-settings-menu .post-setting-static-page');
@ -344,36 +348,36 @@ CasperTest.emberBegin("Post settings menu", 30, function suite(test) {
}); });
// Test Delete Post Modal // Test Delete Post Modal
casper.thenClick(".post-settings-menu a.delete"); casper.thenClick('.post-settings-menu a.delete');
casper.waitUntilVisible("#modal-container", function onSuccess() { casper.waitUntilVisible('#modal-container', function onSuccess() {
test.assert(true, "delete post modal is visible after clicking delete"); test.assert(true, 'delete post modal is visible after clicking delete');
test.assertSelectorHasText( test.assertSelectorHasText(
"#modal-container .modal-header", '#modal-container .modal-header',
"Are you sure you want to delete this post?", 'Are you sure you want to delete this post?',
"delete post modal header has correct text"); 'delete post modal header has correct text');
}); });
casper.thenClick("#modal-container .js-button-reject"); casper.thenClick('#modal-container .js-button-reject');
casper.waitWhileVisible("#modal-container", function onSuccess() { casper.waitWhileVisible('#modal-container', function onSuccess() {
test.assert(true, "clicking cancel should close the delete post modal"); test.assert(true, 'clicking cancel should close the delete post modal');
}); });
casper.thenClick("#publish-bar a.post-settings"); casper.thenClick('#publish-bar a.post-settings');
casper.thenClick(".post-settings-menu a.delete"); casper.thenClick('.post-settings-menu a.delete');
casper.waitUntilVisible("#modal-container", function onSuccess() { casper.waitUntilVisible('#modal-container', function onSuccess() {
casper.thenClick("#modal-container .js-button-accept"); casper.thenClick('#modal-container .js-button-accept');
}); });
casper.waitForUrl(/ghost\/ember\/\d+\/$/, function onSuccess() { casper.waitForUrl(/ghost\/ember\/\d+\/$/, function onSuccess() {
test.assert(true, "clicking the delete post button should bring us to the content page"); test.assert(true, 'clicking the delete post button should bring us to the content page');
}); });
}); });
CasperTest.emberBegin('Publish menu - new post', 11, function suite(test) { CasperTest.emberBegin('Publish menu - new post', 11, function suite(test) {
casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() { casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() {
test.assertTitle("Ghost Admin", "Ghost admin has no title"); test.assertTitle('Ghost Admin', 'Ghost admin has no title');
test.assertUrlMatch(/ghost\/ember\/editor\/$/, 'Landed on the correct URL'); test.assertUrlMatch(/ghost\/ember\/editor\/$/, 'Landed on the correct URL');
}); });
@ -419,7 +423,7 @@ CasperTest.emberBegin('Publish menu - new post', 11, function suite(test) {
CasperTest.emberBegin('Publish menu - existing post', 21, function suite(test) { CasperTest.emberBegin('Publish menu - existing post', 21, function suite(test) {
// Create a post, save it and test refreshed editor // Create a post, save it and test refreshed editor
casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() { casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() {
test.assertTitle("Ghost Admin", "Ghost admin has no title"); test.assertTitle('Ghost Admin', 'Ghost admin has no title');
test.assertUrlMatch(/ghost\/ember\/editor\/$/, 'Landed on the correct URL'); test.assertUrlMatch(/ghost\/ember\/editor\/$/, 'Landed on the correct URL');
}); });
@ -517,7 +521,7 @@ CasperTest.emberBegin('Publish menu - existing post', 21, function suite(test) {
// test the markdown help modal // test the markdown help modal
CasperTest.emberBegin('Markdown help modal', 5, function suite(test) { CasperTest.emberBegin('Markdown help modal', 5, function suite(test) {
casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() { casper.thenOpenAndWaitForPageLoad('editor', function testTitleAndUrl() {
test.assertTitle("Ghost Admin", "Ghost admin has no title"); test.assertTitle('Ghost Admin', 'Ghost admin has no title');
test.assertUrlMatch(/ghost\/ember\/editor\/$/, 'Landed on the correct URL'); test.assertUrlMatch(/ghost\/ember\/editor\/$/, 'Landed on the correct URL');
}); });