discourse/spec/system/page_objects/components/form_kit.rb
Osama Sayegh c3bc7a6a05
DEV: Add support for image fields in FormKit PageObject (#29589)
This commit adds an API `upload_image` to `FormKitField` page object for setting an image file on an `Image` field in FormKit. Usage is like this:

```ruby
form.field("image_field").upload_image(image_path)
```

The `value` API also now supports `Image` fields; it returns an `Upload` record if the field has an uploaded image.
2024-11-05 15:35:53 +03:00

235 lines
6.5 KiB
Ruby

# frozen_string_literal: true
module PageObjects
module Components
class FormKitContainer < PageObjects::Components::Base
attr_reader :component
def initialize(input)
if input.is_a?(Capybara::Node::Element)
@component = input
else
@component = find(input)
end
end
def has_content?(content)
component.has_content?(content)
end
end
class FormKitField < PageObjects::Components::Base
attr_reader :component
def initialize(input)
if input.is_a?(Capybara::Node::Element)
@component = input
else
@component = find(input)
end
end
def value
case control_type
when /input-/, "password"
component.find("input").value
when "icon"
picker = PageObjects::Components::SelectKit.new(component)
picker.value
when "checkbox"
component.find("input[type='checkbox']").checked?
when "menu"
component.find(".fk-d-menu__trigger")["data-value"]
when "select"
component.find("select").value
when "composer"
component.find("textarea").value
when "image"
url = component.find(".uploaded-image-preview a.lightbox", wait: 10)[:href]
sha1 = url.match(/(\h{40})/).captures.first
Upload.find_by(sha1:)
end
end
def unchecked?
if control_type != "checkbox"
raise "'unchecked?' is only supported for control type: #{control_type}"
end
expect(self.value).to eq(false)
end
def checked?
if control_type != "checkbox"
raise "'checked?' is only supported for control type: #{control_type}"
end
expect(self.value).to eq(true)
end
def has_value?(expected_value)
expect(self.value).to eq(expected_value)
end
def has_errors?(*messages)
within component do
messages.all? { |m| find(".form-kit__errors", text: m) }
end
end
def has_no_errors?
!has_css?(".form-kit__errors")
end
def control_type
component["data-control-type"]
end
def toggle
case control_type
when "checkbox"
component.find("input[type='checkbox']").click
when "password"
component.find(".form-kit__control-password-toggle").click
else
raise "'toggle' is not supported for control type: #{control_type}"
end
end
def fill_in(value)
case control_type
when "input-text", "password", "input-date"
component.find("input").fill_in(with: value)
when "textarea", "composer"
component.find("textarea").fill_in(with: value, visible: :all)
when "code"
component.find(".ace_text-input", visible: :all).fill_in(with: value)
else
raise "Unsupported control type: #{control_type}"
end
end
def select(value)
case control_type
when "icon"
selector = component.find(".form-kit__control-icon")["id"]
picker = PageObjects::Components::SelectKit.new("#" + selector)
picker.expand
picker.search(value)
picker.select_row_by_value(value)
when "select"
selector = component.find(".form-kit__control-select")
selector.find(".form-kit__control-option[value='#{value}']").select_option
selector.execute_script(<<~JS, selector)
var selector = arguments[0];
selector.dispatchEvent(new Event("input", { bubbles: true, cancelable: true }));
JS
when "menu"
trigger = component.find(".fk-d-menu__trigger.form-kit__control-menu")
trigger.click
menu = find("[aria-labelledby='#{trigger["id"]}']")
item = menu.find(".form-kit__control-menu-item[data-value='#{value}'] .btn")
item.click
when "radio-group"
radio = component.find("input[type='radio'][value='#{value}']")
radio.click
when "question"
if value == true
accept
else
refuse
end
else
raise "Unsupported control type: #{control_type}"
end
end
def accept
if control_type == "question"
component.find(".form-kit__control-radio[value='true']").click
else
raise "'accept' is not supported for control type: #{control_type}"
end
end
def refuse
if control_type == "question"
component.find(".form-kit__control-radio[value='false']").click
else
raise "'refuse' is not supported for control type: #{control_type}"
end
end
def upload_image(image_path)
if control_type == "image"
attach_file(image_path) do
component.find(".image-upload-controls .btn.btn-default").click
end
else
raise "'upload_image' is not supported for control type: #{control_type}"
end
end
def disabled?
component["data-disabled"] == ""
end
def enabled?
!disabled?
end
end
class FormKit < PageObjects::Components::Base
attr_reader :component
def initialize(component)
@component = component
end
def submit
page.execute_script(
"var form = arguments[0]; form.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true }));",
find(component),
)
end
def reset
page.execute_script(
"var form = arguments[0]; form.dispatchEvent(new Event('reset', { bubbles: true, cancelable: true }));",
find(component),
)
end
def has_an_alert?(message)
within component do
find(".form-kit__alert-message", text: message)
end
end
def field(name)
within component do
FormKitField.new(find(".form-kit__field[data-name='#{name}']"))
end
end
def has_field_with_name?(name)
has_css?(".form-kit__field[data-name='#{name}']")
end
def has_no_field_with_name?(name)
has_no_css?(".form-kit__field[data-name='#{name}']")
end
def container(name)
within component do
FormKitContainer.new(find(".form-kit__container[data-name='#{name}']"))
end
end
def choose_conditional(name)
find(".form-kit__conditional-display .form-kit__control-radio[value='#{name}']").click
end
end
end
end