Commit 0a4b853f authored by Clement Ho's avatar Clement Ho

Merge branch 'refactor_simulate_drag' into 'master'

Refactor test_utils bundle

See merge request !10437
parents d8cbe979 4461e708
...@@ -8,6 +8,7 @@ cache: ...@@ -8,6 +8,7 @@ cache:
variables: variables:
MYSQL_ALLOW_EMPTY_PASSWORD: "1" MYSQL_ALLOW_EMPTY_PASSWORD: "1"
RAILS_ENV: "test" RAILS_ENV: "test"
NODE_ENV: "test"
SIMPLECOV: "true" SIMPLECOV: "true"
SETUP_DB: "true" SETUP_DB: "true"
USE_BUNDLE_INSTALL: "true" USE_BUNDLE_INSTALL: "true"
...@@ -129,9 +130,7 @@ setup-test-env: ...@@ -129,9 +130,7 @@ setup-test-env:
stage: prepare stage: prepare
script: script:
- node --version - node --version
- yarn --version
- yarn install --pure-lockfile - yarn install --pure-lockfile
- yarn check # ensure that yarn.lock matches package.json
- bundle exec rake gitlab:assets:compile - bundle exec rake gitlab:assets:compile
- bundle exec ruby -Ispec -e 'require "spec_helper" ; TestEnv.init' - bundle exec ruby -Ispec -e 'require "spec_helper" ; TestEnv.init'
artifacts: artifacts:
......
...@@ -223,7 +223,7 @@ gem 'oj', '~> 2.17.4' ...@@ -223,7 +223,7 @@ gem 'oj', '~> 2.17.4'
gem 'chronic', '~> 0.10.2' gem 'chronic', '~> 0.10.2'
gem 'chronic_duration', '~> 0.10.6' 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 'rack-proxy', '~> 0.6.0'
gem 'sass-rails', '~> 5.0.6' gem 'sass-rails', '~> 5.0.6'
......
...@@ -823,8 +823,8 @@ GEM ...@@ -823,8 +823,8 @@ GEM
addressable (>= 2.3.6) addressable (>= 2.3.6)
crack (>= 0.3.2) crack (>= 0.3.2)
hashdiff hashdiff
webpack-rails (0.9.9) webpack-rails (0.9.10)
rails (>= 3.2.0) railties (>= 3.2.0)
websocket-driver (0.6.3) websocket-driver (0.6.3)
websocket-extensions (>= 0.1.0) websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.2) websocket-extensions (0.1.2)
...@@ -1026,7 +1026,7 @@ DEPENDENCIES ...@@ -1026,7 +1026,7 @@ DEPENDENCIES
virtus (~> 1.0.1) virtus (~> 1.0.1)
vmstat (~> 2.3.0) vmstat (~> 2.3.0)
webmock (~> 1.24.0) webmock (~> 1.24.0)
webpack-rails (~> 0.9.9) webpack-rails (~> 0.9.10)
wikicloth (= 0.8.1) wikicloth (= 0.8.1)
BUNDLED WITH BUNDLED WITH
......
...@@ -187,6 +187,9 @@ import './visibility_select'; ...@@ -187,6 +187,9 @@ import './visibility_select';
import './wikis'; import './wikis';
import './zen_mode'; import './zen_mode';
// eslint-disable-next-line global-require
if (process.env.NODE_ENV !== 'production') require('./test_utils/');
document.addEventListener('beforeunload', function () { document.addEventListener('beforeunload', function () {
// Unbind scroll events // Unbind scroll events
$(document).off('scroll'); $(document).off('scroll');
......
import simulateDrag from './simulate_drag';
// Export to global space for rspec to use
window.simulateDrag = simulateDrag;
/* 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 simulateEvent(el, type, options = {}) {
(function () { let event;
'use strict'; if (!el) return null;
function simulateEvent(el, type, options) {
var event;
if (!el) return;
var ownerDocument = el.ownerDocument;
options = options || {};
if (/^mouse/.test(type)) { if (/^mouse/.test(type)) {
event = ownerDocument.createEvent('MouseEvents'); event = el.ownerDocument.createEvent('MouseEvents');
event.initMouseEvent(type, true, true, ownerDocument.defaultView, event.initMouseEvent(type, true, true, el.ownerDocument.defaultView,
options.button, options.screenX, options.screenY, options.clientX, options.clientY, options.button, options.screenX, options.screenY, options.clientX, options.clientY,
options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, el); options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, el);
} else { } else {
event = ownerDocument.createEvent('CustomEvent'); event = el.ownerDocument.createEvent('CustomEvent');
event.initCustomEvent(type, true, true, ownerDocument.defaultView, event.initCustomEvent(type, true, true, el.ownerDocument.defaultView,
options.button, options.screenX, options.screenY, options.clientX, options.clientY, options.button, options.screenX, options.screenY, options.clientX, options.clientY,
options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, el); options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, el);
event.dataTransfer = { event.dataTransfer = {
data: {}, data: {},
setData: function (type, val) { setData(key, val) {
this.data[type] = val; this.data[key] = val;
}, },
getData: function (type) { getData(key) {
return this.data[type]; return this.data[key];
} },
}; };
} }
if (el.dispatchEvent) { if (el.dispatchEvent) {
el.dispatchEvent(event); el.dispatchEvent(event);
} else if (el.fireEvent) { } else if (el.fireEvent) {
el.fireEvent('on' + type, event); el.fireEvent(`on${type}`, event);
} }
return event; return event;
} }
function isLast(target) { function isLast(target) {
var el = typeof target.el === 'string' ? document.getElementById(target.el.substr(1)) : target.el; const el = typeof target.el === 'string' ? document.getElementById(target.el.substr(1)) : target.el;
var children = el.children; const children = el.children;
return children.length - 1 === target.index; return children.length - 1 === target.index;
} }
function getTarget(target) { function getTarget(target) {
var el = typeof target.el === 'string' ? document.getElementById(target.el.substr(1)) : target.el; const el = typeof target.el === 'string' ? document.getElementById(target.el.substr(1)) : target.el;
var children = el.children; const children = el.children;
return ( return (
children[target.index] || children[target.index] ||
...@@ -60,49 +53,55 @@ ...@@ -60,49 +53,55 @@
children[target.index === 'last' ? children.length - 1 : -1] || children[target.index === 'last' ? children.length - 1 : -1] ||
el el
); );
} }
function getRect(el) { function getRect(el) {
var rect = el.getBoundingClientRect(); const rect = el.getBoundingClientRect();
var width = rect.right - rect.left; const width = rect.right - rect.left;
var height = rect.bottom - rect.top + 10; const height = (rect.bottom - rect.top) + 10;
return { return {
x: rect.left, x: rect.left,
y: rect.top, y: rect.top,
cx: rect.left + width / 2, cx: rect.left + (width / 2),
cy: rect.top + height / 2, cy: rect.top + (height / 2),
w: width, w: width,
h: height, h: height,
hw: width / 2, hw: width / 2,
wh: height / 2 wh: height / 2,
}; };
} }
function simulateDrag(options, callback) { export default function simulateDrag(options) {
options.to.el = options.to.el || options.from.el; const { to, from } = options;
to.el = to.el || from.el;
var fromEl = getTarget(options.from); const fromEl = getTarget(from);
var toEl = getTarget(options.to); const toEl = getTarget(to);
var firstEl = getTarget({ const firstEl = getTarget({
el: options.to.el, el: to.el,
index: 'first' index: 'first',
}); });
var lastEl = getTarget({ const lastEl = getTarget({
el: options.to.el, el: options.to.el,
index: 'last' index: 'last',
}); });
var scrollable = options.scrollable;
var fromRect = getRect(fromEl); const fromRect = getRect(fromEl);
var toRect = getRect(toEl); const toRect = getRect(toEl);
var firstRect = getRect(firstEl); const firstRect = getRect(firstEl);
var lastRect = getRect(lastEl); const lastRect = getRect(lastEl);
var startTime = new Date().getTime(); const startTime = new Date().getTime();
var duration = options.duration || 1000; const duration = options.duration || 1000;
simulateEvent(fromEl, 'mousedown', { button: 0 });
options.ontap && options.ontap(); simulateEvent(fromEl, 'mousedown', {
button: 0,
clientX: fromRect.cx,
clientY: fromRect.cy,
});
if (options.ontap) options.ontap();
window.SIMULATE_DRAG_ACTIVE = 1; window.SIMULATE_DRAG_ACTIVE = 1;
if (options.to.index === 0) { if (options.to.index === 0) {
...@@ -111,19 +110,19 @@ ...@@ -111,19 +110,19 @@
toRect.cy = lastRect.y + lastRect.h + 50; toRect.cy = lastRect.y + lastRect.h + 50;
} }
var dragInterval = setInterval(function loop() { const dragInterval = setInterval(() => {
var progress = (new Date().getTime() - startTime) / duration; const progress = (new Date().getTime() - startTime) / duration;
var x = (fromRect.cx + (toRect.cx - fromRect.cx) * progress) - scrollable.scrollLeft; const x = (fromRect.cx + ((toRect.cx - fromRect.cx) * progress));
var y = (fromRect.cy + (toRect.cy - fromRect.cy) * progress) - scrollable.scrollTop; const y = (fromRect.cy + ((toRect.cy - fromRect.cy) * progress));
var overEl = fromEl.ownerDocument.elementFromPoint(x, y); const overEl = fromEl.ownerDocument.elementFromPoint(x, y);
simulateEvent(overEl, 'mousemove', { simulateEvent(overEl, 'mousemove', {
clientX: x, clientX: x,
clientY: y clientY: y,
}); });
if (progress >= 1) { if (progress >= 1) {
options.ondragend && options.ondragend(); if (options.ondragend) options.ondragend();
simulateEvent(toEl, 'mouseup'); simulateEvent(toEl, 'mouseup');
clearInterval(dragInterval); clearInterval(dragInterval);
window.SIMULATE_DRAG_ACTIVE = 0; window.SIMULATE_DRAG_ACTIVE = 0;
...@@ -133,11 +132,6 @@ ...@@ -133,11 +132,6 @@
return { return {
target: fromEl, target: fromEl,
fromList: fromEl.parentNode, fromList: fromEl.parentNode,
toList: toEl.parentNode toList: toEl.parentNode,
}; };
} }
// Export
window.simulateEvent = simulateEvent;
window.simulateDrag = simulateDrag;
})();
= render "header_title" = 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/top', milestone: @milestone, group: @group
= render 'shared/milestones/tabs', milestone: @milestone, show_project_name: true = render 'shared/milestones/tabs', milestone: @milestone, show_project_name: true
= render 'shared/milestones/sidebar', milestone: @milestone, affix_offset: 102 = render 'shared/milestones/sidebar', milestone: @milestone, affix_offset: 102
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
= page_specific_javascript_bundle_tag('common_vue') = page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('filtered_search') = page_specific_javascript_bundle_tag('filtered_search')
= page_specific_javascript_bundle_tag('boards') = 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-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" %script#js-board-list-template{ type: "text/x-template" }= render "projects/boards/components/board_list"
......
...@@ -3,9 +3,6 @@ ...@@ -3,9 +3,6 @@
- hide_class = '' - hide_class = ''
= render "projects/issues/head" = 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? - if @labels.exists? || @prioritized_labels.exists?
%div{ class: container_class } %div{ class: container_class }
.top-area.adjust .top-area.adjust
......
...@@ -3,9 +3,6 @@ ...@@ -3,9 +3,6 @@
- page_description @milestone.description - page_description @milestone.description
= render "projects/issues/head" = 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 } %div{ class: container_class }
.detail-page-header.milestone-page-header .detail-page-header.milestone-page-header
.status-box{ class: status_box_class(@milestone) } .status-box{ class: status_box_class(@milestone) }
......
...@@ -23,7 +23,6 @@ var config = { ...@@ -23,7 +23,6 @@ var config = {
main: './main.js', main: './main.js',
blob: './blob_edit/blob_bundle.js', blob: './blob_edit/blob_bundle.js',
boards: './boards/boards_bundle.js', boards: './boards/boards_bundle.js',
simulate_drag: './test_utils/simulate_drag.js',
cycle_analytics: './cycle_analytics/cycle_analytics_bundle.js', cycle_analytics: './cycle_analytics/cycle_analytics_bundle.js',
commit_pipelines: './commit/pipelines/pipelines_bundle.js', commit_pipelines: './commit/pipelines/pipelines_bundle.js',
diff_notes: './diff_notes/diff_notes_bundle.js', diff_notes: './diff_notes/diff_notes_bundle.js',
......
...@@ -76,6 +76,7 @@ describe 'Milestone draggable', feature: true, js: true do ...@@ -76,6 +76,7 @@ describe 'Milestone draggable', feature: true, js: true do
create(:issue, params.merge(title: 'Foo', project: project, milestone: milestone)) create(:issue, params.merge(title: 'Foo', project: project, milestone: milestone))
visit namespace_project_milestone_path(project.namespace, project, 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) drag_to(selector: '.issues-sortable-list', list_to_index: 1)
wait_for_ajax wait_for_ajax
...@@ -86,8 +87,13 @@ describe 'Milestone draggable', feature: true, js: true do ...@@ -86,8 +87,13 @@ describe 'Milestone draggable', feature: true, js: true do
visit namespace_project_milestone_path(project.namespace, project, milestone) visit namespace_project_milestone_path(project.namespace, project, milestone)
page.find("a[href='#tab-merge-requests']").click page.find("a[href='#tab-merge-requests']").click
scroll_into_view('.milestone-content')
drag_to(selector: '.merge_requests-sortable-list', list_to_index: 1) drag_to(selector: '.merge_requests-sortable-list', list_to_index: 1)
wait_for_ajax wait_for_ajax
end end
def scroll_into_view(selector)
page.evaluate_script("document.querySelector('#{selector}').scrollIntoView();")
end
end end
...@@ -3,11 +3,11 @@ module DragTo ...@@ -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}}});") 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 Timeout.timeout(Capybara.default_max_wait_time) do
loop until drag_active? loop while drag_active?
end end
end end
def drag_active? def drag_active?
page.evaluate_script('window.SIMULATE_DRAG_ACTIVE').zero? page.evaluate_script('window.SIMULATE_DRAG_ACTIVE').nonzero?
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment