mirror of
https://github.com/discourse/discourse.git
synced 2025-03-03 21:03:29 +08:00

Short answer -- the problem is the video thumbnail generator & uploader
code added a couple of months back in f144c64e139e41f176ea2ec3433a468fa49b955f.
It was implemented as another Mixin which overrides `this._uppyInstance`
when uploading the video thumbnail after the initial upload is complete,
which means the composer's `this._uppyInstance` value is overridden,
and it loses all of its preprocessors & upload code.
This is generally a problem with the Mixin based architecture that I
used for the Uppy code, which we need to remove at some point and
refacotr.
The most ideal thing to do here would be to convert this video thumbnail
code into an Uppy
[postprocessor](https://uppy.io/docs/uppy/#addpostprocessorfn) plugin,
which runs on each upload after they are complete. I started looking
into this, and the main hurdle here is adding support to tracking the
progress of postprocessors to
[ExtendableUploader](cf42466dea/app/assets/javascripts/discourse/app/mixins/extendable-uploader.js
)
so that is out of scope at this time.
The fix here makes it so the ComposerVideoThumbnailUppy code is no
longer a Mixin, but acts more like a normal class, a pattern which
we have used in chat. I also clean up a lot of the thumbnail uploader
code and remove some unnecessary things.
Attempted to add a system spec, but video streaming does not work
in Chrome for Testing at this time, and it is needed for the
onloadedmetadata event.
227 lines
5.6 KiB
Ruby
227 lines
5.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module PageObjects
|
|
module Components
|
|
class Composer < PageObjects::Components::Base
|
|
COMPOSER_ID = "#reply-control"
|
|
AUTOCOMPLETE_MENU = ".autocomplete.ac-emoji"
|
|
|
|
def opened?
|
|
page.has_css?("#{COMPOSER_ID}.open")
|
|
end
|
|
|
|
def open_composer_actions
|
|
find(".composer-action-title .btn").click
|
|
self
|
|
end
|
|
|
|
def click_toolbar_button(button_class)
|
|
find(".d-editor-button-bar button.#{button_class}").click
|
|
self
|
|
end
|
|
|
|
def fill_title(title)
|
|
find("#{COMPOSER_ID} #reply-title").fill_in(with: title)
|
|
self
|
|
end
|
|
|
|
def fill_content(content)
|
|
composer_input.fill_in(with: content)
|
|
self
|
|
end
|
|
|
|
def fill_form_template_field(field, content)
|
|
form_template_field(field).fill_in(with: content)
|
|
self
|
|
end
|
|
|
|
def type_content(content)
|
|
composer_input.send_keys(content)
|
|
self
|
|
end
|
|
|
|
def clear_content
|
|
fill_content("")
|
|
end
|
|
|
|
def has_content?(content)
|
|
composer_input.value == content
|
|
end
|
|
|
|
def has_popup_content?(content)
|
|
composer_popup.has_content?(content)
|
|
end
|
|
|
|
def select_action(action)
|
|
find(action(action)).click
|
|
self
|
|
end
|
|
|
|
def create
|
|
find("#{COMPOSER_ID} .btn-primary").click
|
|
end
|
|
|
|
def action(action_title)
|
|
".composer-action-title .select-kit-collection li[title='#{action_title}']"
|
|
end
|
|
|
|
def button_label
|
|
find("#{COMPOSER_ID} .btn-primary .d-button-label")
|
|
end
|
|
|
|
def emoji_picker
|
|
find("#{COMPOSER_ID} .emoji-picker")
|
|
end
|
|
|
|
def emoji_autocomplete
|
|
find(AUTOCOMPLETE_MENU)
|
|
end
|
|
|
|
def category_chooser
|
|
Components::SelectKit.new(".category-chooser")
|
|
end
|
|
|
|
def switch_category(category_name)
|
|
find(".category-chooser").click
|
|
find(".category-row[data-name='#{category_name}']").click
|
|
end
|
|
|
|
def preview
|
|
find("#{COMPOSER_ID} .d-editor-preview-wrapper")
|
|
end
|
|
|
|
def has_emoji_autocomplete?
|
|
has_css?(AUTOCOMPLETE_MENU)
|
|
end
|
|
|
|
def has_no_emoji_autocomplete?
|
|
has_no_css?(AUTOCOMPLETE_MENU)
|
|
end
|
|
|
|
EMOJI_SUGGESTION_SELECTOR = "#{AUTOCOMPLETE_MENU} .emoji-shortname"
|
|
|
|
def has_emoji_suggestion?(emoji)
|
|
has_css?(EMOJI_SUGGESTION_SELECTOR, text: emoji)
|
|
end
|
|
|
|
def has_no_emoji_suggestion?(emoji)
|
|
has_no_css?(EMOJI_SUGGESTION_SELECTOR, text: emoji)
|
|
end
|
|
|
|
def has_emoji_preview?(emoji)
|
|
page.has_css?(emoji_preview_selector(emoji))
|
|
end
|
|
|
|
def has_no_emoji_preview?(emoji)
|
|
page.has_no_css?(emoji_preview_selector(emoji))
|
|
end
|
|
|
|
COMPOSER_INPUT_SELECTOR = "#{COMPOSER_ID} .d-editor-input"
|
|
|
|
def has_no_composer_input?
|
|
page.has_no_css?(COMPOSER_INPUT_SELECTOR)
|
|
end
|
|
|
|
def has_composer_input?
|
|
page.has_css?(COMPOSER_INPUT_SELECTOR)
|
|
end
|
|
|
|
def has_composer_preview?
|
|
page.has_css?("#{COMPOSER_ID} .d-editor-preview-wrapper")
|
|
end
|
|
|
|
def has_no_composer_preview?
|
|
page.has_no_css?("#{COMPOSER_ID} .d-editor-preview-wrapper")
|
|
end
|
|
|
|
def has_composer_preview_toggle?
|
|
page.has_css?("#{COMPOSER_ID} .toggle-preview")
|
|
end
|
|
|
|
def has_no_composer_preview_toggle?
|
|
page.has_no_css?("#{COMPOSER_ID} .toggle-preview")
|
|
end
|
|
|
|
def has_form_template?
|
|
page.has_css?(".form-template-form__wrapper")
|
|
end
|
|
|
|
def has_form_template_field?(field)
|
|
page.has_css?(".form-template-field[data-field-type='#{field}']")
|
|
end
|
|
|
|
def has_form_template_field_required_indicator?(field)
|
|
page.has_css?(
|
|
".form-template-field[data-field-type='#{field}'] .form-template-field__required-indicator",
|
|
)
|
|
end
|
|
|
|
FORM_TEMPLATE_CHOOSER_SELECTOR = ".composer-select-form-template"
|
|
|
|
def has_no_form_template_chooser?
|
|
page.has_no_css?(FORM_TEMPLATE_CHOOSER_SELECTOR)
|
|
end
|
|
|
|
def has_form_template_chooser?
|
|
page.has_css?(FORM_TEMPLATE_CHOOSER_SELECTOR)
|
|
end
|
|
|
|
def has_form_template_field_error?(error)
|
|
page.has_css?(".form-template-field__error", text: error)
|
|
end
|
|
|
|
def composer_input
|
|
find("#{COMPOSER_ID} .d-editor .d-editor-input")
|
|
end
|
|
|
|
def composer_popup
|
|
find("#{COMPOSER_ID} .composer-popup")
|
|
end
|
|
|
|
def form_template_field(field)
|
|
find(".form-template-field[data-field-type='#{field}']")
|
|
end
|
|
|
|
def move_cursor_after(text)
|
|
execute_script(<<~JS, text)
|
|
const text = arguments[0];
|
|
const composer = document.querySelector("#{COMPOSER_ID} .d-editor-input");
|
|
const index = composer.value.indexOf(text);
|
|
const position = index + text.length;
|
|
|
|
composer.setSelectionRange(position, position);
|
|
JS
|
|
end
|
|
|
|
def select_all
|
|
execute_script(<<~JS, text)
|
|
const composer = document.querySelector("#{COMPOSER_ID} .d-editor-input");
|
|
composer.setSelectionRange(0, composer.value.length);
|
|
JS
|
|
end
|
|
|
|
def submit
|
|
find("#{COMPOSER_ID} .save-or-cancel .create").click
|
|
end
|
|
|
|
def close
|
|
find("#{COMPOSER_ID} .save-or-cancel .cancel").click
|
|
end
|
|
|
|
def has_no_in_progress_uploads?
|
|
find("#{COMPOSER_ID}").has_no_css?("#file-uploading")
|
|
end
|
|
|
|
def has_in_progress_uploads?
|
|
find("#{COMPOSER_ID}").has_css?("#file-uploading")
|
|
end
|
|
|
|
private
|
|
|
|
def emoji_preview_selector(emoji)
|
|
".d-editor-preview .emoji[title=':#{emoji}:']"
|
|
end
|
|
end
|
|
end
|
|
end
|