kuji-mercury-rails 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +25 -0
- data/POST_INSTALL +15 -0
- data/app/controllers/mercury/images_controller.rb +19 -0
- data/app/controllers/mercury_controller.rb +34 -0
- data/app/models/mercury/image.rb +16 -0
- data/app/views/layouts/mercury.html.erb +33 -0
- data/app/views/mercury/lightviews/about.html +11 -0
- data/app/views/mercury/modals/character.html +255 -0
- data/app/views/mercury/modals/htmleditor.html +13 -0
- data/app/views/mercury/modals/link.html +75 -0
- data/app/views/mercury/modals/media.html +82 -0
- data/app/views/mercury/modals/table.html +84 -0
- data/app/views/mercury/palettes/backcolor.html +73 -0
- data/app/views/mercury/palettes/forecolor.html +73 -0
- data/app/views/mercury/panels/history.html +3 -0
- data/app/views/mercury/panels/notes.html +3 -0
- data/app/views/mercury/panels/snippets.html +12 -0
- data/app/views/mercury/selects/formatblock.html +11 -0
- data/app/views/mercury/selects/style.html +5 -0
- data/app/views/mercury/snippets/example/options.html.erb +34 -0
- data/app/views/mercury/snippets/example/preview.html.erb +1 -0
- data/config/engine.rb +41 -0
- data/db/migrate/20110526035601_create_mercury_images.rb +11 -0
- data/features/loading/loading.feature +22 -0
- data/features/loading/navigating.feature +77 -0
- data/features/loading/user_interface.feature +67 -0
- data/features/regions/editable/advanced_editing.feature +0 -0
- data/features/regions/editable/basic_editing.feature +195 -0
- data/features/regions/editable/inserting_links.feature +98 -0
- data/features/regions/editable/inserting_media.feature +110 -0
- data/features/regions/editable/inserting_snippets.feature +102 -0
- data/features/regions/editable/inserting_special_characters.feature +24 -0
- data/features/regions/editable/inserting_tables.feature +109 -0
- data/features/regions/editable/pasting.feature +0 -0
- data/features/regions/editable/uploading_images.feature +0 -0
- data/features/regions/image/uploading_images.feature +0 -0
- data/features/regions/markupable/advanced_editing.feature +0 -0
- data/features/regions/markupable/basic_editing.feature +0 -0
- data/features/regions/markupable/inserting_links.feature +0 -0
- data/features/regions/markupable/inserting_media.feature +0 -0
- data/features/regions/markupable/inserting_snippets.feature +0 -0
- data/features/regions/markupable/inserting_special_characters.feature +0 -0
- data/features/regions/markupable/inserting_tables.feature +0 -0
- data/features/regions/markupable/uploading_images.feature +0 -0
- data/features/regions/simple/basic_editing.feature +5 -0
- data/features/regions/snippetable/advanced_editing.feature +0 -0
- data/features/regions/snippetable/basic_editing.feature +0 -0
- data/features/regions/snippetable/inserting_snippets.feature +0 -0
- data/features/saving/saving.feature +33 -0
- data/features/step_definitions/debug_steps.rb +14 -0
- data/features/step_definitions/mercury_steps.rb +438 -0
- data/features/step_definitions/web_steps.rb +211 -0
- data/features/support/env.rb +46 -0
- data/features/support/mercury_contents.rb +25 -0
- data/features/support/mercury_selectors.rb +148 -0
- data/features/support/paths.rb +38 -0
- data/features/support/selectors.rb +44 -0
- data/lib/generators/mercury/install/install_generator.rb +49 -0
- data/lib/generators/mercury/install/templates/mongoid_paperclip_image.rb +17 -0
- data/lib/mercury-rails.rb +3 -0
- data/lib/mercury/authentication.rb +8 -0
- data/spec/javascripts/mercury/dialog_spec.js.coffee +281 -0
- data/spec/javascripts/mercury/dialogs/backcolor_spec.js.coffee +37 -0
- data/spec/javascripts/mercury/dialogs/forecolor_spec.js.coffee +37 -0
- data/spec/javascripts/mercury/dialogs/formatblock_spec.js.coffee +25 -0
- data/spec/javascripts/mercury/dialogs/snippetpanel_spec.js.coffee +30 -0
- data/spec/javascripts/mercury/dialogs/style_spec.js.coffee +25 -0
- data/spec/javascripts/mercury/history_buffer_spec.js.coffee +76 -0
- data/spec/javascripts/mercury/lightview_spec.js.coffee +497 -0
- data/spec/javascripts/mercury/mercury_spec.js.coffee +132 -0
- data/spec/javascripts/mercury/modal_spec.js.coffee +504 -0
- data/spec/javascripts/mercury/modals/htmleditor_spec.js.coffee +30 -0
- data/spec/javascripts/mercury/modals/insertcharacter_spec.js.coffee +29 -0
- data/spec/javascripts/mercury/modals/insertlink_spec.js.coffee +220 -0
- data/spec/javascripts/mercury/modals/insertmedia_spec.js.coffee +167 -0
- data/spec/javascripts/mercury/modals/insertsnippet_spec.js.coffee +52 -0
- data/spec/javascripts/mercury/modals/inserttable_spec.js.coffee +160 -0
- data/spec/javascripts/mercury/native_extensions_spec.js.coffee +60 -0
- data/spec/javascripts/mercury/page_editor_spec.js.coffee +757 -0
- data/spec/javascripts/mercury/palette_spec.js.coffee +49 -0
- data/spec/javascripts/mercury/panel_spec.js.coffee +183 -0
- data/spec/javascripts/mercury/region_spec.js.coffee +298 -0
- data/spec/javascripts/mercury/regions/editable_spec.js.coffee +561 -0
- data/spec/javascripts/mercury/regions/image_spec.js.coffee +34 -0
- data/spec/javascripts/mercury/regions/markupable_spec.js.coffee +367 -0
- data/spec/javascripts/mercury/regions/simple_spec.js.coffee +33 -0
- data/spec/javascripts/mercury/regions/snippetable_spec.js.coffee +370 -0
- data/spec/javascripts/mercury/select_spec.js.coffee +49 -0
- data/spec/javascripts/mercury/snippet_spec.js.coffee +253 -0
- data/spec/javascripts/mercury/snippet_toolbar_spec.js.coffee +184 -0
- data/spec/javascripts/mercury/statusbar_spec.js.coffee +150 -0
- data/spec/javascripts/mercury/table_editor_spec.js.coffee +194 -0
- data/spec/javascripts/mercury/toolbar.button_group_spec.js.coffee +90 -0
- data/spec/javascripts/mercury/toolbar.button_spec.js.coffee +360 -0
- data/spec/javascripts/mercury/toolbar.expander_spec.js.coffee +118 -0
- data/spec/javascripts/mercury/toolbar_spec.js.coffee +222 -0
- data/spec/javascripts/mercury/tooltip_spec.js.coffee +186 -0
- data/spec/javascripts/mercury/uploader_spec.js.coffee +530 -0
- data/spec/javascripts/spec_helper.js +513 -0
- data/spec/javascripts/templates/mercury/dialog.html +2 -0
- data/spec/javascripts/templates/mercury/dialogs/backcolor.html +5 -0
- data/spec/javascripts/templates/mercury/dialogs/forecolor.html +5 -0
- data/spec/javascripts/templates/mercury/dialogs/formatblock.html +3 -0
- data/spec/javascripts/templates/mercury/dialogs/snippetpanel.html +16 -0
- data/spec/javascripts/templates/mercury/dialogs/style.html +3 -0
- data/spec/javascripts/templates/mercury/lightview.html +13 -0
- data/spec/javascripts/templates/mercury/modal.html +13 -0
- data/spec/javascripts/templates/mercury/modals/htmleditor.html +5 -0
- data/spec/javascripts/templates/mercury/modals/insertcharacter.html +5 -0
- data/spec/javascripts/templates/mercury/modals/insertlink.html +30 -0
- data/spec/javascripts/templates/mercury/modals/insertmedia.html +35 -0
- data/spec/javascripts/templates/mercury/modals/insertsnippet.html +6 -0
- data/spec/javascripts/templates/mercury/modals/inserttable.html +27 -0
- data/spec/javascripts/templates/mercury/page_editor.html +35 -0
- data/spec/javascripts/templates/mercury/palette.html +16 -0
- data/spec/javascripts/templates/mercury/panel.html +16 -0
- data/spec/javascripts/templates/mercury/region.html +2 -0
- data/spec/javascripts/templates/mercury/regions/editable.html +3 -0
- data/spec/javascripts/templates/mercury/regions/image.html +1 -0
- data/spec/javascripts/templates/mercury/regions/simple.html +3 -0
- data/spec/javascripts/templates/mercury/regions/snippetable.html +4 -0
- data/spec/javascripts/templates/mercury/select.html +16 -0
- data/spec/javascripts/templates/mercury/snippet.html +1 -0
- data/spec/javascripts/templates/mercury/snippet_toolbar.html +16 -0
- data/spec/javascripts/templates/mercury/statusbar.html +8 -0
- data/spec/javascripts/templates/mercury/table_editor.html +65 -0
- data/spec/javascripts/templates/mercury/toolbar.button.html +64 -0
- data/spec/javascripts/templates/mercury/toolbar.button_group.html +9 -0
- data/spec/javascripts/templates/mercury/toolbar.expander.html +18 -0
- data/spec/javascripts/templates/mercury/toolbar.html +11 -0
- data/spec/javascripts/templates/mercury/tooltip.html +12 -0
- data/spec/javascripts/templates/mercury/uploader.html +11 -0
- data/vendor/assets/images/mercury/button.png +0 -0
- data/vendor/assets/images/mercury/close.png +0 -0
- data/vendor/assets/images/mercury/default-snippet.png +0 -0
- data/vendor/assets/images/mercury/loading-dark.gif +0 -0
- data/vendor/assets/images/mercury/loading-light.gif +0 -0
- data/vendor/assets/images/mercury/missing-image.png +0 -0
- data/vendor/assets/images/mercury/search-icon.png +0 -0
- data/vendor/assets/images/mercury/temp-logo.png +0 -0
- data/vendor/assets/images/mercury/toolbar/editable/buttons.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/_expander.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/_pressed.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/historypanel.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/insertcharacter.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/insertlink.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/insertmedia.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/inserttable.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/inspectorpanel.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/notespanel.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/preview.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/redo.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/save.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/snippetpanel.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/undo.png +0 -0
- data/vendor/assets/images/mercury/toolbar/snippetable/buttons.png +0 -0
- data/vendor/assets/javascripts/mercury.js +479 -0
- data/vendor/assets/javascripts/mercury/dependencies/jquery-1.7.js +9300 -0
- data/vendor/assets/javascripts/mercury/dependencies/jquery-ui-1.8.13.custom.js +1328 -0
- data/vendor/assets/javascripts/mercury/dependencies/jquery.additions.js +206 -0
- data/vendor/assets/javascripts/mercury/dependencies/jquery.htmlClean.js +527 -0
- data/vendor/assets/javascripts/mercury/dependencies/liquidmetal.js +88 -0
- data/vendor/assets/javascripts/mercury/dependencies/showdown.js +1340 -0
- data/vendor/assets/javascripts/mercury/dialog.js.coffee +159 -0
- data/vendor/assets/javascripts/mercury/dialogs/backcolor.js.coffee +6 -0
- data/vendor/assets/javascripts/mercury/dialogs/forecolor.js.coffee +6 -0
- data/vendor/assets/javascripts/mercury/dialogs/formatblock.js.coffee +4 -0
- data/vendor/assets/javascripts/mercury/dialogs/snippetpanel.js.coffee +10 -0
- data/vendor/assets/javascripts/mercury/dialogs/style.js.coffee +4 -0
- data/vendor/assets/javascripts/mercury/finalize.js.coffee +3 -0
- data/vendor/assets/javascripts/mercury/history_buffer.js.coffee +30 -0
- data/vendor/assets/javascripts/mercury/lightview.js.coffee +205 -0
- data/vendor/assets/javascripts/mercury/locales/ar.locale.js.coffee +207 -0
- data/vendor/assets/javascripts/mercury/locales/da.locale.js.coffee +211 -0
- data/vendor/assets/javascripts/mercury/locales/de.locale.js.coffee +206 -0
- data/vendor/assets/javascripts/mercury/locales/es.locale.js.coffee +211 -0
- data/vendor/assets/javascripts/mercury/locales/example.local.js.coffee +211 -0
- data/vendor/assets/javascripts/mercury/locales/fr.locale.js.coffee +211 -0
- data/vendor/assets/javascripts/mercury/locales/it.locale.js.coffee +208 -0
- data/vendor/assets/javascripts/mercury/locales/ko.local.js.coffee +206 -0
- data/vendor/assets/javascripts/mercury/locales/nl.locale.js.coffee +206 -0
- data/vendor/assets/javascripts/mercury/locales/pt.locale.js.coffee +211 -0
- data/vendor/assets/javascripts/mercury/locales/sv.local.js.coffee +209 -0
- data/vendor/assets/javascripts/mercury/locales/swedish_chef.locale.js.coffee +213 -0
- data/vendor/assets/javascripts/mercury/mercury.js.coffee +109 -0
- data/vendor/assets/javascripts/mercury/modal.js.coffee +198 -0
- data/vendor/assets/javascripts/mercury/modals/htmleditor.js.coffee +11 -0
- data/vendor/assets/javascripts/mercury/modals/insertcharacter.js.coffee +4 -0
- data/vendor/assets/javascripts/mercury/modals/insertlink.js.coffee +92 -0
- data/vendor/assets/javascripts/mercury/modals/insertmedia.js.coffee +81 -0
- data/vendor/assets/javascripts/mercury/modals/insertsnippet.js.coffee +12 -0
- data/vendor/assets/javascripts/mercury/modals/inserttable.js.coffee +54 -0
- data/vendor/assets/javascripts/mercury/native_extensions.js.coffee +55 -0
- data/vendor/assets/javascripts/mercury/page_editor.js.coffee +225 -0
- data/vendor/assets/javascripts/mercury/palette.js.coffee +29 -0
- data/vendor/assets/javascripts/mercury/panel.js.coffee +115 -0
- data/vendor/assets/javascripts/mercury/plugins/save_as_xml/mercury/page_editor.js.coffee +28 -0
- data/vendor/assets/javascripts/mercury/plugins/save_as_xml/plugin.js +9 -0
- data/vendor/assets/javascripts/mercury/region.js.coffee +107 -0
- data/vendor/assets/javascripts/mercury/regions/editable.js.coffee +600 -0
- data/vendor/assets/javascripts/mercury/regions/image.js.coffee +114 -0
- data/vendor/assets/javascripts/mercury/regions/markupable.js.coffee +398 -0
- data/vendor/assets/javascripts/mercury/regions/simple.js.coffee +325 -0
- data/vendor/assets/javascripts/mercury/regions/snippetable.js.coffee +124 -0
- data/vendor/assets/javascripts/mercury/select.js.coffee +44 -0
- data/vendor/assets/javascripts/mercury/snippet.js.coffee +106 -0
- data/vendor/assets/javascripts/mercury/snippet_toolbar.js.coffee +72 -0
- data/vendor/assets/javascripts/mercury/statusbar.js.coffee +51 -0
- data/vendor/assets/javascripts/mercury/support/history.js +1 -0
- data/vendor/assets/javascripts/mercury/table_editor.js.coffee +265 -0
- data/vendor/assets/javascripts/mercury/toolbar.button.js.coffee +173 -0
- data/vendor/assets/javascripts/mercury/toolbar.button_group.js.coffee +42 -0
- data/vendor/assets/javascripts/mercury/toolbar.expander.js.coffee +56 -0
- data/vendor/assets/javascripts/mercury/toolbar.js.coffee +86 -0
- data/vendor/assets/javascripts/mercury/tooltip.js.coffee +74 -0
- data/vendor/assets/javascripts/mercury/uploader.js.coffee +244 -0
- data/vendor/assets/javascripts/mercury_loader.js +193 -0
- data/vendor/assets/javascripts/mercury_overrides.js +6 -0
- data/vendor/assets/stylesheets/mercury.css +28 -0
- data/vendor/assets/stylesheets/mercury/all_images.css.erb +89 -0
- data/vendor/assets/stylesheets/mercury/dialog.css +212 -0
- data/vendor/assets/stylesheets/mercury/form.css +118 -0
- data/vendor/assets/stylesheets/mercury/lightview.css +151 -0
- data/vendor/assets/stylesheets/mercury/mercury.css +37 -0
- data/vendor/assets/stylesheets/mercury/modal.css +183 -0
- data/vendor/assets/stylesheets/mercury/statusbar.css +32 -0
- data/vendor/assets/stylesheets/mercury/toolbar.css +304 -0
- data/vendor/assets/stylesheets/mercury/tooltip.css +26 -0
- data/vendor/assets/stylesheets/mercury/uploader.css +111 -0
- data/vendor/assets/stylesheets/mercury_overrides.css +17 -0
- metadata +572 -0
@@ -0,0 +1,110 @@
|
|
1
|
+
@javascript
|
2
|
+
Feature:
|
3
|
+
As a content editor type person
|
4
|
+
In order to manage content
|
5
|
+
I should be able to insert different types of media
|
6
|
+
|
7
|
+
Background:
|
8
|
+
Given I am on an editable page
|
9
|
+
And the editor won't prompt when leaving the page
|
10
|
+
|
11
|
+
Scenario: A user can expect all this!
|
12
|
+
|
13
|
+
|
14
|
+
# Scenario: A user can insert and edit an image
|
15
|
+
Given the content of the editable region is simple content
|
16
|
+
And I make a selection
|
17
|
+
|
18
|
+
When I click on the "Insert Media" button
|
19
|
+
Then the modal window should be visible
|
20
|
+
And I should see "Insert Media (images and videos)" within the modal title
|
21
|
+
|
22
|
+
When I fill in "URL" with "/assets/mercury/temp-logo.png"
|
23
|
+
And press "Insert Media"
|
24
|
+
Then the contents of the editable region should be "this is <img src='/assets/mercury/temp-logo.png'> <b>content</b>"
|
25
|
+
And the modal window should not be visible
|
26
|
+
|
27
|
+
When I make a selection for "img"
|
28
|
+
And click on the "Insert Media" button
|
29
|
+
Then the "media_image_url" field should contain "/assets/mercury/temp-logo.png"
|
30
|
+
|
31
|
+
When I fill in "URL" with "/assets/mercury/default-snippet.png"
|
32
|
+
And press "Insert Media"
|
33
|
+
Then the contents of the editable region should be "this is <img src='/assets/mercury/default-snippet.png'> <b>content</b>"
|
34
|
+
|
35
|
+
|
36
|
+
# Scenario: A user can insert and edit an image with an alignment set
|
37
|
+
Given the content of the editable region is simple content
|
38
|
+
And I make a selection
|
39
|
+
|
40
|
+
When I click on the "Insert Media" button
|
41
|
+
When I fill in "media_image_url" with "/assets/mercury/temp-logo.png"
|
42
|
+
And select "Right" from "Alignment"
|
43
|
+
And press "Insert Media"
|
44
|
+
Then the contents of the editable region should be "this is <img src='/assets/mercury/temp-logo.png' align='right'> <b>content</b>"
|
45
|
+
|
46
|
+
When I make a selection for "img"
|
47
|
+
And click on the "Insert Media" button
|
48
|
+
And select "Absolute Middle" from "Alignment"
|
49
|
+
And press "Insert Media"
|
50
|
+
Then the contents of the editable region should be "this is <img src='/assets/mercury/temp-logo.png' align='absmiddle'> <b>content</b>"
|
51
|
+
|
52
|
+
|
53
|
+
Scenario: A user can edit an image by double clicking it
|
54
|
+
Given the content of the editable region has an image
|
55
|
+
|
56
|
+
When I double click on the first image in the editable region
|
57
|
+
Then the modal window should be visible
|
58
|
+
And I should see "Insert Media (images and videos)" within the modal title
|
59
|
+
And the "media_image_url" field should contain "/assets/mercury/temp-logo.png"
|
60
|
+
|
61
|
+
When I fill in "URL" with "/assets/mercury/default-snippet.png"
|
62
|
+
And select "Absolute Middle" from "Alignment"
|
63
|
+
And press "Insert Media"
|
64
|
+
Then the contents of the editable region should be "this is <img src='/assets/mercury/default-snippet.png' align='absmiddle'> <b>content</b>"
|
65
|
+
|
66
|
+
|
67
|
+
Scenario: A user can embed and edit a youtube video
|
68
|
+
Given the content of the editable region is simple content
|
69
|
+
And I make a selection
|
70
|
+
|
71
|
+
When I click on the "Insert Media" button
|
72
|
+
And choose "YouTube Share URL"
|
73
|
+
And fill in "YouTube Share URL" with "http://youtu.be/Pny4hoN8eII"
|
74
|
+
And fill in "Width" with "400"
|
75
|
+
And fill in "Height" with "200"
|
76
|
+
And press "Insert Media"
|
77
|
+
Then the contents of the editable region should be "this is <iframe allowfullscreen='true' src='http://www.youtube.com/embed/Pny4hoN8eII?wmode=transparent' style='width: 400px; height: 200px;' frameborder='0'></iframe> <b>content</b>"
|
78
|
+
|
79
|
+
When I make a selection for "iframe"
|
80
|
+
And click on the "Insert Media" button
|
81
|
+
Then the "media_youtube_url" field should contain "http://youtu.be/Pny4hoN8eII"
|
82
|
+
|
83
|
+
When I fill in "YouTube Share URL" with "http://youtu.be/Pny4hoN8eI"
|
84
|
+
And fill in "Width" with "500"
|
85
|
+
And fill in "Height" with "300"
|
86
|
+
And press "Insert Media"
|
87
|
+
Then the contents of the editable region should be "this is <iframe allowfullscreen='true' src='http://www.youtube.com/embed/Pny4hoN8eI?wmode=transparent' style='width: 500px; height: 300px;' frameborder='0'></iframe> <b>content</b>"
|
88
|
+
|
89
|
+
|
90
|
+
# Scenario: A user can embed and edit a vimeo video
|
91
|
+
Given the content of the editable region is simple content
|
92
|
+
And I make a selection
|
93
|
+
|
94
|
+
When I click on the "Insert Media" button
|
95
|
+
And choose "Vimeo URL"
|
96
|
+
And fill in "Vimeo URL" with "http://vimeo.com/25708134"
|
97
|
+
And fill in "Width" with "400"
|
98
|
+
And fill in "Height" with "200"
|
99
|
+
And press "Insert Media"
|
100
|
+
Then the contents of the editable region should be "this is <iframe src='http://player.vimeo.com/video/25708134?title=1&byline=1&portrait=0&color=ffffff' style='width: 400px; height: 200px;' frameborder='0'></iframe> <b>content</b>"
|
101
|
+
|
102
|
+
When I make a selection for "iframe"
|
103
|
+
And click on the "Insert Media" button
|
104
|
+
Then the "media_vimeo_url" field should contain "http://vimeo.com/25708134"
|
105
|
+
|
106
|
+
When I fill in "Vimeo URL" with "http://vimeo.com/2570813"
|
107
|
+
And fill in "Width" with "500"
|
108
|
+
And fill in "Height" with "300"
|
109
|
+
And press "Insert Media"
|
110
|
+
Then the contents of the editable region should be "this is <iframe src='http://player.vimeo.com/video/2570813?title=1&byline=1&portrait=0&color=ffffff' style='width: 500px; height: 300px;' frameborder='0'></iframe> <b>content</b>"
|
@@ -0,0 +1,102 @@
|
|
1
|
+
@javascript
|
2
|
+
Feature:
|
3
|
+
As a content editor type person
|
4
|
+
In order to reuse content chunks
|
5
|
+
I should be able to put snippets into regions
|
6
|
+
|
7
|
+
Background:
|
8
|
+
Given I am on an editable page
|
9
|
+
And the editor won't prompt when leaving the page
|
10
|
+
|
11
|
+
Scenario: A user can expect all this!
|
12
|
+
|
13
|
+
|
14
|
+
# todo: these can't be one scenario because snippet.load doesn't find/replace existing ones
|
15
|
+
Scenario: A user can drag and drop snippets into an editable region
|
16
|
+
Given the content of the editable region is simple content
|
17
|
+
And I make a selection
|
18
|
+
|
19
|
+
When I open the snippet panel
|
20
|
+
And I drag the example snippet into the editable region
|
21
|
+
Then the modal window should be visible
|
22
|
+
And I should see "Snippet Options" within the modal title
|
23
|
+
|
24
|
+
When I fill in "First Name" with "Jeremy"
|
25
|
+
And fill in "Favorite Beer" with "Stella"
|
26
|
+
And press "Insert Snippet"
|
27
|
+
Then the modal window should not be visible
|
28
|
+
And the contents of the editable region should be "this is <div data-version='1' data-snippet='snippet_14' class='mercury-snippet example-snippet' contenteditable='false'><strong>Jeremy</strong> likes Stella</div><span>simple</span> <b>content</b>"
|
29
|
+
|
30
|
+
|
31
|
+
Scenario: A user can use the snippet toolbar to remove a snippet
|
32
|
+
Given the options for the example snippet "snippet_42" are first_name: "Jeremy", favorite_beer: "Stella"
|
33
|
+
And the content of the editable region has that snippet
|
34
|
+
|
35
|
+
When I hover over the snippet
|
36
|
+
Then the snippet toolbar should be visible
|
37
|
+
|
38
|
+
When I click on the remove snippet toolbar button
|
39
|
+
Then the contents of the editable region should be " <b>content</b>"
|
40
|
+
|
41
|
+
|
42
|
+
Scenario: A user can use the snippet toolbar to edit the options of a snippet
|
43
|
+
Given the options for the example snippet "snippet_42" are first_name: "Hipsters", favorite_beer: "PBR"
|
44
|
+
And the content of the editable region has that snippet
|
45
|
+
|
46
|
+
When I hover over the snippet
|
47
|
+
And click on the edit snippet settings toolbar button
|
48
|
+
Then the modal window should be visible
|
49
|
+
And the "First Name" field should contain "Hipsters"
|
50
|
+
And the "Favorite Beer" field should contain "PBR"
|
51
|
+
|
52
|
+
When I fill in "First Name" with "Jeremy"
|
53
|
+
And fill in "Favorite Beer" with "Stella"
|
54
|
+
And press "Insert Snippet"
|
55
|
+
Then the contents of the editable region should be "<div data-version='2' data-snippet='snippet_42' class='mercury-snippet example-snippet' contenteditable='false'><strong>Jeremy</strong> likes Stella</div> <b>content</b>"
|
56
|
+
|
57
|
+
|
58
|
+
Scenario: A user can make changes to a snippets options, and they'll be versioned for undo and redo
|
59
|
+
Given the options for the example snippet "snippet_42" are first_name: "Hipsters", favorite_beer: "PBR"
|
60
|
+
And the content of the editable region has that snippet
|
61
|
+
|
62
|
+
When I edit the snippet
|
63
|
+
And I fill in "First Name" with "Jeremy"
|
64
|
+
And fill in "Favorite Beer" with "Stella"
|
65
|
+
And press "Insert Snippet"
|
66
|
+
Then the contents of the editable region should be "<div data-version='2' data-snippet='snippet_42' class='mercury-snippet example-snippet' contenteditable='false'><strong>Jeremy</strong> likes Stella</div> <b>content</b>"
|
67
|
+
|
68
|
+
When I edit the snippet
|
69
|
+
Then the "First Name" field should contain "Jeremy"
|
70
|
+
And the "Favorite Beer" field should contain "Stella"
|
71
|
+
|
72
|
+
When fill in "First Name" with "Diesel"
|
73
|
+
And fill in "Favorite Beer" with "Bells Hopslam"
|
74
|
+
And press "Insert Snippet"
|
75
|
+
Then the content of the editable region should be "<div data-version='3' data-snippet='snippet_42' class='mercury-snippet example-snippet' contenteditable='false'><strong>Diesel</strong> likes Bells Hopslam</div> <b>content</b>"
|
76
|
+
|
77
|
+
When I click on the "Undo" button
|
78
|
+
Then the contents of the editable region should be "<div data-version='2' data-snippet='snippet_42' class='mercury-snippet example-snippet' contenteditable='false'><strong>Jeremy</strong> likes Stella</div> <b>content</b>"
|
79
|
+
|
80
|
+
When I edit the snippet
|
81
|
+
# todo: this is a bug
|
82
|
+
# Then the "First Name" field should contain "Jeremy"
|
83
|
+
# And the "Favorite Beer" field should contain "Stella"
|
84
|
+
|
85
|
+
When I close the modal
|
86
|
+
When I click on the "Redo" button
|
87
|
+
Then the contents of the editable region should be "<div data-version='3' data-snippet='snippet_42' class='mercury-snippet example-snippet' contenteditable='false'><strong>Diesel</strong> likes Bells Hopslam</div> <b>content</b>"
|
88
|
+
|
89
|
+
When I edit the snippet
|
90
|
+
Then the "First Name" field should contain "Diesel"
|
91
|
+
And the "Favorite Beer" field should contain "Bells Hopslam"
|
92
|
+
|
93
|
+
When I fill in "First Name" with "Jen"
|
94
|
+
And fill in "Favorite Beer" with "Miller High Life"
|
95
|
+
And press "Insert Snippet"
|
96
|
+
Then the contents of the editable region should be "<div data-version='4' data-snippet='snippet_42' class='mercury-snippet example-snippet' contenteditable='false'><strong>Jen</strong> likes Miller High Life</div> <b>content</b>"
|
97
|
+
|
98
|
+
|
99
|
+
# Scenario: When a user saves, the snippets should be gone from the html, but the options are serialized
|
100
|
+
# Given the options for the example snippet "snippet_42" are first_name: "Hipsters", favorite_beer: "PBR"
|
101
|
+
# And the content of the editable region has that snippet
|
102
|
+
# When I click on the "Save" button
|
@@ -0,0 +1,24 @@
|
|
1
|
+
@javascript
|
2
|
+
Feature:
|
3
|
+
As a content editor type person
|
4
|
+
In order to manage content
|
5
|
+
I should be able to insert characters that are otherwise hard
|
6
|
+
|
7
|
+
Background:
|
8
|
+
Given I am on an editable page
|
9
|
+
And the editor won't prompt when leaving the page
|
10
|
+
|
11
|
+
Scenario: A user can expect all this!
|
12
|
+
|
13
|
+
|
14
|
+
# Scenario: A user can insert special characters
|
15
|
+
Given the content of the editable region is simple content
|
16
|
+
And I make a selection
|
17
|
+
|
18
|
+
When I click on the "Insert Character" button
|
19
|
+
Then the modal window should be visible
|
20
|
+
And I should see "Special Characters" within the modal title
|
21
|
+
|
22
|
+
When I click on the sweet snowman
|
23
|
+
Then the modal window should not be visible
|
24
|
+
And the contents of the editable region should be "this is ☃ <b>content</b>"
|
@@ -0,0 +1,109 @@
|
|
1
|
+
@javascript
|
2
|
+
Feature:
|
3
|
+
As a content editor type person
|
4
|
+
In order to manage content
|
5
|
+
I should be able to insert and edit complex tables
|
6
|
+
|
7
|
+
Background:
|
8
|
+
Given I am on an editable page
|
9
|
+
And the editor won't prompt when leaving the page
|
10
|
+
|
11
|
+
Scenario: A user can expect all this!
|
12
|
+
|
13
|
+
|
14
|
+
# Scenario: A user can insert a table
|
15
|
+
Given the content of the editable region is simple content
|
16
|
+
And I make a selection
|
17
|
+
|
18
|
+
When I click on the "Insert Table" button
|
19
|
+
Then the modal window should be visible
|
20
|
+
And I should see "Insert Table" within the modal title
|
21
|
+
|
22
|
+
When I click on the third cell in the first row
|
23
|
+
And I add a column before it
|
24
|
+
Then the table column count should be 4
|
25
|
+
And the selected cell should be the forth cell in the first row
|
26
|
+
|
27
|
+
When I add a column after
|
28
|
+
Then the table column count should be 5
|
29
|
+
And the selected cell should be the forth cell in the first row
|
30
|
+
|
31
|
+
When I add a row after
|
32
|
+
Then the table row count should be 3
|
33
|
+
And the selected cell should be the forth cell in the first row
|
34
|
+
|
35
|
+
When I add a row before
|
36
|
+
Then the table row count should be 4
|
37
|
+
And the selected cell should be the forth cell in the second row
|
38
|
+
|
39
|
+
When I delete the column
|
40
|
+
Then the table column count should be 4
|
41
|
+
And a selected cell should not be visible
|
42
|
+
|
43
|
+
When I click on the second cell in the second row
|
44
|
+
And delete the row
|
45
|
+
Then the table row count should be 3
|
46
|
+
And a selected cell should not be visible
|
47
|
+
|
48
|
+
When I click on the second cell in the second row
|
49
|
+
And increase the colspan
|
50
|
+
And click on the first cell in the first row
|
51
|
+
And increase the rowspan
|
52
|
+
And select "Right" from "Alignment"
|
53
|
+
And fill in "Border" with "2"
|
54
|
+
And fill in "Spacing" with "2"
|
55
|
+
And press "Insert Table"
|
56
|
+
Then the contents of the editable region should be "this is <table align='right' border='2' cellspacing='2'><tbody><tr><td rowspan='2'><br></td><td><br></td><td><br></td><td><br></td></tr><tr><td colspan='2'><br></td><td><br></td></tr><tr><td><br></td><td><br></td><td><br></td><td><br></td></tr></tbody></table> <b>content</b>"
|
57
|
+
And the modal window should not be visible
|
58
|
+
|
59
|
+
|
60
|
+
# Scenario: A user can edit a table after inserting one (in an editable region)
|
61
|
+
Given the content of the editable region has a table
|
62
|
+
And I make a selection
|
63
|
+
|
64
|
+
When I click on the add row before editor button
|
65
|
+
Then the table row count should be 3
|
66
|
+
And the contents of the editable region should be "this is a <table><tbody><tr><td><br></td><td><br></td></tr><tr><td><span>1</span></td><td><span>2</span></td></tr><tr><td><span>3</span></td><td><span>4</span></td></tr></tbody></table> <b>content</b>"
|
67
|
+
|
68
|
+
When I click on the add row after editor button
|
69
|
+
Then the table row count should be 4
|
70
|
+
And the contents of the editable region should be "this is a <table><tbody><tr><td><br></td><td><br></td></tr><tr><td><span>1</span></td><td><span>2</span></td></tr><tr><td><br></td><td><br></td></tr><tr><td><span>3</span></td><td><span>4</span></td></tr></tbody></table> <b>content</b>"
|
71
|
+
|
72
|
+
When I click on the add column before editor button
|
73
|
+
Then the column count should be 3
|
74
|
+
And the contents of the editable region should be "this is a <table><tbody><tr><td><br></td><td><br></td><td><br></td></tr><tr><td><br></td><td><span>1</span></td><td><span>2</span></td></tr><tr><td><br></td><td><br></td><td><br></td></tr><tr><td><br></td><td><span>3</span></td><td><span>4</span></td></tr></tbody></table> <b>content</b>"
|
75
|
+
|
76
|
+
When I click on the add column after editor button
|
77
|
+
Then the column count should be 4
|
78
|
+
And the contents of the editable region should be "this is a <table><tbody><tr><td><br></td><td><br></td><td><br></td><td><br></td></tr><tr><td><br></td><td><span>1</span></td><td><br></td><td><span>2</span></td></tr><tr><td><br></td><td><br></td><td><br></td><td><br></td></tr><tr><td><br></td><td><span>3</span></td><td><br></td><td><span>4</span></td></tr></tbody></table> <b>content</b>"
|
79
|
+
|
80
|
+
When I click on the delete row editor button
|
81
|
+
Then the table row count should be 3
|
82
|
+
And the contents of the editable region should be "this is a <table><tbody><tr><td><br></td><td><br></td><td><br></td><td><br></td></tr><tr><td><br></td><td><br></td><td><br></td><td><br></td></tr><tr><td><br></td><td><span>3</span></td><td><br></td><td><span>4</span></td></tr></tbody></table> <b>content</b>"
|
83
|
+
|
84
|
+
When I make a selection
|
85
|
+
And click on the delete column editor button
|
86
|
+
Then the table column count should be 3
|
87
|
+
And the contents of the editable region should be "this is a <table><tbody><tr><td><br></td><td><br></td><td><br></td></tr><tr><td><br></td><td><br></td><td><br></td></tr><tr><td><br></td><td><br></td><td><span>4</span></td></tr></tbody></table> <b>content</b>"
|
88
|
+
|
89
|
+
|
90
|
+
# Scenario: A user can adjust the colspans of a table (in an editable region)
|
91
|
+
Given the content of the editable region has a table
|
92
|
+
And I make a selection
|
93
|
+
|
94
|
+
When I click on the increase colspan editor button
|
95
|
+
Then the contents of the editable region should be "this is a <table><tbody><tr><td colspan='2'><span>1</span></td></tr><tr><td><span>3</span></td><td><span>4</span></td></tr></tbody></table> <b>content</b>"
|
96
|
+
|
97
|
+
When I click on the decrease colspan editor button
|
98
|
+
Then the contents of the editable region should be "this is a <table><tbody><tr><td><span>1</span></td><td><br></td></tr><tr><td><span>3</span></td><td><span>4</span></td></tr></tbody></table> <b>content</b>"
|
99
|
+
|
100
|
+
|
101
|
+
# Scenario: A user can adjust the rowspans of a table (in an editable region)
|
102
|
+
Given the content of the editable region has a table
|
103
|
+
And I make a selection
|
104
|
+
|
105
|
+
When I click on the increase rowspan editor button
|
106
|
+
Then the contents of the editable region should be "this is a <table><tbody><tr><td rowspan='2'><span>1</span></td><td><span>2</span></td></tr><tr><td><span>4</span></td></tr></tbody></table> <b>content</b>"
|
107
|
+
|
108
|
+
When I click on the decrease rowspan editor button
|
109
|
+
Then the contents of the editable region should be "this is a <table><tbody><tr><td><span>1</span></td><td><span>2</span></td></tr><tr><td><br></td><td><span>4</span></td></tr></tbody></table> <b>content</b>"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,33 @@
|
|
1
|
+
@javascript
|
2
|
+
Feature:
|
3
|
+
As a content editor type person
|
4
|
+
In order to manage content
|
5
|
+
I should be able to save the content
|
6
|
+
|
7
|
+
Background:
|
8
|
+
Given I am on an editable page
|
9
|
+
And save results will be cached
|
10
|
+
|
11
|
+
|
12
|
+
Scenario: A user can change content in an editable region and save those changes
|
13
|
+
When I set the content of the editable region to "new content"
|
14
|
+
And I click on the "Save" button
|
15
|
+
Then the save should have "new content" for the editable region
|
16
|
+
|
17
|
+
|
18
|
+
Scenario: A user can change content in a markupable region and save those changes
|
19
|
+
When I set the content of the markupable region to "new content"
|
20
|
+
And I click on the "Save" button
|
21
|
+
Then the save should have "new content" for the markupable region
|
22
|
+
|
23
|
+
|
24
|
+
Scenario: A user can put snippets into an editable region and get the options on save
|
25
|
+
# todo: finish
|
26
|
+
|
27
|
+
|
28
|
+
Scenario: A user can expect the right version of the snippet options to be saved
|
29
|
+
# todo: finish
|
30
|
+
|
31
|
+
|
32
|
+
Scenario: A user can put snippets into a markupable region and get the options on save
|
33
|
+
# todo: finish
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# DEBUG / DELAY STEPS
|
2
|
+
#------------------------------------------------------------------------------
|
3
|
+
|
4
|
+
When /^(?:|I )sleep for (\d+) seconds?$/ do |seconds|
|
5
|
+
sleep(seconds.to_i)
|
6
|
+
end
|
7
|
+
|
8
|
+
When /^I debug$/ do
|
9
|
+
puts 'Debugging...'
|
10
|
+
unless ENV['RUBYMINE'].present?
|
11
|
+
require 'debug'
|
12
|
+
debugger
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,438 @@
|
|
1
|
+
## Generic web steps
|
2
|
+
#------------------------------------------------------------------------------
|
3
|
+
When /^(?:|I )click on (.+)$/ do |locator|
|
4
|
+
selector = selector_for(locator)
|
5
|
+
find(selector, :message => "Unable to locate the element '#{selector}' to click on").click
|
6
|
+
end
|
7
|
+
|
8
|
+
Then /^(.+) should (not )?be visible$/ do |locator, boolean|
|
9
|
+
selector = selector_for(locator)
|
10
|
+
if boolean == 'not '
|
11
|
+
page.has_no_css?("#{selector}")
|
12
|
+
else
|
13
|
+
page.has_css?("#{selector}", :visible => true)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# scoping step for different windows
|
18
|
+
When /^(.*) in the "([^"]*)" window$/ do |s, window|
|
19
|
+
page.driver.within_window(window) do
|
20
|
+
step(s)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
## Mercury general steps
|
26
|
+
#------------------------------------------------------------------------------
|
27
|
+
Given /^(?:|I )adjust the configuration to have: \{([^\}]*)\}$/ do |javascript|
|
28
|
+
Rails.application.config.mercury_config = JSON.parse("{#{javascript}}")
|
29
|
+
end
|
30
|
+
|
31
|
+
# scoping step for the mercury content frame
|
32
|
+
When /^(.*) in the content frame$/ do |s|
|
33
|
+
page.driver.within_frame('mercury_iframe') do
|
34
|
+
step(s)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# silence mercury's onbeforeunload confirmation
|
39
|
+
Given /^the editor won't prompt when leaving the page$/ do
|
40
|
+
page.driver.execute_script('Mercury.silent = true;')
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
## Toolbar specific steps
|
45
|
+
#------------------------------------------------------------------------------
|
46
|
+
# for the select dropdowns
|
47
|
+
When /^(?:|I )select (.*?) from the dropdown$/ do |locator|
|
48
|
+
selector = selector_for(locator)
|
49
|
+
find(selector, :message => "Unable to locate the element '#{selector}' to click on").click
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
## Panel specific steps
|
54
|
+
#------------------------------------------------------------------------------
|
55
|
+
When /^(?:I )(?:open|close|toggle) the (.*?) panel$/ do |panel_locator|
|
56
|
+
step(%Q{I click on the "#{panel_locator}" button})
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
## Modal specific steps
|
61
|
+
#------------------------------------------------------------------------------
|
62
|
+
When /^(?:I )close the modal(?: window)?$/ do
|
63
|
+
step(%Q{I click on the modal close button})
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
## Region specific steps
|
68
|
+
#------------------------------------------------------------------------------
|
69
|
+
# setting content
|
70
|
+
Given /^the content of (.*?) (?:is|are|has|includes) (.*?)$/ do |region_locator, contents|
|
71
|
+
step(%Q{I set the contents of #{region_locator} to #{contents}})
|
72
|
+
end
|
73
|
+
|
74
|
+
When /^(?:|I )(?:change|set) the contents? of (.*?) to (.*?)$/ do |region_locator, contents|
|
75
|
+
region_id = region_selector_for(region_locator).gsub('#', '')
|
76
|
+
content = contents[0] == '"' ? contents : "\"#{contents_for(contents)}\""
|
77
|
+
page.driver.within_frame('mercury_iframe') do
|
78
|
+
find("##{region_id}", :message => "Unable to locate a region matching '##{region_id}'")
|
79
|
+
page.driver.execute_script <<-JAVASCRIPT
|
80
|
+
var element = top.jQuery(document).find('##{region_id}');
|
81
|
+
if (element.data('type') == 'markupable') {
|
82
|
+
element.find('textarea').val(#{content});
|
83
|
+
} else {
|
84
|
+
var region = top.mercuryInstance.getRegionByName('#{region_id}');
|
85
|
+
region.content(#{content});
|
86
|
+
}
|
87
|
+
JAVASCRIPT
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# setting/making selections
|
92
|
+
When /^(?:|I )(?:make|have) a selection$/ do
|
93
|
+
step(%Q{I have a selection for "span"})
|
94
|
+
end
|
95
|
+
|
96
|
+
When /^(?:|I )(?:make|have) a selection (?:in (.*?) )?for "([^"]*)"$/ do |region_locator, selector|
|
97
|
+
step(%Q{I can simulate complex javascript events})
|
98
|
+
# assume the first editable region if one wasn't provided'
|
99
|
+
region_selector = region_selector_for(region_locator || 'the editable region')
|
100
|
+
page.driver.within_frame('mercury_iframe') do
|
101
|
+
find("#{region_selector}", :message => "Unable to locate a region matching '#{region_selector}'")
|
102
|
+
find("#{region_selector} #{selector}", :message => "Unable to locate a match for '#{selector}' inside '#{region_locator}'")
|
103
|
+
page.driver.execute_script <<-JAVASCRIPT
|
104
|
+
var element = top.jQuery(document).find('#{region_selector}');
|
105
|
+
if (element.data('type') == 'markupable') {
|
106
|
+
alert('unimplemented');
|
107
|
+
throw('unimplemented');
|
108
|
+
} else {
|
109
|
+
var selectedElement = element.find('#{selector}');
|
110
|
+
var selection = new top.Mercury.Regions.Editable.Selection(window.getSelection(), document);
|
111
|
+
selection.selectNode(selectedElement.get(0));
|
112
|
+
selectedElement.simulate('mouseup');
|
113
|
+
}
|
114
|
+
JAVASCRIPT
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# other events
|
119
|
+
When /^(?:|I )double click on (.*?) in (.*?)$/ do |locator, region_locator|
|
120
|
+
step(%Q{I can simulate complex javascript events})
|
121
|
+
selector = selector_for(locator)
|
122
|
+
# assume the first editable region if one wasn't provided'
|
123
|
+
region_selector = region_selector_for(region_locator || 'the editable region')
|
124
|
+
page.driver.within_frame('mercury_iframe') do
|
125
|
+
find("#{region_selector}", :message => "Unable to locate a region matching '#{region_selector}'")
|
126
|
+
find("#{region_selector} #{selector}", :message => "Unable to locate a match for '#{selector}' inside '#{region_locator}'")
|
127
|
+
page.driver.execute_script <<-JAVASCRIPT
|
128
|
+
top.jQuery(document).find('#{region_selector} #{selector}').simulate('dblclick');
|
129
|
+
JAVASCRIPT
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# getting contents
|
134
|
+
Then /^the contents? of (.*?) should be "([^"]*)"$/ do |region_locator, content|
|
135
|
+
region_selector = region_selector_for(region_locator)
|
136
|
+
page.driver.within_frame('mercury_iframe') do
|
137
|
+
find("#{region_selector}", :message => "Unable to locate a region matching '#{region_selector}'")
|
138
|
+
results = page.driver.execute_script <<-JAVASCRIPT
|
139
|
+
var element = top.jQuery(document).find('#{region_selector}');
|
140
|
+
if (element.data('type') == 'markupable') {
|
141
|
+
return element.find('textarea').val();
|
142
|
+
} else {
|
143
|
+
return element.html();
|
144
|
+
}
|
145
|
+
JAVASCRIPT
|
146
|
+
assert_equal content, results.gsub('"', "'").gsub("\n", '')
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
## Saving specific steps
|
152
|
+
#------------------------------------------------------------------------------
|
153
|
+
# caching for the last save -- a request will still be made
|
154
|
+
Given /^save results will be cached$/ do
|
155
|
+
page.driver.execute_script <<-JAVASCRIPT
|
156
|
+
Mercury.PageEditor.prototype.save = function() {
|
157
|
+
window.cachedResults = this.serialize();
|
158
|
+
}
|
159
|
+
JAVASCRIPT
|
160
|
+
end
|
161
|
+
|
162
|
+
# check for the last save cached results
|
163
|
+
Then /^the save should have (.*?) for (.*?)$/ do |contents, region_locator|
|
164
|
+
region_id = region_selector_for(region_locator).gsub('#', '')
|
165
|
+
content = contents[0] == '"' ? contents : "\"#{contents_for(contents)}\""
|
166
|
+
results = page.driver.execute_script <<-JAVASCRIPT
|
167
|
+
return (window.cachedResults['#{region_id}']) ?
|
168
|
+
window.cachedResults['#{region_id}']['value'] : null;
|
169
|
+
JAVASCRIPT
|
170
|
+
assert_equal content, "\"#{results}\""
|
171
|
+
end
|
172
|
+
|
173
|
+
|
174
|
+
## Table editing specific steps
|
175
|
+
#------------------------------------------------------------------------------
|
176
|
+
# in the modal window
|
177
|
+
When /^(?:|I )(?:add|insert) a (row|column) (before|after)(?: it)?$/ do |row_or_column, before_or_after|
|
178
|
+
name = "insert_#{row_or_column}_#{before_or_after}".camelcase(:lower)
|
179
|
+
step(%Q{I click on ".mercury-modal-content input[name=#{name}]"})
|
180
|
+
end
|
181
|
+
|
182
|
+
When /^(?:|I )delete the(?: current)? (row|column)$/ do |row_or_column|
|
183
|
+
name = "delete_#{row_or_column}".camelcase(:lower)
|
184
|
+
step(%Q{I click on ".mercury-modal-content input[name=#{name}]"})
|
185
|
+
end
|
186
|
+
|
187
|
+
When /^(?:|I )(increase|decrease) the (rowspan|colspan)$/ do |increase_or_decrease, rowspan_or_colspan|
|
188
|
+
name = "#{increase_or_decrease}_#{rowspan_or_colspan}".camelcase(:lower)
|
189
|
+
step(%Q{I click on ".mercury-modal-content input[name=#{name}]"})
|
190
|
+
end
|
191
|
+
|
192
|
+
Then /^the selected cell should be (.*?)$/ do |locator|
|
193
|
+
selector = selector_for(locator).gsub('td:', 'td.selected:')
|
194
|
+
find("#{selector}", :message => "Unable to locate the selected cell for '#{selector}'")
|
195
|
+
end
|
196
|
+
|
197
|
+
# in general
|
198
|
+
Then /^the(?: table)? (row|column) count should be (\d+)$/ do |row_or_column, expected_count|
|
199
|
+
method = "get_#{row_or_column}_count".camelcase(:lower)
|
200
|
+
actual_count = page.driver.execute_script("return Mercury.tableEditor.#{method}()")
|
201
|
+
assert_equal expected_count.to_i, actual_count.to_i
|
202
|
+
end
|
203
|
+
|
204
|
+
|
205
|
+
## Snippet specific steps
|
206
|
+
#------------------------------------------------------------------------------
|
207
|
+
# setting snippet options
|
208
|
+
Given /^the options for the (.*?) snippet "([^"]*)" are (.*?)$/ do |snippet_name, snippet_id, options|
|
209
|
+
@snippet_id = snippet_id
|
210
|
+
options_json = parse_snippet_options_from(options)
|
211
|
+
page.driver.execute_script <<-JAVASCRIPT
|
212
|
+
Mercury.Snippet.load({#{snippet_id}: {name: '#{snippet_name}', options: #{options_json}}});
|
213
|
+
JAVASCRIPT
|
214
|
+
end
|
215
|
+
|
216
|
+
# dragging/dropping
|
217
|
+
When /^(?:|I )(?:drag|drop) (.*?) (?:into|on) (.*?)$/ do |snippet_locator, region_locator|
|
218
|
+
snippet_name = snippet_name_for(snippet_locator)
|
219
|
+
region_id = region_selector_for(region_locator).gsub('#', '')
|
220
|
+
page.driver.within_frame('mercury_iframe') do
|
221
|
+
find("##{region_id}", :message => "Unable to locate a region matching '##{region_id}'")
|
222
|
+
page.driver.execute_script <<-JAVASCRIPT
|
223
|
+
var element = top.jQuery(document).find('##{region_id}');
|
224
|
+
if (element.data('type') == 'markupable') {
|
225
|
+
alert('unimplemented');
|
226
|
+
throw('unimplemented');
|
227
|
+
} else {
|
228
|
+
var region = top.mercuryInstance.getRegionByName('#{region_id}');
|
229
|
+
region.selection().range.collapse(true);
|
230
|
+
document.execCommand('insertHTML', false, '<img data-snippet="#{snippet_name}" src="/assets/mercury/default-snippet.png">');
|
231
|
+
element.trigger('possible:drop');
|
232
|
+
}
|
233
|
+
JAVASCRIPT
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
When /^(?:|I )hover over (.*?)(?: in (.*?))?$/ do |locator, region_locator|
|
238
|
+
step(%Q{I can simulate complex javascript events})
|
239
|
+
selector = selector_for(locator)
|
240
|
+
region_selector = region_selector_for(region_locator || 'the editable region')
|
241
|
+
page.driver.within_frame('mercury_iframe') do
|
242
|
+
find("#{region_selector}", :message => "Unable to locate a region matching '#{region_selector}'")
|
243
|
+
page.driver.execute_script <<-JAVASCRIPT
|
244
|
+
var element = top.jQuery(document).find('#{region_selector}');
|
245
|
+
if (element.data('type') == 'markupable') {
|
246
|
+
alert('unimplemented');
|
247
|
+
throw('unimplemented');
|
248
|
+
} else {
|
249
|
+
element.find('#{selector}').simulate('mousemove');
|
250
|
+
}
|
251
|
+
JAVASCRIPT
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
When /^(?:|I )edit the snippet$/ do
|
256
|
+
step(%{I hover over the snippet})
|
257
|
+
step(%{click on the edit snippet settings toolbar button})
|
258
|
+
end
|
259
|
+
|
260
|
+
|
261
|
+
## Dropping image specific steps
|
262
|
+
#------------------------------------------------------------------------------
|
263
|
+
#When /^(?:|I )drop an image into (.*?) from a different browser/ do |region_locator|
|
264
|
+
# Given(%Q{I can simulate complex javascript events})
|
265
|
+
# region_selector = region_selector_for(region_locator || 'the editable region')
|
266
|
+
# page.driver.within_frame('mercury_iframe') do
|
267
|
+
# find("#{region_selector}", :message => "Unable to locate a region matching '#{region_selector}'")
|
268
|
+
# page.driver.execute_script <<-JAVASCRIPT
|
269
|
+
# var element = top.jQuery(document).find('#{region_selector}');
|
270
|
+
# if (element.data('type') == 'markupable') {
|
271
|
+
# alert('unimplemented');
|
272
|
+
# throw('unimplemented');
|
273
|
+
# } else {
|
274
|
+
# element.find('#{region_selector}').simulate('drop', {'text/html': '<img src="testing.gif"/>'});
|
275
|
+
# }
|
276
|
+
# JAVASCRIPT
|
277
|
+
# end
|
278
|
+
#end
|
279
|
+
|
280
|
+
|
281
|
+
## Javascript event simulation steps
|
282
|
+
#------------------------------------------------------------------------------
|
283
|
+
Given /^(?:|I )can simulate complex javascript events$/ do
|
284
|
+
page.driver.execute_script(EVENT_SIMULATION_JAVASCRIPT)
|
285
|
+
end
|
286
|
+
|
287
|
+
#------------------------------------------------------------------------------
|
288
|
+
|
289
|
+
EVENT_SIMULATION_JAVASCRIPT = <<-JAVASCRIPT
|
290
|
+
/*
|
291
|
+
* jquery.simulate - simulate browser mouse and keyboard events
|
292
|
+
*
|
293
|
+
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
294
|
+
* Dual licensed under the MIT or GPL Version 2 licenses.
|
295
|
+
* http://jquery.org/license
|
296
|
+
*
|
297
|
+
*/
|
298
|
+
;(function($) {
|
299
|
+
|
300
|
+
$.fn.extend({
|
301
|
+
simulate: function(type, options) {
|
302
|
+
return this.each(function() {
|
303
|
+
var opt = $.extend({}, $.simulate.defaults, options || {});
|
304
|
+
new $.simulate(this, type, opt);
|
305
|
+
});
|
306
|
+
}
|
307
|
+
});
|
308
|
+
|
309
|
+
$.simulate = function(el, type, options) {
|
310
|
+
this.target = el;
|
311
|
+
this.options = options;
|
312
|
+
|
313
|
+
if (/^drag$/.test(type)) {
|
314
|
+
this[type].apply(this, [this.target, options]);
|
315
|
+
} else {
|
316
|
+
this.simulateEvent(el, type, options);
|
317
|
+
}
|
318
|
+
}
|
319
|
+
|
320
|
+
$.extend($.simulate.prototype, {
|
321
|
+
simulateEvent: function(el, type, options) {
|
322
|
+
var evt = this.createEvent(type, options);
|
323
|
+
this.dispatchEvent(el, type, evt, options);
|
324
|
+
return evt;
|
325
|
+
},
|
326
|
+
createEvent: function(type, options) {
|
327
|
+
if (/^mouse(over|out|down|up|move)|(dbl)?click$/.test(type)) {
|
328
|
+
return this.mouseEvent(type, options);
|
329
|
+
} else if (/^key(up|down|press)$/.test(type)) {
|
330
|
+
return this.keyboardEvent(type, options);
|
331
|
+
}
|
332
|
+
},
|
333
|
+
mouseEvent: function(type, options) {
|
334
|
+
var evt;
|
335
|
+
var e = $.extend({
|
336
|
+
bubbles: true, cancelable: (type != "mousemove"), view: window, detail: 0,
|
337
|
+
screenX: 0, screenY: 0, clientX: 0, clientY: 0,
|
338
|
+
ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
|
339
|
+
button: 0, relatedTarget: undefined
|
340
|
+
}, options);
|
341
|
+
|
342
|
+
var relatedTarget = $(e.relatedTarget)[0];
|
343
|
+
|
344
|
+
if ($.isFunction(document.createEvent)) {
|
345
|
+
evt = document.createEvent("MouseEvents");
|
346
|
+
evt.initMouseEvent(type, e.bubbles, e.cancelable, e.view, e.detail,
|
347
|
+
e.screenX, e.screenY, e.clientX, e.clientY,
|
348
|
+
e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,
|
349
|
+
e.button, e.relatedTarget || document.body.parentNode);
|
350
|
+
} else if (document.createEventObject) {
|
351
|
+
evt = document.createEventObject();
|
352
|
+
$.extend(evt, e);
|
353
|
+
evt.button = { 0:1, 1:4, 2:2 }[evt.button] || evt.button;
|
354
|
+
}
|
355
|
+
return evt;
|
356
|
+
},
|
357
|
+
keyboardEvent: function(type, options) {
|
358
|
+
var evt;
|
359
|
+
|
360
|
+
var e = $.extend({ bubbles: true, cancelable: true, view: window,
|
361
|
+
ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
|
362
|
+
keyCode: 0, charCode: 0
|
363
|
+
}, options);
|
364
|
+
|
365
|
+
if ($.isFunction(document.createEvent)) {
|
366
|
+
try {
|
367
|
+
evt = document.createEvent("KeyEvents");
|
368
|
+
evt.initKeyEvent(type, e.bubbles, e.cancelable, e.view,
|
369
|
+
e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,
|
370
|
+
e.keyCode, e.charCode);
|
371
|
+
} catch(err) {
|
372
|
+
evt = document.createEvent("Events");
|
373
|
+
evt.initEvent(type, e.bubbles, e.cancelable);
|
374
|
+
$.extend(evt, { view: e.view,
|
375
|
+
ctrlKey: e.ctrlKey, altKey: e.altKey, shiftKey: e.shiftKey, metaKey: e.metaKey,
|
376
|
+
keyCode: e.keyCode, charCode: e.charCode
|
377
|
+
});
|
378
|
+
}
|
379
|
+
} else if (document.createEventObject) {
|
380
|
+
evt = document.createEventObject();
|
381
|
+
$.extend(evt, e);
|
382
|
+
}
|
383
|
+
if ($.browser.msie || $.browser.opera) {
|
384
|
+
evt.keyCode = (e.charCode > 0) ? e.charCode : e.keyCode;
|
385
|
+
evt.charCode = undefined;
|
386
|
+
}
|
387
|
+
return evt;
|
388
|
+
},
|
389
|
+
dispatchEvent: function(el, type, evt) {
|
390
|
+
if (el.dispatchEvent) {
|
391
|
+
el.dispatchEvent(evt);
|
392
|
+
} else if (el.fireEvent) {
|
393
|
+
el.fireEvent('on' + type, evt);
|
394
|
+
}
|
395
|
+
return evt;
|
396
|
+
},
|
397
|
+
drag: function(el) {
|
398
|
+
var self = this, center = this.findCenter(this.target),
|
399
|
+
options = this.options, x = Math.floor(center.x), y = Math.floor(center.y),
|
400
|
+
dx = options.dx || 0, dy = options.dy || 0, target = this.target;
|
401
|
+
var coord = { clientX: x, clientY: y };
|
402
|
+
this.simulateEvent(target, "mousedown", coord);
|
403
|
+
coord = { clientX: x + 1, clientY: y + 1 };
|
404
|
+
this.simulateEvent(document, "mousemove", coord);
|
405
|
+
coord = { clientX: x + dx, clientY: y + dy };
|
406
|
+
this.simulateEvent(document, "mousemove", coord);
|
407
|
+
this.simulateEvent(document, "mousemove", coord);
|
408
|
+
this.simulateEvent(target, "mouseup", coord);
|
409
|
+
this.simulateEvent(target, "click", coord);
|
410
|
+
},
|
411
|
+
findCenter: function(el) {
|
412
|
+
var el = $(this.target), o = el.offset(), d = $(document);
|
413
|
+
return {
|
414
|
+
x: o.left + el.outerWidth() / 2 - d.scrollLeft(),
|
415
|
+
y: o.top + el.outerHeight() / 2 - d.scrollTop()
|
416
|
+
};
|
417
|
+
}
|
418
|
+
});
|
419
|
+
|
420
|
+
$.extend($.simulate, {
|
421
|
+
defaults: {
|
422
|
+
speed: 'sync'
|
423
|
+
},
|
424
|
+
VK_TAB: 9,
|
425
|
+
VK_ENTER: 13,
|
426
|
+
VK_ESC: 27,
|
427
|
+
VK_PGUP: 33,
|
428
|
+
VK_PGDN: 34,
|
429
|
+
VK_END: 35,
|
430
|
+
VK_HOME: 36,
|
431
|
+
VK_LEFT: 37,
|
432
|
+
VK_UP: 38,
|
433
|
+
VK_RIGHT: 39,
|
434
|
+
VK_DOWN: 40
|
435
|
+
});
|
436
|
+
|
437
|
+
})(jQuery);
|
438
|
+
JAVASCRIPT
|