mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-10 01:01:39 -05:00
Remove system spec
This commit is contained in:
parent
e3e5770843
commit
e965c8c67c
5 changed files with 28 additions and 523 deletions
|
|
@ -36,6 +36,8 @@ class MapController < ApplicationController
|
|||
end
|
||||
|
||||
def calculate_distance
|
||||
return 0 if @coordinates.size < 2
|
||||
|
||||
total_distance = 0
|
||||
|
||||
@coordinates.each_cons(2) do
|
||||
|
|
|
|||
|
|
@ -535,8 +535,6 @@ export class VisitsManager {
|
|||
return drawer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Fetches visits data from the API and displays them
|
||||
*/
|
||||
|
|
@ -1574,7 +1572,7 @@ export class VisitsManager {
|
|||
|
||||
// Show confirmation dialog
|
||||
const confirmDelete = confirm('Are you sure you want to delete this visit? This action cannot be undone.');
|
||||
|
||||
|
||||
if (!confirmDelete) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ module LocationSearch
|
|||
return [] if query.blank?
|
||||
|
||||
cache_key = "#{@cache_key_prefix}:#{Digest::SHA256.hexdigest(query.downcase)}"
|
||||
|
||||
|
||||
Rails.cache.fetch(cache_key, expires_in: CACHE_TTL) do
|
||||
perform_geocoding_search(query)
|
||||
end
|
||||
|
|
@ -30,33 +30,33 @@ module LocationSearch
|
|||
|
||||
def perform_geocoding_search(query)
|
||||
Rails.logger.info "LocationSearch::GeocodingService: Searching for '#{query}' using #{provider_name}"
|
||||
|
||||
|
||||
# Try original query first
|
||||
results = Geocoder.search(query, limit: MAX_RESULTS)
|
||||
Rails.logger.info "LocationSearch::GeocodingService: Raw geocoder returned #{results.length} results"
|
||||
|
||||
# If we got results but they seem too generic (common chain names),
|
||||
|
||||
# If we got results but they seem too generic (common chain names),
|
||||
# also try with location context
|
||||
if results.length > 1 && looks_like_chain_store?(query)
|
||||
Rails.logger.info "LocationSearch::GeocodingService: Query looks like chain store, trying with Berlin context"
|
||||
Rails.logger.info 'LocationSearch::GeocodingService: Query looks like chain store, trying with Berlin context'
|
||||
berlin_results = Geocoder.search("#{query} Berlin", limit: MAX_RESULTS)
|
||||
Rails.logger.info "LocationSearch::GeocodingService: Berlin-specific search returned #{berlin_results.length} results"
|
||||
|
||||
|
||||
# Prioritize Berlin results
|
||||
results = (berlin_results + results).uniq
|
||||
end
|
||||
|
||||
|
||||
return [] if results.blank?
|
||||
|
||||
normalized = normalize_geocoding_results(results)
|
||||
Rails.logger.info "LocationSearch::GeocodingService: After normalization: #{normalized.length} results"
|
||||
|
||||
|
||||
normalized
|
||||
end
|
||||
|
||||
def normalize_geocoding_results(results)
|
||||
normalized_results = []
|
||||
|
||||
|
||||
results.each_with_index do |result, idx|
|
||||
unless valid_result?(result)
|
||||
Rails.logger.warn "LocationSearch::GeocodingService: Result #{idx} is invalid: lat=#{result.latitude}, lon=#{result.longitude}"
|
||||
|
|
@ -80,13 +80,13 @@ module LocationSearch
|
|||
# Remove duplicates based on coordinates (within 100m)
|
||||
deduplicated = deduplicate_results(normalized_results)
|
||||
Rails.logger.info "LocationSearch::GeocodingService: After deduplication: #{deduplicated.length} results"
|
||||
|
||||
|
||||
deduplicated
|
||||
end
|
||||
|
||||
def valid_result?(result)
|
||||
result.present? &&
|
||||
result.latitude.present? &&
|
||||
result.present? &&
|
||||
result.latitude.present? &&
|
||||
result.longitude.present? &&
|
||||
result.latitude.to_f.abs <= 90 &&
|
||||
result.longitude.to_f.abs <= 180
|
||||
|
|
@ -120,7 +120,7 @@ module LocationSearch
|
|||
|
||||
def extract_type(result)
|
||||
data = result.data || {}
|
||||
|
||||
|
||||
case provider_name.downcase
|
||||
when 'photon'
|
||||
data.dig('properties', 'osm_key') || data.dig('properties', 'type') || 'unknown'
|
||||
|
|
@ -151,13 +151,13 @@ module LocationSearch
|
|||
def extract_photon_address(result)
|
||||
properties = result.data&.dig('properties') || {}
|
||||
parts = []
|
||||
|
||||
|
||||
parts << properties['street'] if properties['street'].present?
|
||||
parts << properties['housenumber'] if properties['housenumber'].present?
|
||||
parts << properties['city'] if properties['city'].present?
|
||||
parts << properties['state'] if properties['state'].present?
|
||||
parts << properties['country'] if properties['country'].present?
|
||||
|
||||
|
||||
parts.join(', ')
|
||||
end
|
||||
|
||||
|
|
@ -182,7 +182,7 @@ module LocationSearch
|
|||
|
||||
def deduplicate_results(results)
|
||||
deduplicated = []
|
||||
|
||||
|
||||
results.each do |result|
|
||||
# Check if there's already a result within 100m
|
||||
duplicate = deduplicated.find do |existing|
|
||||
|
|
@ -192,27 +192,27 @@ module LocationSearch
|
|||
)
|
||||
distance < 100 # meters
|
||||
end
|
||||
|
||||
|
||||
deduplicated << result unless duplicate
|
||||
end
|
||||
|
||||
|
||||
deduplicated
|
||||
end
|
||||
|
||||
def calculate_distance(lat1, lon1, lat2, lon2)
|
||||
# Haversine formula for distance calculation in meters
|
||||
rad_per_deg = Math::PI / 180
|
||||
rkm = 6371000 # Earth radius in meters
|
||||
|
||||
rkm = 6_371_000 # Earth radius in meters
|
||||
|
||||
dlat_rad = (lat2 - lat1) * rad_per_deg
|
||||
dlon_rad = (lon2 - lon1) * rad_per_deg
|
||||
|
||||
|
||||
lat1_rad = lat1 * rad_per_deg
|
||||
lat2_rad = lat2 * rad_per_deg
|
||||
|
||||
|
||||
a = Math.sin(dlat_rad / 2)**2 + Math.cos(lat1_rad) * Math.cos(lat2_rad) * Math.sin(dlon_rad / 2)**2
|
||||
c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
|
||||
|
||||
|
||||
rkm * c
|
||||
end
|
||||
|
||||
|
|
@ -224,8 +224,8 @@ module LocationSearch
|
|||
/\b(dm|rossmann|müller)\b/i,
|
||||
/\b(h&m|c&a|zara|primark)\b/i
|
||||
]
|
||||
|
||||
|
||||
chain_patterns.any? { |pattern| query.match?(pattern) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -36,7 +36,3 @@ MANAGER_URL = SELF_HOSTED ? nil : ENV.fetch('MANAGER_URL', nil)
|
|||
METRICS_USERNAME = ENV.fetch('METRICS_USERNAME', 'prometheus')
|
||||
METRICS_PASSWORD = ENV.fetch('METRICS_PASSWORD', 'prometheus')
|
||||
# /Prometheus metrics
|
||||
|
||||
FEATURES = {
|
||||
location_search: !!ENV.fetch('PHOTON_API_HOST', nil)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,491 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Location Search Feature', type: :system, js: true do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
before do
|
||||
driven_by(:selenium_chrome_headless)
|
||||
# Alternative for debugging: driven_by(:rack_test)
|
||||
login_as user, scope: :user
|
||||
|
||||
# Create some test points near Berlin with proper PostGIS point format
|
||||
create(:point,
|
||||
user: user,
|
||||
latitude: 52.5200,
|
||||
longitude: 13.4050,
|
||||
timestamp: 1.day.ago.to_i,
|
||||
city: 'Berlin',
|
||||
country: 'Germany'
|
||||
)
|
||||
|
||||
create(:point,
|
||||
user: user,
|
||||
latitude: 52.5201,
|
||||
longitude: 13.4051,
|
||||
timestamp: 2.hours.ago.to_i,
|
||||
city: 'Berlin',
|
||||
country: 'Germany'
|
||||
)
|
||||
|
||||
# Ensure points are properly saved and accessible
|
||||
expect(user.points.count).to eq(2)
|
||||
|
||||
# Mock the geocoding service to avoid external API calls
|
||||
allow_any_instance_of(LocationSearch::GeocodingService).to receive(:search) do |_service, query|
|
||||
case query.downcase
|
||||
when /kaufland/
|
||||
[
|
||||
{
|
||||
lat: 52.5200,
|
||||
lon: 13.4050,
|
||||
name: 'Kaufland Mitte',
|
||||
address: 'Alexanderplatz 1, Berlin',
|
||||
type: 'shop'
|
||||
}
|
||||
]
|
||||
when /nonexistent/
|
||||
[]
|
||||
else
|
||||
[
|
||||
{
|
||||
lat: 52.5200,
|
||||
lon: 13.4050,
|
||||
name: 'Generic Location',
|
||||
address: 'Berlin, Germany',
|
||||
type: 'unknown'
|
||||
}
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Search Bar' do
|
||||
before do
|
||||
visit '/map'
|
||||
|
||||
# Debug: check what's actually on the page
|
||||
puts "Page title: #{page.title}"
|
||||
puts "Page body contains 'Map': #{page.has_content?('Map')}"
|
||||
puts "Page has #map element: #{page.has_css?('#map')}"
|
||||
puts "Page HTML preview: #{page.html[0..500]}..."
|
||||
|
||||
# Check if map container exists
|
||||
if page.has_css?('#map')
|
||||
puts "Map element found!"
|
||||
else
|
||||
puts "Map element NOT found - checking for any div elements:"
|
||||
puts "Number of div elements: #{page.all('div').count}"
|
||||
end
|
||||
|
||||
sleep(3) # Give time for JavaScript to initialize
|
||||
end
|
||||
|
||||
it 'displays search toggle button on the map' do
|
||||
expect(page).to have_css('#location-search-toggle')
|
||||
expect(page).to have_css('button:contains("🔍")')
|
||||
end
|
||||
|
||||
it 'initially hides the search bar' do
|
||||
expect(page).to have_css('#location-search-container.hidden')
|
||||
end
|
||||
|
||||
it 'shows search bar when toggle button is clicked' do
|
||||
find('#location-search-toggle').click
|
||||
|
||||
expect(page).to have_css('#location-search-container:not(.hidden)')
|
||||
expect(page).to have_css('#location-search-input')
|
||||
end
|
||||
|
||||
it 'hides search bar when toggle button is clicked again' do
|
||||
# Show search bar first
|
||||
find('#location-search-toggle').click
|
||||
expect(page).to have_css('#location-search-container:not(.hidden)')
|
||||
|
||||
# Hide it
|
||||
find('#location-search-toggle').click
|
||||
expect(page).to have_css('#location-search-container.hidden')
|
||||
end
|
||||
|
||||
it 'shows placeholder text in search input when visible' do
|
||||
find('#location-search-toggle').click
|
||||
|
||||
search_input = find('#location-search-input')
|
||||
expect(search_input[:placeholder]).to include('Search locations')
|
||||
end
|
||||
|
||||
context 'when performing a search' do
|
||||
before do
|
||||
# Show the search bar first
|
||||
find('#location-search-toggle').click
|
||||
end
|
||||
|
||||
it 'shows loading state during search' do
|
||||
fill_in 'location-search-input', with: 'Kaufland'
|
||||
within('#location-search-container') do
|
||||
click_button '🔍'
|
||||
end
|
||||
|
||||
# Should show loading indicator briefly
|
||||
expect(page).to have_content('Searching for "Kaufland"')
|
||||
end
|
||||
|
||||
it 'displays search results for existing locations' do
|
||||
fill_in 'location-search-input', with: 'Kaufland'
|
||||
within('#location-search-container') do
|
||||
click_button '🔍'
|
||||
end
|
||||
|
||||
# Wait for results to appear
|
||||
within('#location-search-results') do
|
||||
expect(page).to have_content('Kaufland Mitte')
|
||||
expect(page).to have_content('Alexanderplatz 1, Berlin')
|
||||
expect(page).to have_content('visit(s)')
|
||||
end
|
||||
end
|
||||
|
||||
it 'shows visit details in results' do
|
||||
fill_in 'location-search-input', with: 'Kaufland'
|
||||
within('#location-search-container') do
|
||||
click_button '🔍'
|
||||
end
|
||||
|
||||
within('#location-search-results') do
|
||||
# Should show visit timestamps and distances
|
||||
expect(page).to have_css('.location-result')
|
||||
expect(page).to have_content('m away') # distance indicator
|
||||
end
|
||||
end
|
||||
|
||||
it 'handles search with Enter key' do
|
||||
fill_in 'location-search-input', with: 'Kaufland'
|
||||
find('#location-search-input').send_keys(:enter)
|
||||
|
||||
within('#location-search-results') do
|
||||
expect(page).to have_content('Kaufland Mitte')
|
||||
end
|
||||
end
|
||||
|
||||
it 'displays appropriate message for no results' do
|
||||
fill_in 'location-search-input', with: 'NonexistentPlace'
|
||||
click_button '🔍'
|
||||
|
||||
within('#location-search-results') do
|
||||
expect(page).to have_content('No visits found for "NonexistentPlace"')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with search interaction' do
|
||||
before do
|
||||
# Show the search bar first
|
||||
find('#location-search-toggle').click
|
||||
end
|
||||
|
||||
it 'focuses search input when search bar is shown' do
|
||||
expect(page).to have_css('#location-search-input:focus')
|
||||
end
|
||||
|
||||
it 'closes search bar when Escape key is pressed' do
|
||||
find('#location-search-input').send_keys(:escape)
|
||||
|
||||
expect(page).to have_css('#location-search-container.hidden')
|
||||
end
|
||||
|
||||
it 'shows clear button when text is entered' do
|
||||
search_input = find('#location-search-input')
|
||||
clear_button = find('#location-search-clear')
|
||||
|
||||
expect(clear_button).not_to be_visible
|
||||
|
||||
search_input.fill_in(with: 'test')
|
||||
expect(clear_button).to be_visible
|
||||
end
|
||||
|
||||
it 'clears search when clear button is clicked' do
|
||||
search_input = find('#location-search-input')
|
||||
clear_button = find('#location-search-clear')
|
||||
|
||||
search_input.fill_in(with: 'test search')
|
||||
clear_button.click
|
||||
|
||||
expect(search_input.value).to be_empty
|
||||
expect(clear_button).not_to be_visible
|
||||
end
|
||||
|
||||
it 'hides results and search bar when clicking outside' do
|
||||
# First, show search bar and perform search
|
||||
find('#location-search-toggle').click
|
||||
fill_in 'location-search-input', with: 'Kaufland'
|
||||
within('#location-search-container') do
|
||||
click_button '🔍'
|
||||
end
|
||||
|
||||
# Wait for results to show
|
||||
expect(page).to have_css('#location-search-results:not(.hidden)')
|
||||
|
||||
# Click outside the search area (left side of map to avoid controls)
|
||||
page.execute_script("document.querySelector('#map').dispatchEvent(new MouseEvent('click', {clientX: 100, clientY: 200}))")
|
||||
|
||||
# Both results and search bar should be hidden
|
||||
expect(page).to have_css('#location-search-results.hidden')
|
||||
expect(page).to have_css('#location-search-container.hidden')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with map interaction' do
|
||||
before do
|
||||
# Show the search bar first
|
||||
find('#location-search-toggle').click
|
||||
end
|
||||
|
||||
it 'completes search and shows results without location markers' do
|
||||
fill_in 'location-search-input', with: 'Kaufland'
|
||||
within('#location-search-container') do
|
||||
click_button '🔍'
|
||||
end
|
||||
|
||||
# Wait for search to complete
|
||||
expect(page).to have_content('Kaufland Mitte')
|
||||
|
||||
# Verify search results are displayed (no location markers are added to keep map clean)
|
||||
expect(page).to have_content('Found 1 location(s)')
|
||||
end
|
||||
|
||||
it 'focuses map on clicked search result' do
|
||||
fill_in 'location-search-input', with: 'Kaufland'
|
||||
within('#location-search-container') do
|
||||
click_button '🔍'
|
||||
end
|
||||
|
||||
within('#location-search-results') do
|
||||
find('.location-result').click
|
||||
end
|
||||
|
||||
# Results should be hidden after clicking
|
||||
expect(page).to have_css('#location-search-results.hidden')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with error handling' do
|
||||
before do
|
||||
# Mock API to return error
|
||||
allow_any_instance_of(LocationSearch::PointFinder).to receive(:call).and_raise(StandardError.new('API Error'))
|
||||
end
|
||||
|
||||
it 'handles API errors gracefully' do
|
||||
fill_in 'location-search-input', with: 'test'
|
||||
click_button '🔍'
|
||||
|
||||
within('#location-search-results') do
|
||||
expect(page).to have_content('Failed to search locations')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with authentication' do
|
||||
it 'includes API key in search requests' do
|
||||
# This test verifies that the search component receives the API key
|
||||
# from the data attribute and includes it in requests
|
||||
|
||||
map_element = find('#map')
|
||||
expect(map_element['data-api_key']).to eq(user.api_key)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Search API Integration' do
|
||||
it 'makes authenticated requests to the search API' do
|
||||
# Test that the frontend makes proper API calls
|
||||
visit '/map'
|
||||
|
||||
fill_in 'location-search-input', with: 'Kaufland'
|
||||
|
||||
# Intercept the API request
|
||||
expect(page.driver.browser.manage).to receive(:add_cookie).with(
|
||||
hash_including(name: 'api_request_made')
|
||||
)
|
||||
|
||||
click_button '🔍'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Real-world Search Scenarios' do
|
||||
context 'with business name search' do
|
||||
it 'finds visits to business locations' do
|
||||
visit '/map'
|
||||
|
||||
fill_in 'location-search-input', with: 'Kaufland'
|
||||
click_button '🔍'
|
||||
|
||||
expect(page).to have_content('Kaufland Mitte')
|
||||
expect(page).to have_content('visit(s)')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with address search' do
|
||||
it 'handles street address searches' do
|
||||
visit '/map'
|
||||
|
||||
fill_in 'location-search-input', with: 'Alexanderplatz 1'
|
||||
click_button '🔍'
|
||||
|
||||
within('#location-search-results') do
|
||||
expect(page).to have_content('location(s)')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with multiple search terms' do
|
||||
it 'handles complex search queries' do
|
||||
visit '/map'
|
||||
|
||||
fill_in 'location-search-input', with: 'Kaufland Berlin'
|
||||
click_button '🔍'
|
||||
|
||||
# Should handle multi-word searches
|
||||
expect(page).to have_content('location(s) for "Kaufland Berlin"')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with real-time suggestions' do
|
||||
before do
|
||||
# Mock the geocoding service to return suggestions
|
||||
allow_any_instance_of(LocationSearch::GeocodingService).to receive(:search) do |_service, query|
|
||||
case query.downcase
|
||||
when /kau/
|
||||
[
|
||||
{
|
||||
lat: 52.5200,
|
||||
lon: 13.4050,
|
||||
name: 'Kaufland Mitte',
|
||||
address: 'Alexanderplatz 1, Berlin',
|
||||
type: 'shop'
|
||||
},
|
||||
{
|
||||
lat: 52.5100,
|
||||
lon: 13.4000,
|
||||
name: 'Kaufland Friedrichshain',
|
||||
address: 'Warschauer Str. 80, Berlin',
|
||||
type: 'shop'
|
||||
}
|
||||
]
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
# Show the search bar first
|
||||
find('#location-search-toggle').click
|
||||
end
|
||||
|
||||
it 'shows suggestions as user types' do
|
||||
search_input = find('#location-search-input')
|
||||
search_input.fill_in(with: 'Kau')
|
||||
|
||||
# Wait for debounced search to trigger
|
||||
sleep(0.4)
|
||||
|
||||
within('#location-search-suggestions') do
|
||||
expect(page).to have_content('Kaufland Mitte')
|
||||
expect(page).to have_content('Alexanderplatz 1, Berlin')
|
||||
expect(page).to have_content('Kaufland Friedrichshain')
|
||||
end
|
||||
end
|
||||
|
||||
it 'allows selecting suggestions with mouse click' do
|
||||
search_input = find('#location-search-input')
|
||||
search_input.fill_in(with: 'Kau')
|
||||
sleep(0.4)
|
||||
|
||||
within('#location-search-suggestions') do
|
||||
find('.suggestion-item', text: 'Kaufland Mitte').click
|
||||
end
|
||||
|
||||
expect(search_input.value).to eq('Kaufland Mitte')
|
||||
expect(page).to have_css('#location-search-suggestions.hidden')
|
||||
end
|
||||
|
||||
it 'allows keyboard navigation through suggestions' do
|
||||
search_input = find('#location-search-input')
|
||||
search_input.fill_in(with: 'Kau')
|
||||
sleep(0.4)
|
||||
|
||||
# Navigate down through suggestions
|
||||
search_input.send_keys(:arrow_down)
|
||||
within('#location-search-suggestions') do
|
||||
expect(page).to have_css('.suggestion-item.bg-blue-50', text: 'Kaufland Mitte')
|
||||
end
|
||||
|
||||
search_input.send_keys(:arrow_down)
|
||||
within('#location-search-suggestions') do
|
||||
expect(page).to have_css('.suggestion-item.bg-blue-50', text: 'Kaufland Friedrichshain')
|
||||
end
|
||||
|
||||
# Select with Enter
|
||||
search_input.send_keys(:enter)
|
||||
expect(search_input.value).to eq('Kaufland Friedrichshain')
|
||||
end
|
||||
|
||||
it 'hides suggestions when input is cleared' do
|
||||
search_input = find('#location-search-input')
|
||||
search_input.fill_in(with: 'Kau')
|
||||
sleep(0.4)
|
||||
|
||||
expect(page).to have_css('#location-search-suggestions:not(.hidden)')
|
||||
|
||||
search_input.set('')
|
||||
expect(page).to have_css('#location-search-suggestions.hidden')
|
||||
end
|
||||
|
||||
it 'hides suggestions on Escape key' do
|
||||
search_input = find('#location-search-input')
|
||||
search_input.fill_in(with: 'Kau')
|
||||
sleep(0.4)
|
||||
|
||||
expect(page).to have_css('#location-search-suggestions:not(.hidden)')
|
||||
|
||||
search_input.send_keys(:escape)
|
||||
expect(page).to have_css('#location-search-suggestions.hidden')
|
||||
end
|
||||
|
||||
it 'does not show suggestions for queries shorter than 2 characters' do
|
||||
search_input = find('#location-search-input')
|
||||
search_input.fill_in(with: 'K')
|
||||
sleep(0.4)
|
||||
|
||||
expect(page).to have_css('#location-search-suggestions.hidden')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sign_in(user)
|
||||
visit '/users/sign_in'
|
||||
# Try different selectors for email field
|
||||
if page.has_field?('Email')
|
||||
fill_in 'Email', with: user.email
|
||||
elsif page.has_field?('user_email')
|
||||
fill_in 'user_email', with: user.email
|
||||
elsif page.has_css('input[type="email"]')
|
||||
find('input[type="email"]').fill_in with: user.email
|
||||
else
|
||||
raise "Could not find email field"
|
||||
end
|
||||
|
||||
# Try different selectors for password field
|
||||
if page.has_field?('Password')
|
||||
fill_in 'Password', with: user.password
|
||||
elsif page.has_field?('user_password')
|
||||
fill_in 'user_password', with: user.password
|
||||
elsif page.has_css('input[type="password"]')
|
||||
find('input[type="password"]').fill_in with: user.password
|
||||
else
|
||||
raise "Could not find password field"
|
||||
end
|
||||
|
||||
click_button 'Log in'
|
||||
end
|
||||
end
|
||||
Loading…
Reference in a new issue