974 lines
42 KiB
TypeScript
974 lines
42 KiB
TypeScript
import * as moment from 'moment';
|
||
import { CITIES, MOCK_FLIGHTS_ARRIVAL, MOCK_FLIGHTS_DEPARTURE } from '../../support/fixtures';
|
||
|
||
describe('Online Board Feature Tests (~70 tests)', () => {
|
||
const today = moment().format('DD.MM.YYYY');
|
||
const tomorrow = moment().add(1, 'day').format('DD.MM.YYYY');
|
||
const yesterday = moment().subtract(1, 'day').format('DD.MM.YYYY');
|
||
const nextWeek = moment().add(7, 'day').format('DD.MM.YYYY');
|
||
|
||
const expectedUrlDateTime = `${moment().format('DDMMYYYY')}-0000-2400`;
|
||
|
||
beforeEach(() => {
|
||
cy.intercept('GET', '**/api/flights/v1.1/**').as('getFlights');
|
||
cy.intercept('GET', '**/api/cities/**').as('getCities');
|
||
cy.forbidGeolocation();
|
||
cy.visit('/');
|
||
});
|
||
|
||
// ============================================================================
|
||
// ARRIVAL TAB TESTS (~20 tests)
|
||
// ============================================================================
|
||
describe('Arrival Tab Tests', () => {
|
||
describe('City Input - Manual Entry', () => {
|
||
it('should accept manual city entry for valid city name', () => {
|
||
cy.getByTestId('city-autocomplete-input-arrival')
|
||
.clear()
|
||
.type('Москва');
|
||
cy.getByTestId('city-autocomplete-input-arrival')
|
||
.should('have.value', 'Москва');
|
||
});
|
||
|
||
it('should display dropdown suggestions for partial city name', () => {
|
||
cy.getByTestId('city-autocomplete-input-arrival')
|
||
.clear()
|
||
.type('Мос');
|
||
cy.getByTestId('city-dropdown-option')
|
||
.should('be.visible')
|
||
.should('have.length.greaterThan', 0);
|
||
});
|
||
|
||
it('should filter dropdown options based on input', () => {
|
||
cy.getByTestId('city-autocomplete-input-arrival')
|
||
.clear()
|
||
.type('Анапа');
|
||
cy.getByTestId('city-dropdown-option')
|
||
.contains('Анапа')
|
||
.should('be.visible');
|
||
});
|
||
|
||
it('should handle special characters in city input', () => {
|
||
cy.getByTestId('city-autocomplete-input-arrival')
|
||
.clear()
|
||
.type('М@сква');
|
||
// Should not crash and handle gracefully
|
||
cy.getByTestId('city-autocomplete-input-arrival').should('exist');
|
||
});
|
||
|
||
it('should clear city input when cleared explicitly', () => {
|
||
cy.getByTestId('city-autocomplete-input-arrival')
|
||
.clear()
|
||
.type('Москва');
|
||
cy.getByTestId('city-autocomplete-input-arrival').clear();
|
||
cy.getByTestId('city-autocomplete-input-arrival')
|
||
.should('have.value', '');
|
||
});
|
||
|
||
it('should show validation error for empty city input on search', () => {
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
cy.shouldShowValidationError('City');
|
||
});
|
||
});
|
||
|
||
describe('City Input - Dropdown Selection', () => {
|
||
it('should select city from dropdown by clicking', () => {
|
||
cy.getByTestId('city-autocomplete-input-arrival')
|
||
.clear()
|
||
.type('Москва');
|
||
cy.getByTestId('city-dropdown-option')
|
||
.contains('Москва')
|
||
.click();
|
||
cy.getByTestId('city-autocomplete-input-arrival')
|
||
.should('have.value', 'Москва');
|
||
});
|
||
|
||
it('should display city code after selection from dropdown', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('city-code')
|
||
.should('contain', 'MOW');
|
||
});
|
||
|
||
it('should allow switching between different cities using dropdown', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('city-code').should('contain', 'MOW');
|
||
|
||
cy.getByTestId('city-autocomplete-input-arrival').clear().type('Анапа');
|
||
cy.getByTestId('city-dropdown-option').contains('Анапа').click();
|
||
cy.getByTestId('city-code').should('contain', 'AAQ');
|
||
});
|
||
});
|
||
|
||
describe('Date Picker - Valid Dates', () => {
|
||
it('should accept valid today date', () => {
|
||
cy.getByTestId('arrival-date-input')
|
||
.clear()
|
||
.type(today)
|
||
.type('{enter}');
|
||
cy.getByTestId('arrival-date-input')
|
||
.should('have.value', today);
|
||
});
|
||
|
||
it('should accept valid future date (tomorrow)', () => {
|
||
cy.getByTestId('arrival-date-input')
|
||
.clear()
|
||
.type(tomorrow)
|
||
.type('{enter}');
|
||
cy.getByTestId('arrival-date-input')
|
||
.should('have.value', tomorrow);
|
||
});
|
||
|
||
it('should accept valid future date (one week)', () => {
|
||
cy.getByTestId('arrival-date-input')
|
||
.clear()
|
||
.type(nextWeek)
|
||
.type('{enter}');
|
||
cy.getByTestId('arrival-date-input')
|
||
.should('have.value', nextWeek);
|
||
});
|
||
});
|
||
|
||
describe('Date Picker - Invalid Dates', () => {
|
||
it('should reject past date (yesterday)', () => {
|
||
cy.getByTestId('arrival-date-input')
|
||
.clear()
|
||
.type(yesterday);
|
||
cy.getByTestId('search-button').click();
|
||
cy.shouldShowValidationError('date');
|
||
});
|
||
|
||
it('should handle invalid date format', () => {
|
||
cy.getByTestId('arrival-date-input')
|
||
.clear()
|
||
.type('invalid');
|
||
cy.getByTestId('search-button').click();
|
||
// Should show error or ignore invalid input
|
||
cy.getByTestId('validation-error').should('exist');
|
||
});
|
||
|
||
it('should show validation error when date field is empty on search', () => {
|
||
cy.getByTestId('arrival-date-input').clear();
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('search-button').click();
|
||
cy.shouldShowValidationError('date');
|
||
});
|
||
});
|
||
|
||
describe('Search - Valid and Error Cases', () => {
|
||
it('should perform valid arrival search with city and date', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.getByTestId('loader').should('be.visible');
|
||
cy.wait('@getFlights').then(() => {
|
||
cy.getByTestId('board-search-result').should('be.visible');
|
||
});
|
||
});
|
||
|
||
it('should show validation error when missing city field', () => {
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
cy.shouldShowValidationError('City');
|
||
});
|
||
|
||
it('should show validation error when missing date field', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('search-button').click();
|
||
cy.shouldShowValidationError('date');
|
||
});
|
||
|
||
it('should handle network error gracefully', () => {
|
||
cy.intercept('GET', '**/api/flights/v1.1/**', {
|
||
statusCode: 500,
|
||
body: { error: 'Internal Server Error' },
|
||
}).as('getFlightsError');
|
||
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlightsError');
|
||
cy.getByTestId('error-message').should('be.visible');
|
||
});
|
||
|
||
it('should show loading state during search', () => {
|
||
cy.intercept('GET', '**/api/flights/v1.1/**', (req) => {
|
||
req.reply((res) => {
|
||
res.delay(1000);
|
||
});
|
||
}).as('getFlightsSlow');
|
||
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.getByTestId('loader').should('be.visible');
|
||
cy.wait('@getFlightsSlow');
|
||
});
|
||
});
|
||
|
||
describe('Results - Flight List Rendering', () => {
|
||
it('should render flight list after successful search', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFlightResults().should('have.length.greaterThan', 0);
|
||
});
|
||
|
||
it('should display all required flight information in results', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().within(() => {
|
||
cy.getByTestId('flight-carrier-number').should('be.visible');
|
||
cy.getByTestId('flight-status').should('be.visible');
|
||
cy.getByTestId('flight-time').should('be.visible');
|
||
});
|
||
});
|
||
});
|
||
|
||
describe('Results - Flight Details Modal', () => {
|
||
it('should open flight details modal on flight click', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
cy.getByTestId('flight-details-modal').should('be.visible');
|
||
});
|
||
|
||
it('should display all flight info in modal (number, times, gate, terminal)', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
|
||
cy.getByTestId('flight-details-number').should('be.visible');
|
||
cy.getByTestId('flight-details-time').should('be.visible');
|
||
cy.getByTestId('flight-details-gate').should('be.visible');
|
||
cy.getByTestId('flight-details-terminal').should('be.visible');
|
||
});
|
||
|
||
it('should close modal when clicking X button', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
cy.getByTestId('flight-details-modal').should('be.visible');
|
||
|
||
cy.getByTestId('modal-close-button').click();
|
||
cy.getByTestId('flight-details-modal').should('not.be.visible');
|
||
});
|
||
|
||
it('should close modal when pressing Escape key', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
cy.getByTestId('flight-details-modal').should('be.visible');
|
||
|
||
cy.get('body').type('{esc}');
|
||
cy.getByTestId('flight-details-modal').should('not.be.visible');
|
||
});
|
||
|
||
it('should close modal when clicking outside modal', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
cy.getByTestId('flight-details-modal').should('be.visible');
|
||
|
||
cy.getByTestId('modal-backdrop').click({ force: true });
|
||
cy.getByTestId('flight-details-modal').should('not.be.visible');
|
||
});
|
||
});
|
||
|
||
describe('Filter Persistence', () => {
|
||
it('should preserve arrival filters when navigating back', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
cy.getByTestId('flight-details-modal').should('be.visible');
|
||
|
||
// Navigate back
|
||
cy.go('back');
|
||
|
||
// Filters should still be present
|
||
cy.getByTestId('city-autocomplete-input-arrival').should('have.value', 'Москва');
|
||
cy.getByTestId('arrival-date-input').should('have.value', today);
|
||
});
|
||
});
|
||
});
|
||
|
||
// ============================================================================
|
||
// DEPARTURE TAB TESTS (~20 tests)
|
||
// ============================================================================
|
||
describe('Departure Tab Tests', () => {
|
||
beforeEach(() => {
|
||
cy.getByTestId('departure-tab').click();
|
||
});
|
||
|
||
describe('City Input - Manual Entry', () => {
|
||
it('should accept manual city entry for departure', () => {
|
||
cy.getByTestId('city-autocomplete-input-departure')
|
||
.clear()
|
||
.type('Москва');
|
||
cy.getByTestId('city-autocomplete-input-departure')
|
||
.should('have.value', 'Москва');
|
||
});
|
||
|
||
it('should display dropdown suggestions for departure city', () => {
|
||
cy.getByTestId('city-autocomplete-input-departure')
|
||
.clear()
|
||
.type('Мос');
|
||
cy.getByTestId('city-dropdown-option')
|
||
.should('be.visible');
|
||
});
|
||
|
||
it('should filter dropdown options for departure based on input', () => {
|
||
cy.getByTestId('city-autocomplete-input-departure')
|
||
.clear()
|
||
.type('Казань');
|
||
cy.getByTestId('city-dropdown-option')
|
||
.contains('Казань')
|
||
.should('be.visible');
|
||
});
|
||
|
||
it('should show validation error for empty departure city on search', () => {
|
||
cy.getByTestId('departure-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
cy.shouldShowValidationError('City');
|
||
});
|
||
});
|
||
|
||
describe('City Input - Dropdown Selection', () => {
|
||
it('should select departure city from dropdown', () => {
|
||
cy.selectDepartureCity('Москва');
|
||
cy.getByTestId('city-autocomplete-input-departure')
|
||
.should('have.value', 'Москва');
|
||
});
|
||
|
||
it('should display departure city code after selection', () => {
|
||
cy.selectDepartureCity('Москва');
|
||
cy.getByTestId('city-code').should('contain', 'MOW');
|
||
});
|
||
|
||
it('should allow switching between different departure cities', () => {
|
||
cy.selectDepartureCity('Москва');
|
||
cy.getByTestId('city-code').should('contain', 'MOW');
|
||
|
||
cy.getByTestId('city-autocomplete-input-departure').clear().type('Казань');
|
||
cy.getByTestId('city-dropdown-option').contains('Казань').click();
|
||
cy.getByTestId('city-code').should('contain', 'KZN');
|
||
});
|
||
});
|
||
|
||
describe('Date Picker - Valid Dates', () => {
|
||
it('should accept valid today date for departure', () => {
|
||
cy.getByTestId('departure-date-input')
|
||
.clear()
|
||
.type(today)
|
||
.type('{enter}');
|
||
cy.getByTestId('departure-date-input')
|
||
.should('have.value', today);
|
||
});
|
||
|
||
it('should accept valid future date for departure', () => {
|
||
cy.getByTestId('departure-date-input')
|
||
.clear()
|
||
.type(tomorrow)
|
||
.type('{enter}');
|
||
cy.getByTestId('departure-date-input')
|
||
.should('have.value', tomorrow);
|
||
});
|
||
});
|
||
|
||
describe('Date Picker - Invalid Dates', () => {
|
||
it('should reject past date for departure', () => {
|
||
cy.getByTestId('departure-date-input')
|
||
.clear()
|
||
.type(yesterday);
|
||
cy.selectDepartureCity('Москва');
|
||
cy.getByTestId('search-button').click();
|
||
cy.shouldShowValidationError('date');
|
||
});
|
||
|
||
it('should show validation error when departure date is empty on search', () => {
|
||
cy.getByTestId('departure-date-input').clear();
|
||
cy.selectDepartureCity('Москва');
|
||
cy.getByTestId('search-button').click();
|
||
cy.shouldShowValidationError('date');
|
||
});
|
||
});
|
||
|
||
describe('Search - Valid and Error Cases', () => {
|
||
it('should perform valid departure search', () => {
|
||
cy.selectDepartureCity('Москва');
|
||
cy.getByTestId('departure-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.getByTestId('loader').should('be.visible');
|
||
cy.wait('@getFlights').then(() => {
|
||
cy.getByTestId('board-search-result').should('be.visible');
|
||
});
|
||
});
|
||
|
||
it('should handle network error for departure search', () => {
|
||
cy.intercept('GET', '**/api/flights/v1.1/**', {
|
||
statusCode: 500,
|
||
}).as('getFlightsError');
|
||
|
||
cy.selectDepartureCity('Москва');
|
||
cy.getByTestId('departure-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlightsError');
|
||
cy.getByTestId('error-message').should('be.visible');
|
||
});
|
||
|
||
it('should show loading state during departure search', () => {
|
||
cy.intercept('GET', '**/api/flights/v1.1/**', (req) => {
|
||
req.reply((res) => {
|
||
res.delay(1000);
|
||
});
|
||
}).as('getFlightsSlow');
|
||
|
||
cy.selectDepartureCity('Москва');
|
||
cy.getByTestId('departure-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.getByTestId('loader').should('be.visible');
|
||
});
|
||
});
|
||
|
||
describe('Results - Flight List', () => {
|
||
it('should render departure flight list after successful search', () => {
|
||
cy.selectDepartureCity('Москва');
|
||
cy.getByTestId('departure-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFlightResults().should('have.length.greaterThan', 0);
|
||
});
|
||
|
||
it('should display required flight information in departure results', () => {
|
||
cy.selectDepartureCity('Москва');
|
||
cy.getByTestId('departure-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().within(() => {
|
||
cy.getByTestId('flight-carrier-number').should('be.visible');
|
||
cy.getByTestId('flight-status').should('be.visible');
|
||
});
|
||
});
|
||
});
|
||
|
||
describe('Results - Flight Details Modal for Departure', () => {
|
||
it('should open flight details modal for departure flight', () => {
|
||
cy.selectDepartureCity('Москва');
|
||
cy.getByTestId('departure-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
cy.getByTestId('flight-details-modal').should('be.visible');
|
||
});
|
||
|
||
it('should display complete flight details for departure', () => {
|
||
cy.selectDepartureCity('Москва');
|
||
cy.getByTestId('departure-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
|
||
cy.getByTestId('flight-details-number').should('be.visible');
|
||
cy.getByTestId('flight-details-gate').should('be.visible');
|
||
cy.getByTestId('flight-details-terminal').should('be.visible');
|
||
});
|
||
|
||
it('should close departure flight details modal on X click', () => {
|
||
cy.selectDepartureCity('Москва');
|
||
cy.getByTestId('departure-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
cy.getByTestId('flight-details-modal').should('be.visible');
|
||
|
||
cy.getByTestId('modal-close-button').click();
|
||
cy.getByTestId('flight-details-modal').should('not.be.visible');
|
||
});
|
||
});
|
||
|
||
describe('Filter Persistence for Departure', () => {
|
||
it('should preserve departure filters when navigating back', () => {
|
||
cy.selectDepartureCity('Москва');
|
||
cy.getByTestId('departure-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
|
||
cy.go('back');
|
||
|
||
cy.getByTestId('city-autocomplete-input-departure').should('have.value', 'Москва');
|
||
cy.getByTestId('departure-date-input').should('have.value', today);
|
||
});
|
||
});
|
||
});
|
||
|
||
// ============================================================================
|
||
// TAB SWITCHING TESTS (~5 tests)
|
||
// ============================================================================
|
||
describe('Tab Switching Tests', () => {
|
||
it('should switch from arrival tab to departure tab', () => {
|
||
cy.getByTestId('arrival-tab').should('have.class', 'active');
|
||
cy.getByTestId('departure-tab').click();
|
||
cy.getByTestId('departure-tab').should('have.class', 'active');
|
||
});
|
||
|
||
it('should switch from departure tab back to arrival tab', () => {
|
||
cy.getByTestId('departure-tab').click();
|
||
cy.getByTestId('departure-tab').should('have.class', 'active');
|
||
cy.getByTestId('arrival-tab').click();
|
||
cy.getByTestId('arrival-tab').should('have.class', 'active');
|
||
});
|
||
|
||
it('should maintain separate state for arrival and departure tabs', () => {
|
||
// Set arrival filter
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('city-autocomplete-input-arrival').should('have.value', 'Москва');
|
||
|
||
// Switch to departure
|
||
cy.getByTestId('departure-tab').click();
|
||
cy.getByTestId('city-autocomplete-input-departure').should('have.value', '');
|
||
|
||
// Switch back to arrival
|
||
cy.getByTestId('arrival-tab').click();
|
||
cy.getByTestId('city-autocomplete-input-arrival').should('have.value', 'Москва');
|
||
});
|
||
|
||
it('should preserve departure state when switching tabs', () => {
|
||
cy.getByTestId('departure-tab').click();
|
||
cy.selectDepartureCity('Казань');
|
||
cy.getByTestId('city-autocomplete-input-departure').should('have.value', 'Казань');
|
||
|
||
cy.getByTestId('arrival-tab').click();
|
||
cy.getByTestId('departure-tab').click();
|
||
|
||
cy.getByTestId('city-autocomplete-input-departure').should('have.value', 'Казань');
|
||
});
|
||
});
|
||
|
||
// ============================================================================
|
||
// FLIGHT NUMBER FILTER TESTS (~15 tests)
|
||
// ============================================================================
|
||
describe('Flight Number Filter Tests', () => {
|
||
describe('Basic Flight Number Filtering', () => {
|
||
it('should filter results by flight number', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getByTestId('flight-number-filter').clear().type('SU001');
|
||
|
||
cy.getFlightResults().should('have.length', 1);
|
||
cy.getFirstFlightResult().should('contain', 'SU001');
|
||
});
|
||
|
||
it('should filter flights by partial flight number', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getByTestId('flight-number-filter').clear().type('001');
|
||
|
||
cy.getFlightResults().should('have.length', 1);
|
||
});
|
||
|
||
it('should handle no results when filtering by non-existent flight number', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getByTestId('flight-number-filter').clear().type('ZZ999');
|
||
|
||
cy.getByTestId('no-results-message').should('be.visible');
|
||
cy.getFlightResults().should('have.length', 0);
|
||
});
|
||
|
||
it('should be case-insensitive when filtering flight numbers', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getByTestId('flight-number-filter').clear().type('su001');
|
||
|
||
cy.getFlightResults().should('have.length', 1);
|
||
cy.getFirstFlightResult().should('contain', 'SU001');
|
||
});
|
||
});
|
||
|
||
describe('Flight Number Filter - Special Characters', () => {
|
||
it('should handle special characters in flight number filter gracefully', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getByTestId('flight-number-filter').clear().type('SU@001');
|
||
|
||
// Should not crash, display no results or handle gracefully
|
||
cy.getByTestId('flight-number-filter').should('exist');
|
||
});
|
||
|
||
it('should handle empty flight number filter (no filter applied)', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFlightResults().should('have.length.greaterThan', 0);
|
||
});
|
||
|
||
it('should ignore leading/trailing spaces in flight number filter', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getByTestId('flight-number-filter').clear().type(' SU001 ');
|
||
|
||
cy.getFlightResults().should('have.length', 1);
|
||
});
|
||
});
|
||
|
||
describe('Flight Number Filter - Clear Filter', () => {
|
||
it('should clear flight number filter', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFlightResults().then((flights) => {
|
||
const initialCount = flights.length;
|
||
|
||
cy.getByTestId('flight-number-filter').clear().type('SU001');
|
||
cy.getFlightResults().should('have.length', 1);
|
||
|
||
cy.getByTestId('flight-number-filter').clear();
|
||
cy.getFlightResults().should('have.length', initialCount);
|
||
});
|
||
});
|
||
|
||
it('should reset filter when clicking clear button', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getByTestId('flight-number-filter').clear().type('SU001');
|
||
cy.getFlightResults().should('have.length', 1);
|
||
|
||
cy.getByTestId('clear-flight-filter-button').click();
|
||
cy.getByTestId('flight-number-filter').should('have.value', '');
|
||
cy.getFlightResults().should('have.length.greaterThan', 1);
|
||
});
|
||
|
||
it('should update results in real-time as user types in flight number filter', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFlightResults().then((flights) => {
|
||
const initialCount = flights.length;
|
||
|
||
cy.getByTestId('flight-number-filter').type('0');
|
||
cy.getFlightResults().should('have.length.lessThan', initialCount);
|
||
|
||
cy.getByTestId('flight-number-filter').type('01');
|
||
cy.getFlightResults().should('have.length', 1);
|
||
});
|
||
});
|
||
});
|
||
|
||
describe('Flight Number Filter - Integration with Other Filters', () => {
|
||
it('should combine flight number filter with date filter', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFlightResults().should('have.length.greaterThan', 0);
|
||
|
||
cy.getByTestId('flight-number-filter').clear().type('SU001');
|
||
cy.getFlightResults().should('have.length', 1);
|
||
|
||
// Change date and verify filter still works
|
||
cy.getByTestId('arrival-date-input').clear().type(tomorrow).type('{enter}');
|
||
cy.getByTestId('flight-number-filter').should('have.value', 'SU001');
|
||
});
|
||
|
||
it('should preserve flight number filter when switching between tabs', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getByTestId('flight-number-filter').clear().type('SU001');
|
||
|
||
cy.getByTestId('departure-tab').click();
|
||
cy.getByTestId('arrival-tab').click();
|
||
|
||
// Filter might not persist across tabs, but should not crash
|
||
cy.getByTestId('flight-number-filter').should('exist');
|
||
});
|
||
});
|
||
});
|
||
|
||
// ============================================================================
|
||
// FLIGHT DETAILS MODAL TESTS (~15 tests)
|
||
// ============================================================================
|
||
describe('Flight Details Modal Tests', () => {
|
||
describe('Modal Opening and Closing', () => {
|
||
it('should open modal when clicking on flight result', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
cy.getByTestId('flight-details-modal').should('be.visible');
|
||
});
|
||
|
||
it('should close modal with close button (X)', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
cy.getByTestId('flight-details-modal').should('be.visible');
|
||
|
||
cy.getByTestId('modal-close-button').click();
|
||
cy.getByTestId('flight-details-modal').should('not.exist');
|
||
});
|
||
|
||
it('should close modal when pressing Escape key', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
cy.getByTestId('flight-details-modal').should('be.visible');
|
||
|
||
cy.get('body').type('{esc}');
|
||
cy.getByTestId('flight-details-modal').should('not.exist');
|
||
});
|
||
|
||
it('should close modal when clicking outside (backdrop)', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
cy.getByTestId('flight-details-modal').should('be.visible');
|
||
|
||
cy.getByTestId('modal-backdrop').click({ force: true });
|
||
cy.getByTestId('flight-details-modal').should('not.exist');
|
||
});
|
||
});
|
||
|
||
describe('Modal Content - Flight Information Display', () => {
|
||
it('should display flight number in modal', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
|
||
cy.getByTestId('flight-details-number').should('be.visible')
|
||
.should('contain', 'SU');
|
||
});
|
||
|
||
it('should display estimated arrival time in modal', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
|
||
cy.getByTestId('flight-details-time').should('be.visible');
|
||
});
|
||
|
||
it('should display gate information in modal', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
|
||
cy.getByTestId('flight-details-gate').should('be.visible')
|
||
.should('contain', 'Gate');
|
||
});
|
||
|
||
it('should display terminal information in modal', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
|
||
cy.getByTestId('flight-details-terminal').should('be.visible')
|
||
.should('contain', 'Terminal');
|
||
});
|
||
|
||
it('should display flight status in modal', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
|
||
cy.getByTestId('flight-details-status').should('be.visible');
|
||
});
|
||
|
||
it('should display aircraft type in modal', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
|
||
cy.getByTestId('flight-details-aircraft').should('be.visible');
|
||
});
|
||
});
|
||
|
||
describe('Modal Navigation', () => {
|
||
it('should navigate to next flight using next button in modal', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
|
||
const firstFlightNumber = cy.getByTestId('flight-details-number');
|
||
cy.getByTestId('modal-next-button').click();
|
||
|
||
cy.getByTestId('flight-details-number')
|
||
.should('not.equal', firstFlightNumber);
|
||
});
|
||
|
||
it('should navigate to previous flight using prev button in modal', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFlightResults().then((flights) => {
|
||
if (flights.length > 1) {
|
||
cy.getByTestId('flight-result').eq(1).click();
|
||
cy.getByTestId('modal-prev-button').click();
|
||
cy.getByTestId('flight-details-modal').should('be.visible');
|
||
}
|
||
});
|
||
});
|
||
|
||
it('should disable prev button on first flight', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
|
||
cy.getByTestId('modal-prev-button').should('be.disabled');
|
||
});
|
||
|
||
it('should disable next button on last flight', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFlightResults().then((flights) => {
|
||
cy.getByTestId('flight-result').eq(flights.length - 1).click();
|
||
cy.getByTestId('modal-next-button').should('be.disabled');
|
||
});
|
||
});
|
||
});
|
||
|
||
describe('Modal Display and Responsiveness', () => {
|
||
it('should center modal on screen', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
|
||
cy.getByTestId('flight-details-modal').should('be.visible');
|
||
cy.getByTestId('flight-details-modal')
|
||
.should('have.css', 'position')
|
||
.and('match', /absolute|fixed/);
|
||
});
|
||
|
||
it('should prevent scrolling on body when modal is open', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
|
||
cy.get('body').should('have.css', 'overflow', 'hidden');
|
||
});
|
||
|
||
it('should restore body scrolling when modal closes', () => {
|
||
cy.selectArrivalCity('Москва');
|
||
cy.getByTestId('arrival-date-input').clear().type(today).type('{enter}');
|
||
cy.getByTestId('search-button').click();
|
||
|
||
cy.wait('@getFlights');
|
||
cy.getFirstFlightResult().click();
|
||
cy.getByTestId('modal-close-button').click();
|
||
|
||
cy.get('body').should('not.have.css', 'overflow', 'hidden');
|
||
});
|
||
});
|
||
});
|
||
});
|