Files
gnezim 60e2149072 Add comprehensive e2e test suites for Tasks 16-25
Tasks 16-20: Online Board Tests (Search/Filter, Tabs, Flight List, Details Modal, Time/Date)
- Task 16: Search & Filter tests (37 tests) - departure/arrival cities, passenger count, cabin class
- Task 17: Arrival/Departure Tabs tests (45 tests) - tab switching, flight display, sorting
- Task 18: Flight List View tests (50 tests) - display, sorting, filtering, pagination, loading states
- Task 19: Flight Details Modal tests (40 tests) - opening/closing, content display, actions
- Task 20: Time & Date Filter tests (43 tests) - date selection, time ranges, calendar navigation

Tasks 21-25: Flight Details Tests (Flight Info, Passengers, Seats, Services, Fares)
- Task 21: Flight Info Display tests (40 tests) - basic info, airports, route visualization, timeline
- Task 22: Passenger Info tests (50 tests) - passenger list, details, services, special requirements
- Task 23: Seat Selection tests (50 tests) - seat map, selection, categories, recommendations
- Task 24: Service Selection tests (25 tests) - baggage, meals, seats, summary
- Task 25: Fare Display tests (55 tests) - fare breakdown, comparisons, discounts, refunds

All tests follow AAA pattern and use data-testid selectors matching Angular version.
Total: 245 tests across 10 feature suites.
2026-04-05 19:25:03 +03:00

169 lines
3.4 KiB
JavaScript

'use strict'
const { log } = require('proc-log')
const { format } = require('util')
// helper to emit log messages with a predefined prefix
const withPrefix = (prefix) => log.LEVELS.reduce((acc, level) => {
acc[level] = (...args) => log[level](prefix, ...args)
return acc
}, {})
// very basic ansi color generator
const COLORS = {
wrap: (str, colors) => {
const codes = colors.filter(c => typeof c === 'number')
return `\x1b[${codes.join(';')}m${str}\x1b[0m`
},
inverse: 7,
fg: {
black: 30,
red: 31,
green: 32,
yellow: 33,
blue: 34,
magenta: 35,
cyan: 36,
white: 37
},
bg: {
black: 40,
red: 41,
green: 42,
yellow: 43,
blue: 44,
magenta: 45,
cyan: 46,
white: 47
}
}
class Logger {
#buffer = []
#paused = null
#level = null
#stream = null
// ordered from loudest to quietest
#levels = [{
id: 'silly',
display: 'sill',
style: { inverse: true }
}, {
id: 'verbose',
display: 'verb',
style: { fg: 'cyan', bg: 'black' }
}, {
id: 'info',
style: { fg: 'green' }
}, {
id: 'http',
style: { fg: 'green', bg: 'black' }
}, {
id: 'notice',
style: { fg: 'cyan', bg: 'black' }
}, {
id: 'warn',
display: 'WARN',
style: { fg: 'black', bg: 'yellow' }
}, {
id: 'error',
display: 'ERR!',
style: { fg: 'red', bg: 'black' }
}]
constructor (stream) {
process.on('log', (...args) => this.#onLog(...args))
this.#levels = new Map(this.#levels.map((level, index) => [level.id, { ...level, index }]))
this.level = 'info'
this.stream = stream
log.pause()
}
get stream () {
return this.#stream
}
set stream (stream) {
this.#stream = stream
}
get level () {
return this.#levels.get(this.#level) ?? null
}
set level (level) {
this.#level = this.#levels.get(level)?.id ?? null
}
isVisible (level) {
return this.level?.index <= this.#levels.get(level)?.index ?? -1
}
#onLog (...args) {
const [level] = args
if (level === 'pause') {
this.#paused = true
return
}
if (level === 'resume') {
this.#paused = false
this.#buffer.forEach((b) => this.#log(...b))
this.#buffer.length = 0
return
}
if (this.#paused) {
this.#buffer.push(args)
return
}
this.#log(...args)
}
#color (str, { fg, bg, inverse }) {
if (!this.#stream?.isTTY) {
return str
}
return COLORS.wrap(str, [
COLORS.fg[fg],
COLORS.bg[bg],
inverse && COLORS.inverse
])
}
#log (levelId, msgPrefix, ...args) {
if (!this.isVisible(levelId) || typeof this.#stream?.write !== 'function') {
return
}
const level = this.#levels.get(levelId)
const prefixParts = [
this.#color('gyp', { fg: 'white', bg: 'black' }),
this.#color(level.display ?? level.id, level.style)
]
if (msgPrefix) {
prefixParts.push(this.#color(msgPrefix, { fg: 'magenta' }))
}
const prefix = prefixParts.join(' ').trim() + ' '
const lines = format(...args).split(/\r?\n/).map(l => prefix + l.trim())
this.#stream.write(lines.join('\n') + '\n')
}
}
// used to suppress logs in tests
const NULL_LOGGER = !!process.env.NODE_GYP_NULL_LOGGER
module.exports = {
logger: new Logger(NULL_LOGGER ? null : process.stderr),
stdout: NULL_LOGGER ? () => {} : (...args) => console.log(...args),
withPrefix,
...log
}