mirror of
https://git.kescher.at/CatCatNya/catstodon.git
synced 2025-01-17 19:51:51 +01:00
Merge commit 'da4e55eb17e459fbc6d1a19fac3303508324324c' into glitch-soc/merge-upstream
This commit is contained in:
commit
f6a0cd9d1a
17 changed files with 135 additions and 49 deletions
|
@ -69,15 +69,6 @@ Style/MapToHash:
|
|||
Exclude:
|
||||
- 'app/models/status.rb'
|
||||
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
# SupportedStyles: literals, strict
|
||||
Style/MutableConstant:
|
||||
Exclude:
|
||||
- 'app/models/tag.rb'
|
||||
- 'app/services/delete_account_service.rb'
|
||||
- 'lib/mastodon/migration_warning.rb'
|
||||
|
||||
# Configuration parameters: AllowedMethods.
|
||||
# AllowedMethods: respond_to_missing?
|
||||
Style/OptionalBooleanParameter:
|
||||
|
|
|
@ -18,7 +18,7 @@ class Auth::SetupController < ApplicationController
|
|||
|
||||
if @user.update(user_params)
|
||||
@user.resend_confirmation_instructions unless @user.confirmed?
|
||||
redirect_to auth_setup_path, notice: I18n.t('auth.setup.new_confirmation_instructions_sent')
|
||||
redirect_to auth_setup_path, notice: t('auth.setup.new_confirmation_instructions_sent')
|
||||
else
|
||||
render :show
|
||||
end
|
||||
|
|
|
@ -378,6 +378,8 @@
|
|||
"ignore_notifications_modal.not_followers_title": "Nevšímať si oznámenia od ľudí, ktorí ťa nenasledujú?",
|
||||
"ignore_notifications_modal.not_following_title": "Nevšímať si oznámenia od ľudí, ktorých nenasleduješ?",
|
||||
"ignore_notifications_modal.private_mentions_title": "Nevšímať si oznámenia o nevyžiadaných súkromných spomínaniach?",
|
||||
"interaction_modal.action.favourite": "Pre pokračovanie si musíš obľúbiť zo svojho účtu.",
|
||||
"interaction_modal.action.follow": "Pre pokračovanie musíš nasledovať zo svojho účtu.",
|
||||
"interaction_modal.action.reply": "Pre pokračovanie musíš odpovedať s tvojho účtu.",
|
||||
"interaction_modal.action.vote": "Pre pokračovanie musíš hlasovať s tvojho účtu.",
|
||||
"interaction_modal.go": "Prejdi",
|
||||
|
@ -389,6 +391,7 @@
|
|||
"interaction_modal.title.reblog": "Zdieľať príspevok od {name}",
|
||||
"interaction_modal.title.reply": "Odpovedať na príspevok od {name}",
|
||||
"interaction_modal.title.vote": "Hlasuj v ankete od {name}",
|
||||
"interaction_modal.username_prompt": "Napr. {example}",
|
||||
"intervals.full.days": "{number, plural, one {# deň} few {# dni} many {# dní} other {# dní}}",
|
||||
"intervals.full.hours": "{number, plural, one {# hodina} few {# hodiny} many {# hodín} other {# hodín}}",
|
||||
"intervals.full.minutes": "{number, plural, one {# minúta} few {# minúty} many {# minút} other {# minút}}",
|
||||
|
@ -517,6 +520,7 @@
|
|||
"notification.moderation_warning": "Dostal/a si varovanie od moderátora",
|
||||
"notification.moderation_warning.action_delete_statuses": "Niektoré z tvojich príspevkov boli odstránené.",
|
||||
"notification.moderation_warning.action_disable": "Tvoj účet bol vypnutý.",
|
||||
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Niektoré tvoje príspevky boli označené za chúlostivé.",
|
||||
"notification.moderation_warning.action_none": "Tvoj účet dostal upozornenie od moderátora.",
|
||||
"notification.moderation_warning.action_sensitive": "Tvoje príspevky budú odteraz označované ako chúlostivé.",
|
||||
"notification.moderation_warning.action_silence": "Tvoj účet bol obmedzený.",
|
||||
|
@ -575,9 +579,11 @@
|
|||
"notifications.policy.accept_hint": "Ukáž v oznámeniach",
|
||||
"notifications.policy.drop": "Ignoruj",
|
||||
"notifications.policy.filter": "Triediť",
|
||||
"notifications.policy.filter_limited_accounts_hint": "Obmedzené moderátormi servera",
|
||||
"notifications.policy.filter_limited_accounts_title": "Moderované účty",
|
||||
"notifications.policy.filter_new_accounts_title": "Nové účty",
|
||||
"notifications.policy.filter_not_followers_title": "Ľudia, ktorí ťa nenasledujú",
|
||||
"notifications.policy.filter_not_following_hint": "Pokiaľ ich ručne neschváliš",
|
||||
"notifications.policy.filter_not_following_title": "Ľudia, ktorých nenasleduješ",
|
||||
"notifications.policy.filter_private_mentions_title": "Nevyžiadané priame spomenutia",
|
||||
"notifications.policy.title": "Spravuj oznámenia od…",
|
||||
|
@ -625,6 +631,7 @@
|
|||
"privacy_policy.title": "Pravidlá ochrany súkromia",
|
||||
"recommended": "Odporúčané",
|
||||
"refresh": "Obnoviť",
|
||||
"regeneration_indicator.please_stand_by": "Prosím, čakajte.",
|
||||
"regeneration_indicator.preparing_your_home_feed": "Pripravuje sa tvoj domáci kanál…",
|
||||
"relative_time.days": "{number} dní",
|
||||
"relative_time.full.days": "Pred {number, plural, one {# dňom} other {# dňami}}",
|
||||
|
@ -716,6 +723,7 @@
|
|||
"server_banner.about_active_users": "Ľudia používajúci tento server za posledných 30 dní (aktívni používatelia za mesiac)",
|
||||
"server_banner.active_users": "Aktívne účty",
|
||||
"server_banner.administered_by": "Správa servera:",
|
||||
"server_banner.is_one_of_many": "{domain} je jeden z mnohých nezávislých Mastodon serverov, ktoré môžeš použiť na zúčastňovanie sa v rámci fediversa.",
|
||||
"server_banner.server_stats": "Štatistiky servera:",
|
||||
"sign_in_banner.create_account": "Vytvoriť účet",
|
||||
"sign_in_banner.sign_in": "Prihlásiť sa",
|
||||
|
@ -758,6 +766,7 @@
|
|||
"status.reblogs.empty": "Nikto ešte tento príspevok nezdieľal. Keď tak niekto urobí, zobrazí sa to tu.",
|
||||
"status.redraft": "Vymazať a prepísať",
|
||||
"status.remove_bookmark": "Odstrániť záložku",
|
||||
"status.remove_favourite": "Odstráň z obľúbených",
|
||||
"status.replied_in_thread": "Odpovedal/a vo vlákne",
|
||||
"status.replied_to": "Odpoveď na {name}",
|
||||
"status.reply": "Odpovedať",
|
||||
|
|
|
@ -46,6 +46,8 @@ class DeliveryFailureTracker
|
|||
urls.reject do |url|
|
||||
host = Addressable::URI.parse(url).normalized_host
|
||||
unavailable_domains_map[host]
|
||||
rescue Addressable::URI::InvalidURIError, IDN::Idna::IdnaError
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -35,11 +35,11 @@ class Tag < ApplicationRecord
|
|||
has_one :trend, class_name: 'TagTrend', inverse_of: :tag, dependent: :destroy
|
||||
|
||||
HASHTAG_SEPARATORS = "_\u00B7\u30FB\u200c"
|
||||
HASHTAG_FIRST_SEQUENCE_CHUNK_ONE = "[[:word:]_][[:word:]#{HASHTAG_SEPARATORS}]*[[:alpha:]#{HASHTAG_SEPARATORS}]"
|
||||
HASHTAG_FIRST_SEQUENCE_CHUNK_TWO = "[[:word:]#{HASHTAG_SEPARATORS}]*[[:word:]_]"
|
||||
HASHTAG_FIRST_SEQUENCE = "(#{HASHTAG_FIRST_SEQUENCE_CHUNK_ONE}#{HASHTAG_FIRST_SEQUENCE_CHUNK_TWO})"
|
||||
HASHTAG_FIRST_SEQUENCE_CHUNK_ONE = "[[:word:]_][[:word:]#{HASHTAG_SEPARATORS}]*[[:alpha:]#{HASHTAG_SEPARATORS}]".freeze
|
||||
HASHTAG_FIRST_SEQUENCE_CHUNK_TWO = "[[:word:]#{HASHTAG_SEPARATORS}]*[[:word:]_]".freeze
|
||||
HASHTAG_FIRST_SEQUENCE = "(#{HASHTAG_FIRST_SEQUENCE_CHUNK_ONE}#{HASHTAG_FIRST_SEQUENCE_CHUNK_TWO})".freeze
|
||||
HASHTAG_LAST_SEQUENCE = '([[:word:]_]*[[:alpha:]][[:word:]_]*)'
|
||||
HASHTAG_NAME_PAT = "#{HASHTAG_FIRST_SEQUENCE}|#{HASHTAG_LAST_SEQUENCE}"
|
||||
HASHTAG_NAME_PAT = "#{HASHTAG_FIRST_SEQUENCE}|#{HASHTAG_LAST_SEQUENCE}".freeze
|
||||
|
||||
HASHTAG_RE = %r{(?<![=/)\p{Alnum}])#(#{HASHTAG_NAME_PAT})}
|
||||
HASHTAG_NAME_RE = /\A(#{HASHTAG_NAME_PAT})\z/i
|
||||
|
|
|
@ -9,6 +9,8 @@ class ActivityPub::ProcessAccountService < BaseService
|
|||
SUBDOMAINS_RATELIMIT = 10
|
||||
DISCOVERIES_PER_REQUEST = 400
|
||||
|
||||
VALID_URI_SCHEMES = %w(http https).freeze
|
||||
|
||||
# Should be called with confirmed valid JSON
|
||||
# and WebFinger-resolved username and domain
|
||||
def call(username, domain, json, options = {})
|
||||
|
@ -96,16 +98,28 @@ class ActivityPub::ProcessAccountService < BaseService
|
|||
end
|
||||
|
||||
def set_immediate_protocol_attributes!
|
||||
@account.inbox_url = @json['inbox'] || ''
|
||||
@account.outbox_url = @json['outbox'] || ''
|
||||
@account.shared_inbox_url = (@json['endpoints'].is_a?(Hash) ? @json['endpoints']['sharedInbox'] : @json['sharedInbox']) || ''
|
||||
@account.followers_url = @json['followers'] || ''
|
||||
@account.inbox_url = valid_collection_uri(@json['inbox'])
|
||||
@account.outbox_url = valid_collection_uri(@json['outbox'])
|
||||
@account.shared_inbox_url = valid_collection_uri(@json['endpoints'].is_a?(Hash) ? @json['endpoints']['sharedInbox'] : @json['sharedInbox'])
|
||||
@account.followers_url = valid_collection_uri(@json['followers'])
|
||||
@account.url = url || @uri
|
||||
@account.uri = @uri
|
||||
@account.actor_type = actor_type
|
||||
@account.created_at = @json['published'] if @json['published'].present?
|
||||
end
|
||||
|
||||
def valid_collection_uri(uri)
|
||||
uri = uri.first if uri.is_a?(Array)
|
||||
uri = uri['id'] if uri.is_a?(Hash)
|
||||
return '' unless uri.is_a?(String)
|
||||
|
||||
parsed_uri = Addressable::URI.parse(uri)
|
||||
|
||||
VALID_URI_SCHEMES.include?(parsed_uri.scheme) && parsed_uri.host.present? ? parsed_uri : ''
|
||||
rescue Addressable::URI::InvalidURIError
|
||||
''
|
||||
end
|
||||
|
||||
def set_immediate_attributes!
|
||||
@account.featured_collection_url = @json['featured'] || ''
|
||||
@account.display_name = @json['name'] || ''
|
||||
|
@ -268,10 +282,11 @@ class ActivityPub::ProcessAccountService < BaseService
|
|||
end
|
||||
|
||||
def collection_info(type)
|
||||
return [nil, nil] if @json[type].blank?
|
||||
collection_uri = valid_collection_uri(@json[type])
|
||||
return [nil, nil] if collection_uri.blank?
|
||||
return @collections[type] if @collections.key?(type)
|
||||
|
||||
collection = fetch_resource_without_id_validation(@json[type])
|
||||
collection = fetch_resource_without_id_validation(collection_uri)
|
||||
|
||||
total_items = collection.is_a?(Hash) && collection['totalItems'].present? && collection['totalItems'].is_a?(Numeric) ? collection['totalItems'] : nil
|
||||
has_first_page = collection.is_a?(Hash) && collection['first'].present?
|
||||
|
|
|
@ -51,7 +51,7 @@ class DeleteAccountService < BaseService
|
|||
scheduled_statuses
|
||||
status_pins
|
||||
tag_follows
|
||||
)
|
||||
).freeze
|
||||
|
||||
ASSOCIATIONS_ON_DESTROY = %w(
|
||||
reports
|
||||
|
|
|
@ -24,6 +24,8 @@ de:
|
|||
models:
|
||||
account:
|
||||
attributes:
|
||||
fields:
|
||||
fields_with_values_missing_labels: enthält Werte, bei denen Beschriftungen fehlen
|
||||
username:
|
||||
invalid: nur Buchstaben, Ziffern und Unterstriche
|
||||
reserved: ist bereits vergeben
|
||||
|
|
|
@ -936,17 +936,22 @@ eo:
|
|||
generate: Uzi ŝablonon
|
||||
generates:
|
||||
action: Generi
|
||||
chance_to_review_html: "<strong>La generataj kondiĉoj de uzado ne aŭtomate publikiĝos.</strong> Estos oportuni por vi kontroli la rezultojn. Bonvole entajpu la necesajn detalojn por daŭrigi."
|
||||
explanation_html: La modelo por la kondiĉoj de la servo disponeblas sole por informi. Ĝi nepre ne estas leĝa konsilo pri iu ajn temo. Bonvole konsultu vian propran leĝan konsilanton pri via situacio kaj iuj leĝaj neklarecoj.
|
||||
title: Agordo de kondiĉoj de uzado
|
||||
history: Historio
|
||||
live: Antaŭmontro
|
||||
no_history: Ankoraŭ ne estas registritaj ŝanĝoj de la kondiĉoj de la servo.
|
||||
no_terms_of_service_html: Vi nuntempe ne havas iujn ajn kondiĉojn de la servo agordita. La kondiĉoj de la servo celas doni klarecon kaj protekti vin kontraŭ eblaj respondecoj en disputoj kun viaj uzantoj.
|
||||
notified_on_html: Uzantojn sciigis je %{date}
|
||||
notify_users: Informu uzantojn
|
||||
preview:
|
||||
explanation_html: 'La retmesaĝo estos alsendata al <strong>%{display_count} uzantoj</strong>, kiuj kreis konton antaŭ %{date}. La sekvonta teksto inkluziviĝos en la retmesaĝo:'
|
||||
send_preview: Sendu antaŭrigardon al %{email}
|
||||
send_to_all:
|
||||
one: Sendi %{display_count} retpoŝton
|
||||
other: Sendi %{display_count} retpoŝtojn
|
||||
title: Antaŭmontri sciigon pri la kondiĉoj de la servo
|
||||
publish: Publikigi
|
||||
published_on_html: Publikigita je %{date}
|
||||
save_draft: Konservi malneton
|
||||
|
@ -1930,6 +1935,8 @@ eo:
|
|||
subject: Via konto estas alirita de nova IP-adreso
|
||||
title: Nova saluto
|
||||
terms_of_service_changed:
|
||||
agreement: Se vi daŭrige uzos %{domain}, vi aŭtomate interkonsentos pri ĉi tiuj kondiĉoj. Se vi malkonsentas pri la novaj kondiĉoj, vi ĉiutempe rajtas nuligi la interkonsenton kun %{domain} per forigi vian konton.
|
||||
changelog: 'Facile dirite, la ŝanĝoj estas la jenaj:'
|
||||
description: 'Vi ricevas ĉi tiun retmesaĝon ĉar ni faras iujn ŝanĝojn al niaj servokondiĉoj ĉe %{domain}. Ni instigas vin revizii la ĝisdatigitajn kondiĉojn tute ĉi tie:'
|
||||
description_html: Vi ricevas ĉi tiun retmesaĝon ĉar ni faras iujn ŝanĝojn al niaj servokondiĉoj ĉe %{domain}. Ni instigas vin revizii la <a href="%{path}" target="_blank">ĝisdatigitajn kondiĉojn plene ĉi tie</a>.
|
||||
sign_off: La teamo de %{domain}
|
||||
|
|
|
@ -137,6 +137,7 @@ de:
|
|||
admin_email: Rechtliche Hinweise umfassen Gegendarstellungen, Gerichtsbeschlüsse, Anfragen zum Herunternehmen von Inhalten und Anfragen von Strafverfolgungsbehörden.
|
||||
arbitration_address: Kann wie die Anschrift hierüber sein oder „N/A“, falls eine E-Mail verwendet wird
|
||||
arbitration_website: Kann ein Webformular sein oder „N/A“, falls eine E-Mail verwendet wird
|
||||
dmca_address: US-Betreiber sollten die im „DMCA Designated Agent Directory“ eingetragene Adresse verwenden. Eine Postfachadresse ist auf direkte Anfrage verfügbar. Verwenden Sie die „DMCA Designated Agent Post Box Waiver“-Anfrage, um per E-Mail die Urheberrechtsbehörde darüber zu unterrichten, dass Sie Inhalte per Heimarbeit moderieren, eventuelle Rache oder Vergeltung für Ihre Handlungen befürchten und deshalb eine Postfachadresse benötigen, um Ihre Privatadresse nicht preiszugeben.
|
||||
dmca_email: Kann dieselbe E-Mail wie bei „E-Mail-Adresse für rechtliche Hinweise“ sein
|
||||
domain: Einzigartige Identifizierung des angebotenen Online-Services.
|
||||
jurisdiction: Gib das Land an, in dem die Person lebt, die alle Rechnungen bezahlt. Falls es sich dabei um ein Unternehmen oder eine andere Einrichtung handelt, gib das Land mit dem Sitz an, sowie die Stadt oder Region.
|
||||
|
|
|
@ -28,6 +28,7 @@ sk:
|
|||
admin:
|
||||
account_actions:
|
||||
action: Vykonaj
|
||||
already_silenced: Tento účet už bol obmedzený.
|
||||
title: Vykonaj moderovací úkon voči %{acct}
|
||||
account_moderation_notes:
|
||||
create: Zanechaj poznámku
|
||||
|
@ -204,6 +205,7 @@ sk:
|
|||
enable_user: Povoľ užívateľa
|
||||
memorialize_account: Zmena na „in memoriam“
|
||||
promote_user: Povýš užívateľskú rolu
|
||||
publish_terms_of_service: Zverejni podmienky prevozu
|
||||
reject_appeal: Zamietni námietku
|
||||
reject_user: Zamietni užívateľa
|
||||
remove_avatar_user: Vymaž avatar
|
||||
|
|
|
@ -4,7 +4,7 @@ module Mastodon
|
|||
module MigrationWarning
|
||||
WARNING_SECONDS = 10
|
||||
|
||||
DEFAULT_WARNING = <<~WARNING_MESSAGE
|
||||
DEFAULT_WARNING = <<~WARNING_MESSAGE.freeze
|
||||
WARNING: This migration may take a *long* time for large instances.
|
||||
It will *not* lock tables for any significant time, but it may run
|
||||
for a very long time. We will pause for #{WARNING_SECONDS} seconds to allow you to
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Auth::SetupController do
|
||||
render_views
|
||||
|
||||
describe 'GET #show' do
|
||||
context 'with a signed out request' do
|
||||
it 'returns http redirect' do
|
||||
get :show
|
||||
expect(response).to be_redirect
|
||||
end
|
||||
end
|
||||
|
||||
context 'with an unconfirmed signed in user' do
|
||||
before { sign_in Fabricate(:user, confirmed_at: nil) }
|
||||
|
||||
it 'returns http success' do
|
||||
get :show
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -42,8 +42,8 @@ RSpec.describe DeliveryFailureTracker do
|
|||
Fabricate(:unavailable_domain, domain: 'foo.bar')
|
||||
end
|
||||
|
||||
it 'removes URLs that are unavailable' do
|
||||
results = described_class.without_unavailable(['http://example.com/good/inbox', 'http://foo.bar/unavailable/inbox'])
|
||||
it 'removes URLs that are bogus or unavailable' do
|
||||
results = described_class.without_unavailable(['http://example.com/good/inbox', 'http://foo.bar/unavailable/inbox', '{foo:'])
|
||||
|
||||
expect(results).to include('http://example.com/good/inbox')
|
||||
expect(results).to_not include('http://foo.bar/unavailable/inbox')
|
||||
|
|
|
@ -36,6 +36,31 @@ RSpec.describe 'Polls' do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when poll is remote and needs refresh' do
|
||||
let(:poll) { Fabricate(:poll, last_fetched_at: nil, account: remote_account, status: status) }
|
||||
let(:remote_account) { Fabricate :account, domain: 'host.example' }
|
||||
let(:service) { instance_double(ActivityPub::FetchRemotePollService, call: nil) }
|
||||
let(:status) { Fabricate(:status, visibility: 'public', account: remote_account) }
|
||||
|
||||
before { allow(ActivityPub::FetchRemotePollService).to receive(:new).and_return(service) }
|
||||
|
||||
it 'returns poll data and calls fetch remote service' do
|
||||
subject
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/json')
|
||||
expect(response.parsed_body).to match(
|
||||
a_hash_including(
|
||||
id: poll.id.to_s
|
||||
)
|
||||
)
|
||||
expect(service)
|
||||
.to have_received(:call).with(poll, user.account)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when parent status is private' do
|
||||
let(:visibility) { 'private' }
|
||||
|
||||
|
|
27
spec/requests/auth/setup_spec.rb
Normal file
27
spec/requests/auth/setup_spec.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Auth Setup' do
|
||||
describe 'GET /auth/setup' do
|
||||
context 'with a signed out request' do
|
||||
it 'redirects to root' do
|
||||
get '/auth/setup'
|
||||
|
||||
expect(response)
|
||||
.to redirect_to(new_user_session_url)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a confirmed signed in user' do
|
||||
before { sign_in Fabricate(:user, confirmed_at: 2.days.ago) }
|
||||
|
||||
it 'redirects to root' do
|
||||
get '/auth/setup'
|
||||
|
||||
expect(response)
|
||||
.to redirect_to(root_url)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
30
spec/system/auth/setup_spec.rb
Normal file
30
spec/system/auth/setup_spec.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Auth Setup' do
|
||||
context 'with an unconfirmed signed in user' do
|
||||
let(:user) { Fabricate(:user, confirmed_at: nil) }
|
||||
|
||||
before { sign_in(user) }
|
||||
|
||||
it 'can update email address' do
|
||||
visit auth_setup_path
|
||||
|
||||
expect(page)
|
||||
.to have_content(I18n.t('auth.setup.title'))
|
||||
|
||||
find('summary.lead').click
|
||||
fill_in 'user_email', with: 'new-email@example.host'
|
||||
|
||||
expect { submit_form }
|
||||
.to(change { user.reload.unconfirmed_email })
|
||||
expect(page)
|
||||
.to have_content(I18n.t('auth.setup.new_confirmation_instructions_sent'))
|
||||
end
|
||||
|
||||
def submit_form
|
||||
find('[name=button]').click
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue