Add html5 drop fake component to upload a real fixture image

pull/6346/head
Oliver Günther 7 years ago
parent a5af400d63
commit 22178e12d9
No known key found for this signature in database
GPG Key ID: 88872239EB414F99
  1. 8
      frontend/src/app/modules/fields/edit/edit.field.module.ts
  2. 5
      frontend/src/app/modules/fields/edit/editing-portal/wp-editing-portal-service.ts
  3. 2
      frontend/src/app/modules/fields/edit/field-types/formattable-edit-field.ts
  4. 2
      frontend/src/app/modules/fields/field.base.ts
  5. 59
      spec/features/work_packages/attachments/attachment_upload_spec.rb
  6. BIN
      spec/fixtures/files/image.png
  7. 34
      spec/support/components/attachments/attachments.rb
  8. 49
      spec/support/components/attachments/attachments_input.js

@ -41,8 +41,14 @@ export class EditField extends Field {
this.initialize();
}
public onSubmit() {
/**
* Called when the edit field is open and ready
* @param {HTMLElement} container
*/
public $onInit(container:HTMLElement) {
}
public onSubmit() {
}
public get inFlight() {

@ -59,7 +59,10 @@ export class WorkPackageEditingPortalService {
take(1)
)
.toPromise()
.then(() => fieldHandler);
.then(() => {
field.$onInit(container);
return fieldHandler;
});
}
/**

@ -65,8 +65,6 @@ export class FormattableEditField extends EditField {
protected initialize() {
const configurationService:ConfigurationService = this.$injector.get(ConfigurationService);
this.wysiwig = configurationService.textFormat() === 'markdown' && configurationService.useWysiwyg();
}
public get component() {

@ -42,8 +42,6 @@ export class Field {
public static type:string;
public static $injector:Injector;
public $onInit(container:HTMLElement) {}
public get displayName():string {
return this.schema.name || this.name;
}

@ -0,0 +1,59 @@
require 'spec_helper'
require 'features/page_objects/notification'
describe 'Upload attachment to work package', js: true do
let(:dev_role) do
FactoryBot.create :role,
permissions: %i[view_work_packages add_work_packages edit_work_packages]
end
let(:dev) do
FactoryBot.create :user,
firstname: 'Dev',
lastname: 'Guy',
member_in_project: project,
member_through_role: dev_role
end
let(:project) { FactoryBot.create(:project) }
let(:work_package) { FactoryBot.create(:work_package, project: project, description: 'Initial description') }
let(:wp_page) { ::Pages::FullWorkPackage.new(work_package, project) }
let(:attachments) { ::Components::Attachments.new }
let(:field) { WorkPackageEditorField.new wp_page, 'description' }
let(:image_fixture) { Rails.root.join('spec/fixtures/files/image.png') }
before do
login_as(dev)
wp_page.visit!
end
describe 'wysiwyg editor', with_settings: { text_formatting: 'markdown', use_wysiwyg?: 1 } do
it 'can upload an image via drag & drop' do
# Activate the edit field
field.activate!
target = find('.op-ckeditor-element')
attachments.drag_and_drop_file(target, image_fixture)
field.submit_by_click
expect(field.display_element).to have_selector('img')
end
end
describe 'attachment dropzone' do
it 'can upload an image via attaching and drag & drop' do
container = page.find('.wp-attachment-upload')
scroll_to_element(container)
##
# Attach file manually
expect(page).to have_no_selector('.work-package--attachments--filename')
attachments.attach_file_on_input(image_fixture)
expect(page).to have_selector('.work-package--attachments--filename', text: 'image.png')
sleep 2
##
# and via drag & drop
attachments.drag_and_drop_file(container, Rails.root.join('spec/fixtures/files/image.png'))
expect(page).to have_selector('.work-package--attachments--filename', text: 'image.png', count: 2, wait: 10)
end
end
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

@ -0,0 +1,34 @@
# JavaScript: HTML5 File attachments handling
# requires a (hidden) input file field
module Components
class Attachments
include Capybara::DSL
def initialize; end
##
# Drag and Drop the file loaded from path on to the (native) target element
def drag_and_drop_file(target, path)
# Remove any previous input, if any
page.execute_script <<-JS
jQuery('#temporary_attachment_files').remove()
JS
# Use the HTML5 file dropper to create a fake drop event
scroll_to_element(target)
page.execute_script(js_drop_files, target.native, 'temporary_attachment_files')
attach_file_on_input(path, 'temporary_attachment_files')
end
##
# Attach a file to the hidden file input
def attach_file_on_input(path, name = 'attachment_files')
page.attach_file(name, path, visible: :all)
end
def js_drop_files
@js_file ||= File.read(File.expand_path('../attachments_input.js', __FILE__))
end
end
end

@ -0,0 +1,49 @@
var params = arguments;
// Target element to drag & drop to
var target = params[0];
// name of the hidden file input field
// must exist on the page, create if needed.
var name = params[1];
// We need coordinates to drop to the element
var box = target.getBoundingClientRect();
var targetX = box.left + (box.width / 2);
var targetY = box.top + (box.height / 2);
var input = jQuery('<input>')
.attr('id', name)
.attr('name', name)
.attr('type', 'file')
.attr('style', 'position:fixed;left:0;bottom:0;z-index:10000')
.appendTo(document.body)
.on('change', function(event) {
input.remove();
event.stopPropagation();
var dataTransfer = {
constructor : DataTransfer,
effectAllowed : 'all',
dropEffect : 'none',
types : [ 'Files' ],
files : input[0].files,
setData : function setData(){},
getData : function getData(){},
clearData : function clearData(){},
setDragImage : function setDragImage(){}
};
['dragenter', 'dragover', 'drop'].forEach(function (type) {
var event = new MouseEvent(type, { clientX: targetX, clientY: targetY });
// Override the constructor to the DragEvent class
Object.setPrototypeOf(event, null);
event.dataTransfer = dataTransfer;
Object.setPrototypeOf(event, DragEvent.prototype);
console.log("Dispatching event %O", event);
target.dispatchEvent(event);
});
});
Loading…
Cancel
Save