# Testing Booking.js

This document explains the testing strategy, tools, and workflows for the Booking.js widget.

## Overview

The test suite is designed to verify the widget's behavior in a headless browser environment. It covers initialization, configuration overrides, UI interactions, timezone handling, and API integration (via mocks).

## Tech Stack

- **[Jasmine](https://jasmine.github.io/):** The core testing framework (BDD style).
- **[Karma](https://karma-runner.github.io/):** The test runner that executes code in a browser.
- **[Puppeteer](https://pptr.dev/):** Used to provide a headless Chrome instance (`ChromeHeadless`).
- **[Browserify](http://browserify.org/):** Bundles the CommonJS modules and specs for the browser.
- **[Jasmine-Ajax](https://github.com/jasmine/jasmine-ajax):** Intercepts and mocks network requests.

## Running Tests

### Local Execution
To run the full test suite once:
```bash
yarn test
```

### Development Mode
To keep the test runner open and re-run tests on file changes:
```bash
yarn test:watch
```

## Mocking API Interactions

**Crucial:** Tests do NOT contact the real Timekit API. All network requests to `https://api.timekit.io` are intercepted using `jasmine-ajax`.

- **Helper:** `test/utils/mockAjax.js` contains pre-defined responses for common endpoints (Availability, Bookings, Projects).
- **Setup:** Every test file typically initializes mocks in a `beforeEach` block:
  ```javascript
  beforeEach(function() {
    jasmine.Ajax.install();
    mockAjax.all(); // Mocks common successful responses
  });
  ```
- **Custom Responses:** You can use specific mock methods to simulate errors or edge cases:
  ```javascript
  mockAjax.findTimeWithError();
  mockAjax.findTimeWithNoTimeslots();
  ```

## Test Structure

- `test/*.spec.js`: The actual test files.
- `test/fixtures/`: HTML files used as the base DOM for tests (e.g., `main.html`).
- `test/utils/`:
    - `createWidget.js`: Helper to instantiate and initialize the widget with custom config.
    - `commonInteractions.js`: Shared logic for simulated user actions (clicking arrows, filling forms).
    - `defaultConfig.js`: The baseline configuration used for most tests.

## Key Testing Areas

1.  **Initialization:** Verifying singleton vs. instance patterns.
2.  **Configuration:** Ensuring that supplied JS objects or remote project configs are correctly applied.
3.  **Timezones:** Testing that dates/times shift correctly when a user changes their timezone in the footer.
4.  **Responsiveness:** Using the `viewport` plugin to simulate mobile devices and verify UI adjustments (e.g., switching to day view).
5.  **Booking Flow:** Simulating the end-to-end process of selecting a slot, filling the form, and receiving a success message.

## CI/CD Integration

Tests run automatically on every Merge Request via GitLab CI.

- **Environment:** The pipeline uses a `node:18` image.
- **Headless Chrome:** Since CI runs as root, Chrome is launched with the `--no-sandbox` flag (configured in `karma.conf.js` under the `ChromeHeadlessNoSandbox` launcher).
- **Dependencies:** The CI environment installs several Linux system libraries (e.g., `libnss3`) required by Puppeteer/Chrome.
