summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml3
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock6
-rw-r--r--app/assets/javascripts/main.js3
-rw-r--r--app/assets/javascripts/test_utils/index.js4
-rw-r--r--app/assets/javascripts/test_utils/simulate_drag.js262
-rw-r--r--app/views/groups/milestones/show.html.haml4
-rw-r--r--app/views/projects/boards/_show.html.haml1
-rw-r--r--app/views/projects/labels/index.html.haml3
-rw-r--r--app/views/projects/milestones/show.html.haml3
-rw-r--r--config/webpack.config.js1
-rw-r--r--spec/features/milestones/milestones_spec.rb6
-rw-r--r--spec/support/drag_to_helper.rb4
13 files changed, 148 insertions, 154 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f2fb6d3101c..66f8b6e6f9a 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -8,6 +8,7 @@ cache:
variables:
MYSQL_ALLOW_EMPTY_PASSWORD: "1"
RAILS_ENV: "test"
+ NODE_ENV: "test"
SIMPLECOV: "true"
SETUP_DB: "true"
USE_BUNDLE_INSTALL: "true"
@@ -129,9 +130,7 @@ setup-test-env:
stage: prepare
script:
- node --version
- - yarn --version
- yarn install --pure-lockfile
- - yarn check # ensure that yarn.lock matches package.json
- bundle exec rake gitlab:assets:compile
- bundle exec ruby -Ispec -e 'require "spec_helper" ; TestEnv.init'
artifacts:
diff --git a/Gemfile b/Gemfile
index 910ab318227..6a45b3d7339 100644
--- a/Gemfile
+++ b/Gemfile
@@ -223,7 +223,7 @@ gem 'oj', '~> 2.17.4'
gem 'chronic', '~> 0.10.2'
gem 'chronic_duration', '~> 0.10.6'
-gem 'webpack-rails', '~> 0.9.9'
+gem 'webpack-rails', '~> 0.9.10'
gem 'rack-proxy', '~> 0.6.0'
gem 'sass-rails', '~> 5.0.6'
diff --git a/Gemfile.lock b/Gemfile.lock
index 304fc9f2bb3..50ca9af7a7a 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -823,8 +823,8 @@ GEM
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff
- webpack-rails (0.9.9)
- rails (>= 3.2.0)
+ webpack-rails (0.9.10)
+ railties (>= 3.2.0)
websocket-driver (0.6.3)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.2)
@@ -1026,7 +1026,7 @@ DEPENDENCIES
virtus (~> 1.0.1)
vmstat (~> 2.3.0)
webmock (~> 1.24.0)
- webpack-rails (~> 0.9.9)
+ webpack-rails (~> 0.9.10)
wikicloth (= 0.8.1)
BUNDLED WITH
diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js
index 665a59f3183..5b50bc62876 100644
--- a/app/assets/javascripts/main.js
+++ b/app/assets/javascripts/main.js
@@ -187,6 +187,9 @@ import './visibility_select';
import './wikis';
import './zen_mode';
+// eslint-disable-next-line global-require
+if (process.env.NODE_ENV !== 'production') require('./test_utils/');
+
document.addEventListener('beforeunload', function () {
// Unbind scroll events
$(document).off('scroll');
diff --git a/app/assets/javascripts/test_utils/index.js b/app/assets/javascripts/test_utils/index.js
new file mode 100644
index 00000000000..ef401abce2d
--- /dev/null
+++ b/app/assets/javascripts/test_utils/index.js
@@ -0,0 +1,4 @@
+import simulateDrag from './simulate_drag';
+
+// Export to global space for rspec to use
+window.simulateDrag = simulateDrag;
diff --git a/app/assets/javascripts/test_utils/simulate_drag.js b/app/assets/javascripts/test_utils/simulate_drag.js
index d48f2404fa5..e39213cb098 100644
--- a/app/assets/javascripts/test_utils/simulate_drag.js
+++ b/app/assets/javascripts/test_utils/simulate_drag.js
@@ -1,143 +1,137 @@
-/* eslint-disable wrap-iife, func-names, strict, no-var, vars-on-top, no-param-reassign, object-shorthand, no-shadow, comma-dangle, prefer-template, consistent-return, no-mixed-operators, no-unused-vars, no-unused-expressions, prefer-arrow-callback, max-len */
-(function () {
- 'use strict';
-
- function simulateEvent(el, type, options) {
- var event;
- if (!el) return;
- var ownerDocument = el.ownerDocument;
-
- options = options || {};
-
- if (/^mouse/.test(type)) {
- event = ownerDocument.createEvent('MouseEvents');
- event.initMouseEvent(type, true, true, ownerDocument.defaultView,
- options.button, options.screenX, options.screenY, options.clientX, options.clientY,
- options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, el);
- } else {
- event = ownerDocument.createEvent('CustomEvent');
-
- event.initCustomEvent(type, true, true, ownerDocument.defaultView,
- options.button, options.screenX, options.screenY, options.clientX, options.clientY,
- options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, el);
-
- event.dataTransfer = {
- data: {},
-
- setData: function (type, val) {
- this.data[type] = val;
- },
-
- getData: function (type) {
- return this.data[type];
- }
- };
- }
-
- if (el.dispatchEvent) {
- el.dispatchEvent(event);
- } else if (el.fireEvent) {
- el.fireEvent('on' + type, event);
- }
-
- return event;
- }
-
- function isLast(target) {
- var el = typeof target.el === 'string' ? document.getElementById(target.el.substr(1)) : target.el;
- var children = el.children;
-
- return children.length - 1 === target.index;
+function simulateEvent(el, type, options = {}) {
+ let event;
+ if (!el) return null;
+
+ if (/^mouse/.test(type)) {
+ event = el.ownerDocument.createEvent('MouseEvents');
+ event.initMouseEvent(type, true, true, el.ownerDocument.defaultView,
+ options.button, options.screenX, options.screenY, options.clientX, options.clientY,
+ options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, el);
+ } else {
+ event = el.ownerDocument.createEvent('CustomEvent');
+
+ event.initCustomEvent(type, true, true, el.ownerDocument.defaultView,
+ options.button, options.screenX, options.screenY, options.clientX, options.clientY,
+ options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, el);
+
+ event.dataTransfer = {
+ data: {},
+
+ setData(key, val) {
+ this.data[key] = val;
+ },
+
+ getData(key) {
+ return this.data[key];
+ },
+ };
}
- function getTarget(target) {
- var el = typeof target.el === 'string' ? document.getElementById(target.el.substr(1)) : target.el;
- var children = el.children;
-
- return (
- children[target.index] ||
- children[target.index === 'first' ? 0 : -1] ||
- children[target.index === 'last' ? children.length - 1 : -1] ||
- el
- );
+ if (el.dispatchEvent) {
+ el.dispatchEvent(event);
+ } else if (el.fireEvent) {
+ el.fireEvent(`on${type}`, event);
}
- function getRect(el) {
- var rect = el.getBoundingClientRect();
- var width = rect.right - rect.left;
- var height = rect.bottom - rect.top + 10;
-
- return {
- x: rect.left,
- y: rect.top,
- cx: rect.left + width / 2,
- cy: rect.top + height / 2,
- w: width,
- h: height,
- hw: width / 2,
- wh: height / 2
- };
+ return event;
+}
+
+function isLast(target) {
+ const el = typeof target.el === 'string' ? document.getElementById(target.el.substr(1)) : target.el;
+ const children = el.children;
+
+ return children.length - 1 === target.index;
+}
+
+function getTarget(target) {
+ const el = typeof target.el === 'string' ? document.getElementById(target.el.substr(1)) : target.el;
+ const children = el.children;
+
+ return (
+ children[target.index] ||
+ children[target.index === 'first' ? 0 : -1] ||
+ children[target.index === 'last' ? children.length - 1 : -1] ||
+ el
+ );
+}
+
+function getRect(el) {
+ const rect = el.getBoundingClientRect();
+ const width = rect.right - rect.left;
+ const height = (rect.bottom - rect.top) + 10;
+
+ return {
+ x: rect.left,
+ y: rect.top,
+ cx: rect.left + (width / 2),
+ cy: rect.top + (height / 2),
+ w: width,
+ h: height,
+ hw: width / 2,
+ wh: height / 2,
+ };
+}
+
+export default function simulateDrag(options) {
+ const { to, from } = options;
+ to.el = to.el || from.el;
+
+ const fromEl = getTarget(from);
+ const toEl = getTarget(to);
+ const firstEl = getTarget({
+ el: to.el,
+ index: 'first',
+ });
+ const lastEl = getTarget({
+ el: options.to.el,
+ index: 'last',
+ });
+
+ const fromRect = getRect(fromEl);
+ const toRect = getRect(toEl);
+ const firstRect = getRect(firstEl);
+ const lastRect = getRect(lastEl);
+
+ const startTime = new Date().getTime();
+ const duration = options.duration || 1000;
+
+ simulateEvent(fromEl, 'mousedown', {
+ button: 0,
+ clientX: fromRect.cx,
+ clientY: fromRect.cy,
+ });
+
+ if (options.ontap) options.ontap();
+ window.SIMULATE_DRAG_ACTIVE = 1;
+
+ if (options.to.index === 0) {
+ toRect.cy = firstRect.y;
+ } else if (isLast(options.to)) {
+ toRect.cy = lastRect.y + lastRect.h + 50;
}
- function simulateDrag(options, callback) {
- options.to.el = options.to.el || options.from.el;
+ const dragInterval = setInterval(() => {
+ const progress = (new Date().getTime() - startTime) / duration;
+ const x = (fromRect.cx + ((toRect.cx - fromRect.cx) * progress));
+ const y = (fromRect.cy + ((toRect.cy - fromRect.cy) * progress));
+ const overEl = fromEl.ownerDocument.elementFromPoint(x, y);
- var fromEl = getTarget(options.from);
- var toEl = getTarget(options.to);
- var firstEl = getTarget({
- el: options.to.el,
- index: 'first'
+ simulateEvent(overEl, 'mousemove', {
+ clientX: x,
+ clientY: y,
});
- var lastEl = getTarget({
- el: options.to.el,
- index: 'last'
- });
- var scrollable = options.scrollable;
-
- var fromRect = getRect(fromEl);
- var toRect = getRect(toEl);
- var firstRect = getRect(firstEl);
- var lastRect = getRect(lastEl);
-
- var startTime = new Date().getTime();
- var duration = options.duration || 1000;
- simulateEvent(fromEl, 'mousedown', { button: 0 });
- options.ontap && options.ontap();
- window.SIMULATE_DRAG_ACTIVE = 1;
-
- if (options.to.index === 0) {
- toRect.cy = firstRect.y;
- } else if (isLast(options.to)) {
- toRect.cy = lastRect.y + lastRect.h + 50;
- }
- var dragInterval = setInterval(function loop() {
- var progress = (new Date().getTime() - startTime) / duration;
- var x = (fromRect.cx + (toRect.cx - fromRect.cx) * progress) - scrollable.scrollLeft;
- var y = (fromRect.cy + (toRect.cy - fromRect.cy) * progress) - scrollable.scrollTop;
- var overEl = fromEl.ownerDocument.elementFromPoint(x, y);
-
- simulateEvent(overEl, 'mousemove', {
- clientX: x,
- clientY: y
- });
-
- if (progress >= 1) {
- options.ondragend && options.ondragend();
- simulateEvent(toEl, 'mouseup');
- clearInterval(dragInterval);
- window.SIMULATE_DRAG_ACTIVE = 0;
- }
- }, 100);
-
- return {
- target: fromEl,
- fromList: fromEl.parentNode,
- toList: toEl.parentNode
- };
- }
-
- // Export
- window.simulateEvent = simulateEvent;
- window.simulateDrag = simulateDrag;
-})();
+ if (progress >= 1) {
+ if (options.ondragend) options.ondragend();
+ simulateEvent(toEl, 'mouseup');
+ clearInterval(dragInterval);
+ window.SIMULATE_DRAG_ACTIVE = 0;
+ }
+ }, 100);
+
+ return {
+ target: fromEl,
+ fromList: fromEl.parentNode,
+ toList: toEl.parentNode,
+ };
+}
diff --git a/app/views/groups/milestones/show.html.haml b/app/views/groups/milestones/show.html.haml
index 8e83b2002b2..33e68bc766e 100644
--- a/app/views/groups/milestones/show.html.haml
+++ b/app/views/groups/milestones/show.html.haml
@@ -1,8 +1,4 @@
= render "header_title"
-
-- content_for :page_specific_javascripts do
- = page_specific_javascript_bundle_tag('simulate_drag') if Rails.env.test?
-
= render 'shared/milestones/top', milestone: @milestone, group: @group
= render 'shared/milestones/tabs', milestone: @milestone, show_project_name: true
= render 'shared/milestones/sidebar', milestone: @milestone, affix_offset: 102
diff --git a/app/views/projects/boards/_show.html.haml b/app/views/projects/boards/_show.html.haml
index added3f669b..d93eac63bd3 100644
--- a/app/views/projects/boards/_show.html.haml
+++ b/app/views/projects/boards/_show.html.haml
@@ -6,7 +6,6 @@
= page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('filtered_search')
= page_specific_javascript_bundle_tag('boards')
- = page_specific_javascript_bundle_tag('simulate_drag') if Rails.env.test?
%script#js-board-template{ type: "text/x-template" }= render "projects/boards/components/board"
%script#js-board-list-template{ type: "text/x-template" }= render "projects/boards/components/board_list"
diff --git a/app/views/projects/labels/index.html.haml b/app/views/projects/labels/index.html.haml
index 8d4a91cb64c..29f861c09c6 100644
--- a/app/views/projects/labels/index.html.haml
+++ b/app/views/projects/labels/index.html.haml
@@ -3,9 +3,6 @@
- hide_class = ''
= render "projects/issues/head"
-- content_for :page_specific_javascripts do
- = page_specific_javascript_bundle_tag('simulate_drag') if Rails.env.test?
-
- if @labels.exists? || @prioritized_labels.exists?
%div{ class: container_class }
.top-area.adjust
diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml
index f612b5c7d6b..5249d752585 100644
--- a/app/views/projects/milestones/show.html.haml
+++ b/app/views/projects/milestones/show.html.haml
@@ -3,9 +3,6 @@
- page_description @milestone.description
= render "projects/issues/head"
-- content_for :page_specific_javascripts do
- = page_specific_javascript_bundle_tag('simulate_drag') if Rails.env.test?
-
%div{ class: container_class }
.detail-page-header.milestone-page-header
.status-box{ class: status_box_class(@milestone) }
diff --git a/config/webpack.config.js b/config/webpack.config.js
index 70d98b022c1..728c2a64053 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -23,7 +23,6 @@ var config = {
main: './main.js',
blob: './blob_edit/blob_bundle.js',
boards: './boards/boards_bundle.js',
- simulate_drag: './test_utils/simulate_drag.js',
cycle_analytics: './cycle_analytics/cycle_analytics_bundle.js',
commit_pipelines: './commit/pipelines/pipelines_bundle.js',
diff_notes: './diff_notes/diff_notes_bundle.js',
diff --git a/spec/features/milestones/milestones_spec.rb b/spec/features/milestones/milestones_spec.rb
index 8de9942c54e..2fa3e72ab08 100644
--- a/spec/features/milestones/milestones_spec.rb
+++ b/spec/features/milestones/milestones_spec.rb
@@ -76,6 +76,7 @@ describe 'Milestone draggable', feature: true, js: true do
create(:issue, params.merge(title: 'Foo', project: project, milestone: milestone))
visit namespace_project_milestone_path(project.namespace, project, milestone)
+ scroll_into_view('.milestone-content')
drag_to(selector: '.issues-sortable-list', list_to_index: 1)
wait_for_ajax
@@ -86,8 +87,13 @@ describe 'Milestone draggable', feature: true, js: true do
visit namespace_project_milestone_path(project.namespace, project, milestone)
page.find("a[href='#tab-merge-requests']").click
+ scroll_into_view('.milestone-content')
drag_to(selector: '.merge_requests-sortable-list', list_to_index: 1)
wait_for_ajax
end
+
+ def scroll_into_view(selector)
+ page.evaluate_script("document.querySelector('#{selector}').scrollIntoView();")
+ end
end
diff --git a/spec/support/drag_to_helper.rb b/spec/support/drag_to_helper.rb
index 0c0659d3ecd..ae149631ed9 100644
--- a/spec/support/drag_to_helper.rb
+++ b/spec/support/drag_to_helper.rb
@@ -3,11 +3,11 @@ module DragTo
evaluate_script("simulateDrag({scrollable: $('#{scrollable}').get(0), from: {el: $('#{selector}').eq(#{list_from_index}).get(0), index: #{from_index}}, to: {el: $('#{selector}').eq(#{list_to_index}).get(0), index: #{to_index}}});")
Timeout.timeout(Capybara.default_max_wait_time) do
- loop until drag_active?
+ loop while drag_active?
end
end
def drag_active?
- page.evaluate_script('window.SIMULATE_DRAG_ACTIVE').zero?
+ page.evaluate_script('window.SIMULATE_DRAG_ACTIVE').nonzero?
end
end