Added simulate drag JS for tests
This commit is contained in:
parent
c7b210ebd7
commit
9172c45bdb
5 changed files with 218 additions and 4 deletions
121
app/assets/javascripts/boards/test_utils/simulate_drag.js
Executable file
121
app/assets/javascripts/boards/test_utils/simulate_drag.js
Executable file
|
@ -0,0 +1,121 @@
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
function simulateEvent(el, type, options) {
|
||||||
|
var event;
|
||||||
|
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 getTraget(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]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRect(el) {
|
||||||
|
var rect = el.getBoundingClientRect();
|
||||||
|
var width = rect.right - rect.left;
|
||||||
|
var height = rect.bottom - rect.top;
|
||||||
|
|
||||||
|
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
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function simulateDrag(options, callback) {
|
||||||
|
options.to.el = options.to.el || options.from.el;
|
||||||
|
|
||||||
|
var fromEl = getTraget(options.from);
|
||||||
|
var toEl = getTraget(options.to);
|
||||||
|
var scrollable = options.scrollable;
|
||||||
|
|
||||||
|
var fromRect = getRect(fromEl);
|
||||||
|
var toRect = getRect(toEl);
|
||||||
|
|
||||||
|
var startTime = new Date().getTime();
|
||||||
|
var duration = options.duration || 1000;
|
||||||
|
simulateEvent(fromEl, 'mousedown', {button: 0});
|
||||||
|
options.ontap && options.ontap();
|
||||||
|
|
||||||
|
requestAnimationFrame(function () {
|
||||||
|
options.ondragstart && options.ondragstart();
|
||||||
|
});
|
||||||
|
|
||||||
|
requestAnimationFrame(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;
|
||||||
|
var overEl = fromEl.ownerDocument.elementFromPoint(x, y);
|
||||||
|
|
||||||
|
simulateEvent(overEl, 'mousemove', {
|
||||||
|
clientX: x,
|
||||||
|
clientY: y
|
||||||
|
});
|
||||||
|
|
||||||
|
if (progress < 1) {
|
||||||
|
requestAnimationFrame(loop);
|
||||||
|
} else {
|
||||||
|
options.ondragend && options.ondragend();
|
||||||
|
simulateEvent(toEl, 'mouseup');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
target: fromEl,
|
||||||
|
fromList: fromEl.parentNode,
|
||||||
|
toList: toEl.parentNode
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Export
|
||||||
|
window.simulateEvent = simulateEvent;
|
||||||
|
window.simulateDrag = simulateDrag;
|
||||||
|
})();
|
|
@ -23,18 +23,33 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.issue-boards-page {
|
.issue-boards-page {
|
||||||
|
.content-wrapper {
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-nav,
|
||||||
|
.issues-filters {
|
||||||
|
-webkit-flex: none;
|
||||||
|
flex: none;
|
||||||
|
}
|
||||||
|
|
||||||
.page-with-sidebar {
|
.page-with-sidebar {
|
||||||
|
display: -webkit-flex;
|
||||||
display: flex;
|
display: flex;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
max-height: 100vh;
|
max-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.issue-boards-content {
|
.issue-boards-content {
|
||||||
|
display: -webkit-flex;
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100%;
|
width: 100%;
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
|
display: -webkit-flex;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
-webkit-flex-direction: column;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
@ -42,8 +57,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.boards-list {
|
.boards-list {
|
||||||
|
display: -webkit-flex;
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100%;
|
-webkit-flex: 1;
|
||||||
|
flex: 1;
|
||||||
min-height: 455px;
|
min-height: 455px;
|
||||||
padding-top: 25px;
|
padding-top: 25px;
|
||||||
padding-right: ($gl-padding / 2);
|
padding-right: ($gl-padding / 2);
|
||||||
|
@ -52,17 +69,19 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.board {
|
.board {
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: flex;
|
||||||
min-width: 400px;
|
min-width: 400px;
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
height: 100%;
|
|
||||||
padding-right: ($gl-padding / 2);
|
padding-right: ($gl-padding / 2);
|
||||||
padding-left: ($gl-padding / 2);
|
padding-left: ($gl-padding / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.board-inner {
|
.board-inner {
|
||||||
|
display: -webkit-flex;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
-webkit-flex-direction: column;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: $issue-boards-font-size;
|
font-size: $issue-boards-font-size;
|
||||||
background: $background-color;
|
background: $background-color;
|
||||||
|
@ -162,6 +181,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.board-list {
|
.board-list {
|
||||||
|
-webkit-flex: 1;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
- content_for :page_specific_javascripts do
|
- content_for :page_specific_javascripts do
|
||||||
= page_specific_javascript_tag('boards/boards_bundle.js')
|
= page_specific_javascript_tag('boards/boards_bundle.js')
|
||||||
|
= page_specific_javascript_tag('boards/test_utils/simulate_drag.js') if Rails.env.test?
|
||||||
|
|
||||||
= render "projects/issues/head"
|
= render "projects/issues/head"
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ module Gitlab
|
||||||
config.assets.precompile << "network/network_bundle.js"
|
config.assets.precompile << "network/network_bundle.js"
|
||||||
config.assets.precompile << "profile/profile_bundle.js"
|
config.assets.precompile << "profile/profile_bundle.js"
|
||||||
config.assets.precompile << "boards/boards_bundle.js"
|
config.assets.precompile << "boards/boards_bundle.js"
|
||||||
|
config.assets.precompile << "boards/test_utils/simulate_drag.js"
|
||||||
config.assets.precompile << "lib/utils/*.js"
|
config.assets.precompile << "lib/utils/*.js"
|
||||||
config.assets.precompile << "lib/*.js"
|
config.assets.precompile << "lib/*.js"
|
||||||
config.assets.precompile << "u2f.js"
|
config.assets.precompile << "u2f.js"
|
||||||
|
|
71
spec/features/boards/boards_spec.rb
Normal file
71
spec/features/boards/boards_spec.rb
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe 'Issue Boards', feature: true, js: true do
|
||||||
|
let(:project) { create(:project) }
|
||||||
|
let(:user) { create(:user) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
project.team << [user, :master]
|
||||||
|
login_as(user)
|
||||||
|
|
||||||
|
visit namespace_project_boards_path(project.namespace, project)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shows default lists' do
|
||||||
|
lists = all('.board')
|
||||||
|
|
||||||
|
page.within lists.first do
|
||||||
|
expect(page).to have_content 'Backlog'
|
||||||
|
end
|
||||||
|
|
||||||
|
page.within lists.last do
|
||||||
|
expect(page).to have_content 'Done'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'removes blank state list' do
|
||||||
|
click_button 'Nevermind, i\'ll use my own'
|
||||||
|
|
||||||
|
expect(page).to have_selector('.board', count: 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'can drag card to new list' do
|
||||||
|
sleep 0.5
|
||||||
|
lists = all('.board')
|
||||||
|
drag_to(list_from_index: 0, list_to_index: 1)
|
||||||
|
|
||||||
|
page.within lists[1].find('.board-list') do
|
||||||
|
expect(page).to have_content('Test')
|
||||||
|
expect(page).to have_selector('.card', count: 2)
|
||||||
|
|
||||||
|
page.within first('.card .card-footer') do
|
||||||
|
expect(page).to have_content 'Frontend'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'removes all labels from card' do
|
||||||
|
sleep 0.5
|
||||||
|
lists = all('.board')
|
||||||
|
drag_to(list_from_index: 1, list_to_index: 3)
|
||||||
|
|
||||||
|
page.within lists[3].find('.board-list') do
|
||||||
|
expect(page).to have_content('Frontend bug')
|
||||||
|
expect(page).to have_selector('.card', count: 2)
|
||||||
|
|
||||||
|
page.within first('.card .card-footer') do
|
||||||
|
expect(page).not_to have_content 'Frontend'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
page.within lists[1].find('.board-list') do
|
||||||
|
expect(page).not_to have_content('Frontend bug')
|
||||||
|
expect(page).not_to have_selector('.card')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def drag_to(list_from_index: 0, card_index: 0, to_index: 0, list_to_index: 0)
|
||||||
|
evaluate_script("simulateDrag({scrollable: document.getElementById('board-app'), from: {el: $('.board-list').eq(#{list_from_index}).get(0), index: #{card_index}}, to: {el: $('.board-list').eq(#{list_to_index}).get(0), index: #{to_index}}});")
|
||||||
|
sleep 1
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue