diff --git a/.commitlintrc.js b/.commitlintrc.js new file mode 100644 index 0000000..84dcb12 --- /dev/null +++ b/.commitlintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: ['@commitlint/config-conventional'], +}; diff --git a/.czrc b/.czrc new file mode 100644 index 0000000..90c38db --- /dev/null +++ b/.czrc @@ -0,0 +1,3 @@ +{ + "path": "./node_modules/cz-conventional-changelog" +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..08d8481 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6313b56 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..7a165e1 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,47 @@ +name: CI Workflow + +on: + push: + branches: + - main + pull_request: + branches: + - '**' + +jobs: + ci: + name: CI and Release Pipeline + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Run linting + run: npm run lint:ci + + - name: Run unit tests + run: npm test + + - name: Build project + run: npm run build + + - name: Run package-e2e tests + working-directory: package-e2e + run: | + npm install + npm test + + - name: Semantic Release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + run: npx semantic-release diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..591ace4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +# Node +coverage/ +dist/ +node_modules/ + +# Logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea/ +.vscode/ +!.idea/icon.svg + +# OS-specific files +.DS_Store diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..1fb913e --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npm run lint:staged diff --git a/.lintstagedrc.js b/.lintstagedrc.js new file mode 100644 index 0000000..f473103 --- /dev/null +++ b/.lintstagedrc.js @@ -0,0 +1,3 @@ +module.exports = { + '*.{js,jsx,ts,tsx,json,md}': ['eslint --fix'] +}; diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..deed13c --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +lts/jod diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..5d23c8b --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "printWidth": 100, + "singleQuote": true, + "trailingComma": "es5", + "semi": true +} diff --git a/API.md b/API.md new file mode 100644 index 0000000..704a881 --- /dev/null +++ b/API.md @@ -0,0 +1,105 @@ +# API Overview + +`allure-store` is built around a central `AllureStore` class that abstracts reading, writing, and transforming Allure data. It uses pluggable `AllureReader` and `AllureWriter` interfaces to allow custom data sources and destinations. + +## High-Level Architecture + +The core components are: + +- **AllureStore**: A single interface for reading and writing Allure data. It delegates low-level operations to `AllureReader` and `AllureWriter` implementations. +- **AllureReader**: Responsible for fetching Allure data (containers, results, categories, environment, executor) from a source (e.g., filesystem, database). +- **AllureWriter**: Responsible for persisting Allure data back to some storage medium (e.g., writing JSON files, updating a database, etc.). + +By default, `allure-store` provides: + +- `FileAllureReader`: Reads Allure data from a directory containing `*-result.json`, `*-container.json`, `categories.json`, `environment.properties`, and optionally `executor.json`. +- `FileAllureWriter`: Writes data back to a directory using the Allure standard file formats. + +## `AllureStore` Lifecycle + +1. **Initialization**: + Use `fromDirectory` or `fromConfig` to create and initialize an `AllureStore` instance. + - `fromDirectory(resultsDir, options?)`: + - Creates a `FileAllureReader` and `FileAllureWriter` based on the provided directory. + - Optional `overwrite` parameter to clear the directory before writing new data. + - Optional `onError` parameter controlling error handling (`'throw' | 'ignore' | (err: Error) => void`). + - `fromConfig({ reader, writer })`: + - Use a custom reader/writer combination. + +2. **Reading Data**: + Once you have an `AllureStore` instance: + - `getAllResults()`: Returns all results, including merged steps from ancestor containers. + - `getLatestResults()`: Returns only the most recent result per `historyId`. + - `getCategories()`: Fetches categories defined for the test results. + - `getEnvironment()`: Fetches environment properties. + - `getExecutor()`: Fetches executor info (CI system, etc.). + - `getContainer(id: string)`: Fetches a specific container. + - `getResult(id: string)`: Fetches a specific test result. + +3. **Writing Data**: + `AllureStore` also provides methods to write data back to your storage: + - `writeCategories(categories: Category[])`: Updates the categories file. + - `writeEnvironmentInfo(info: Record)`: Writes environment properties. + - `writeExecutorInfo(info: ExecutorInfo)`: Writes executor information. + - `writeContainer(container: Container)`: Writes an `*-container.json` file. + - `writeResult(result: Result)`: Writes a `*-result.json` file. + +4. **Customization & Extensibility**: + - Create custom `AllureReader` and `AllureWriter` classes to support non-file-based stores: + ```typescript + class MyDatabaseReader implements AllureReader { + async getContainerIds() { /* query DB */ } + async getResultIds() { /* query DB */ } + async readContainer(id: string) { /* fetch container from DB */ } + async readResult(id: string) { /* fetch result from DB */ } + async readCategories() { /* fetch categories */ } + async readEnvironmentInfo() { /* fetch environment info */ } + async readExecutorInfo() { /* fetch executor info */ } + } + ``` + + - Similarly, implement `AllureWriter` to save data to a desired location. + +## Data Structures + +The core Allure data types follow the Allure data model: + +- **Result**: Represents a single test’s execution data: `uuid`, `historyId`, `name`, `status`, `steps`, etc. +- **Container**: Groups related tests (results) and includes `befores` and `afters` steps. +- **Category**: Defines a set of conditions (e.g., regex-based) to group tests into categories. +- **Environment Info**: Key-value pairs describing the environment (e.g., `NODE_ENV=production`). +- **Executor Info**: Metadata about the system that ran the tests (e.g., CI pipeline details). + +For full type definitions, see the TypeScript declarations in [src/types.ts](./src/types.ts). + +## Error Handling + +Both `FileAllureReader` and `FileAllureWriter` accept an `onError` parameter. This can be: + +- `'throw'` (default): Throw an error to be handled by your application. +- `'ignore'`: Suppress errors silently. +- A custom function `(error: Error) => void`: Log or track errors according to your needs. + +## Practical Examples + +- **Merging Historical Results**: + You might have multiple runs of the same test (differentiated by `historyId`). `getLatestResults()` returns only the most recent result per test, useful for building a stable, final Allure report. + +- **Adding Custom Metadata**: + Before generating a final Allure report, you can: + 1. Read environment info: `const env = await store.getEnvironment();` + 2. Update it with new data: `env['BUILD_ID'] = process.env.BUILD_ID;` + 3. Write it back: `await store.writeEnvironmentInfo(env);` + +- **Integrating with CI**: + In a CI pipeline, you might: + 1. Download `allure-results` from a previous step. + 2. Initialize `AllureStore` with `fromDirectory`. + 3. Add categories or environment info. + 4. Generate or update an Allure report with the enriched data. + +## Next Steps + +- Explore the source to understand how `FileAllureReader` and `FileAllureWriter` are implemented. +- Implement your own `AllureReader` and `AllureWriter` if your data isn’t file-based. +- Read the test suite to see practical usage scenarios. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..bb2b18e --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[Issues page](https://github.com/wix-incubator/allure-store/issues). +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..83b012e --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,68 @@ +# CONTRIBUTING + +We welcome issues and pull requests from the community. :purple_heart: + +## Issues + +Open an issue on the [issue tracker]. + +There a few issue templates to choose from, where you will find instructions on how to report a bug or request a feature. + +## Pull requests + +There are no strict rules for pull requests, but we recommend the following: + +* Open an issue first, and discuss your idea with the maintainers. +* Fork the repository and create a new branch for your changes. +* Make your changes and submit a pull request. +* Add tests for your changes. +* Update the documentation. + +### Setup + +This is a standard Node.js project. You'll need to have Node.js installed. + +Fork this repository, clone and install dependencies: + +```bash +npm install +``` + +### Running unit tests + +```bash +npm test +``` + +### Running package integration tests + +```bash +npm run build # Build the library first + +cd package-e2e +npm install +npm test +``` + +### Checking your code + +Before committing, run the linter and tests: + +```bash +npm run lint +npm test +``` + +To create a commit, use [Commitizen]: + +```bash +npx cz +``` + +and follow the instructions. We adhere to Angular's [commit message guidelines]. + +Thanks in advance for your contribution! + +[commit message guidelines]: https://github.com/angular/angular/blob/main/CONTRIBUTING.md#commit +[issue tracker]: https://github.com/wix-incubator/allure-store/issues +[Commitizen]: https://github.com/commitizen/cz-cli diff --git a/README.md b/README.md index 9852268..6eb42ae 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,48 @@ -# allure-store +
+ Allure Store logo -[![npm version](https://img.shields.io/npm/v/allure-store.svg)](https://www.npmjs.com/package/allure-store) -[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -[![CI Status](https://github.com/wix-incubator/allure-store/actions/workflows/ci.yml/badge.svg)](https://github.com/wix-incubator/allure-store/actions) + # allure-store -A flexible and extensible store for reading, writing, and transforming [Allure](https://docs.qameta.io/allure/) test results [^1]. + A flexible and extensible store for reading, writing, and transforming [Allure](https://docs.qameta.io/allure/) test results [^1]. -## Key Features + [![npm version](https://img.shields.io/npm/v/allure-store.svg)](https://www.npmjs.com/package/allure-store) + [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) + [![CI Status](https://github.com/wix-incubator/allure-store/actions/workflows/ci.yml/badge.svg)](https://github.com/wix-incubator/allure-store/actions) +
-- **Unified API**: Interact with Allure test results, containers, categories, environment, and executor info using a single, simple interface. -- **Filesystem Integration**: Easily read from and write Allure results in the familiar `allure-results` directory structure. -- **Custom Readers/Writers**: Inject your own `AllureReader` and `AllureWriter` implementations to integrate with your preferred storage backends. -- **Result Aggregation**: Merge test containers and results to produce enriched test data for Allure-compatible tools. -- **Flexible Composition**: Combine multiple data sources or transform results before generating your final Allure report. +## Introduction -## Installation +`allure-store` provides a standardized interface (the **AllureStore**) to: -```bash -npm install allure-store -``` +- Read existing Allure test results from a variety of sources (e.g., local filesystem, remote storage). +- Write new Allure data (results, categories, environment info, etc.) for downstream consumers or tools. +- Transform, aggregate, or customize Allure test data before generating a final Allure report. + +By abstracting the data access behind `AllureReader` and `AllureWriter` interfaces, `allure-store` makes it simple to plug in custom storage backends, apply custom transformations, or integrate seamlessly into your CI/CD pipeline. + +## 🌟 Key Features + +- **Unified API**: Interact with Allure test results, containers, categories, environment, and executor info using a single, simple API (`AllureStore`). +- **Filesystem Integration**: Use built-in utilities to read from/write to a traditional `allure-results` directory. +- **Custom Integration Points**: Implement `AllureReader` and `AllureWriter` interfaces to read from or write to any storage backend—databases, cloud storage, etc. +- **Result Aggregation**: Merge parent test containers and child results to produce enriched test data for Allure-compatible tools. +- **Flexible Composition**: Combine multiple data sources or transform results before finalizing your Allure report. + +## 🚀 Installation -or +Install with your preferred package manager: ```bash +npm install allure-store +# or yarn add allure-store ``` -## Basic Usage +## 📖 Quick Start -### Initializing from a Directory +### Reading Results from a Directory -If you already have generated Allure results in a directory (e.g. `allure-results`), you can create a store directly: +If you have an existing `allure-results` directory (produced by Allure or a tool that supports it): ```typescript import { fromDirectory } from 'allure-store'; @@ -46,30 +58,24 @@ import { fromDirectory } from 'allure-store'; const categories = await store.getCategories(); console.log('Categories:', categories); - - const environment = await store.getEnvironment(); - console.log('Environment info:', environment); })(); ``` -### Writing Data +### Writing Data Back -You can also write data back to the Allure results directory (or another destination) using the store’s writer: +You can also write categories, environment info, or even individual test results: ```typescript import { fromDirectory } from 'allure-store'; (async () => { - // You can pass optional 'overwrite' parameter to delete the directory before writing anything const store = await fromDirectory('allure-results', { overwrite: true }); - // Add/update environment info await store.writeEnvironmentInfo({ NODE_ENV: 'production', SERVICE_URL: 'https://api.example.com', }); - // Add new categories await store.writeCategories([ { name: 'Product defects', matchedStatuses: ['failed'] }, { name: 'Test defects', matchedStatuses: ['broken'] }, @@ -77,12 +83,12 @@ import { fromDirectory } from 'allure-store'; })(); ``` -### Using a Custom Configuration +### Using Custom Readers/Writers -If you have a custom `AllureReader` or `AllureWriter`: +If your results are stored in a different system, implement the `AllureReader` and `AllureWriter` interfaces and provide them to `fromConfig`: ```typescript -import { fromConfig, AllureStore, AllureReader, AllureWriter } from 'allure-store'; +import { fromConfig, AllureReader, AllureWriter } from 'allure-store'; const customReader: AllureReader = { async getContainerIds() { /* ... */ }, @@ -105,44 +111,28 @@ const customWriter: AllureWriter = { (async () => { const store = await fromConfig({ reader: customReader, writer: customWriter }); const results = await store.getAllResults(); - // ...do something with results... + console.log('Custom source results:', results); })(); ``` -## API Overview - -**Core Exports:** - -- **Classes:** - - `AllureStore`: Main class managing both reading and writing of Allure data. - -- **Factory Functions:** - - `fromConfig(options: AllureStoreConfig): Promise` - - `fromDirectory(options: FileSystemAllureWriterConfig): Promise` - -- **Types & Interfaces:** - - `AllureReader`, `AllureWriter`: Protocols for custom readers/writers. - - `AllureResult`, `AllureContainer`, `AllureStep`, `AllureParameter`, `Category`, `ExecutorInfo` and other core Allure data types. - -## Use Cases +## When to Use `allure-store` -- **Custom CI Integrations**: Use `allure-store` to load Allure results from your CI artifacts and produce a final enriched Allure report. -- **Data Transformation**: Before generating the final report, read and manipulate test results (e.g., filter out certain tests, add environment details, or group tests differently). -- **Storage Abstraction**: If your results are stored in a database or remote object storage, implement a custom `AllureReader` and `AllureWriter` to integrate seamlessly. +- **Custom CI Integrations**: Integrate Allure data from multiple pipelines or artifact stores, then produce a final Allure report. +- **Data Transformation**: Filter, enrich, or modify Allure results before final reporting. +- **Non-File Storage**: If your Allure data isn’t file-based, `allure-store` provides an abstraction to still leverage Allure’s ecosystem. -## Contributing +## Additional Documentation -Contributions are welcome! If you find a bug or have a feature request, please open an issue or submit a pull request. +- **[API Documentation](./API.md)**: Detailed information on the store design, available methods, and data types. +- **[CONTRIBUTING.md](./CONTRIBUTING.md)**: Guidelines for contributing to this project. +- **[CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md)**: Our expectations for community interactions. -1. Fork the repository -2. Create a new branch for your feature or fix -3. Submit a PR once you’re ready +## 🌐 Contributing -## License +Contributions are welcome! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for details on how to get started. -> [!NOTE] -> `allure-store` is not affiliated with the official Allure framework, but it aims to provide a compatible and convenient way to handle Allure data. +## 📃 License This project is licensed under the [MIT License](LICENSE). -[^1]: **Note:** `allure-store` is not affiliated with the official Allure framework, but it aims to provide a compatible and convenient way to handle Allure data. +[^1]: **Note:** `allure-store` is not affiliated with the official Allure framework. It aims to provide a compatible and convenient way to handle Allure data. diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..13c81e0 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,54 @@ +import eslint from '@eslint/js'; +import tseslint from 'typescript-eslint'; +import { FlatCompat } from '@eslint/eslintrc'; + +const compat = new FlatCompat(); + +export default tseslint.config( + eslint.configs.recommended, + ...compat.extends('plugin:import/recommended'), + ...compat.extends('plugin:unicorn/recommended'), + ...tseslint.configs.recommended, + { + ignores: [ + 'dist/**', + 'package-e2e/**', + 'scripts/**', + '*.{js,json,mjs}' + ], + }, + { + rules: { + 'quotes': ['error', 'single', {'avoidEscape': true}], + 'import/no-unresolved': 'off', + 'import/order': ['error', { + 'newlines-between': 'always' + }], + 'import/no-extraneous-dependencies': 'error', + 'unicorn/consistent-function-scoping': 'off', + 'unicorn/filename-case': 'off', + 'unicorn/no-array-callback-reference': 'off', + 'unicorn/no-for-loop': 'off', + 'unicorn/no-null': 'off', + 'unicorn/prefer-module': 'off', + 'unicorn/no-nested-ternary': 'off', + 'unicorn/prevent-abbreviations': 'off', + '@typescript-eslint/consistent-type-imports': 'error', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + 'argsIgnorePattern': '^_' + } + ], + '@typescript-eslint/triple-slash-reference': 'off', + }, + }, + { + files: ['**/*.test.ts', '**/__tests__/**/*'], + rules: { + '@typescript-eslint/no-unused-expressions': 'off', // Allow Chai assertions like `expect(foo).to.be.true` + }, + }, +); diff --git a/package-e2e/.npmrc b/package-e2e/.npmrc new file mode 100644 index 0000000..43c97e7 --- /dev/null +++ b/package-e2e/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/package-e2e/package.json b/package-e2e/package.json new file mode 100644 index 0000000..f96f404 --- /dev/null +++ b/package-e2e/package.json @@ -0,0 +1,15 @@ +{ + "name": "@allure-store/package-e2e", + "private": true, + "version": "1.0.0", + "description": "", + "scripts": { + "test": "node test.cjs && node test.mjs && tsc", + "test:cjs": "node test.cjs", + "test:mjs": "node test.mjs", + "test:ts": "tsc" + }, + "dependencies": { + "allure-store": ".." + } +} diff --git a/package-e2e/test.cjs b/package-e2e/test.cjs new file mode 100644 index 0000000..25cc631 --- /dev/null +++ b/package-e2e/test.cjs @@ -0,0 +1,19 @@ +const assert = require('assert'); +const { + AllureStore, + fromConfig, + fromDirectory, + FileAllureReader, + FileAllureWriter, + // Type exports won't be runtime objects, so we can't assert them directly, + // but we can at least check some known runtime values like classes. +} = require('allure-store'); + +// Check functions +assert(typeof fromConfig === 'function', 'fromConfig should be a function'); +assert(typeof fromDirectory === 'function', 'fromDirectory should be a function'); + +// Check classes +assert(typeof AllureStore === 'function', 'AllureStore should be a class/function'); +assert(typeof FileAllureReader === 'function', 'FileAllureReader should be a class/function'); +assert(typeof FileAllureWriter === 'function', 'FileAllureWriter should be a class/function'); diff --git a/package-e2e/test.mjs b/package-e2e/test.mjs new file mode 100644 index 0000000..7fcc315 --- /dev/null +++ b/package-e2e/test.mjs @@ -0,0 +1,17 @@ +import assert from 'node:assert'; +import { + AllureStore, + fromConfig, + fromDirectory, + FileAllureReader, + FileAllureWriter, + // Since MJS also doesn't give us runtime interfaces, + // we just ensure the named exports exist. +} from 'allure-store'; + +assert(typeof fromConfig === 'function', 'fromConfig should be a function'); +assert(typeof fromDirectory === 'function', 'fromDirectory should be a function'); + +assert(typeof AllureStore === 'function', 'AllureStore should be a class'); +assert(typeof FileAllureReader === 'function', 'FileAllureReader should be a class'); +assert(typeof FileAllureWriter === 'function', 'FileAllureWriter should be a class'); diff --git a/package-e2e/test.ts b/package-e2e/test.ts new file mode 100644 index 0000000..1f97570 --- /dev/null +++ b/package-e2e/test.ts @@ -0,0 +1,88 @@ +import { + AllureStore, + AllureStoreConfig, + AllureStoreDirectoryConfig, + fromConfig, + fromDirectory, + AllureReader, + AllureWriter, + FileAllureReader, + FileAllureReaderConfig, + FileAllureWriter, + FileSystemAllureWriterConfig, + Container, + Result, + Category, + ExecutorInfo, + Step, + Parameter, + Attachment, + Label, + Link, + StatusDetails, + Stage, + Status +} from 'allure-store'; + +declare function assertType(value: T): T; + +// Check classes and functions +assertType(AllureStore); +assertType<(options: AllureStoreConfig) => Promise>(fromConfig); +assertType<(resultsDirectory: string, options?: AllureStoreDirectoryConfig) => Promise>(fromDirectory); + +// Check Reader/Writer interfaces +const dummyReader: AllureReader = { + getContainerIds: async () => [], + getResultIds: async () => [], + readContainer: async () => null, + readResult: async () => null, + readCategories: async () => null, + readEnvironmentInfo: async () => null, + readExecutorInfo: async () => null +}; +assertType(dummyReader); + +const dummyWriter: AllureWriter = { + writeCategories: async () => {}, + writeEnvironmentInfo: async () => {}, + writeExecutorInfo: async () => {}, + writeContainer: async () => {}, + writeResult: async () => {} +}; +assertType(dummyWriter); +assertType(new FileAllureReader({ resultsDirectory: 'fake-dir' })); +assertType(new FileAllureWriter({ resultsDirectory: 'fake-dir' })); + +// Check File readers/writers configs +assertType({ resultsDirectory: 'fake-dir' }); +assertType({ resultsDirectory: 'fake-dir', overwrite: true }); + +// Check various data types +assertType({ uuid: 'fake-uuid', children: [] }); +assertType({ + uuid: 'r-uuid', + historyId: 'h-id', + name: 'Test', + fullName: 'Test Full', + start: 0, + stop: 1, + stage: 'finished', + status: 'passed' +}); +assertType({ name: 'My Category', matchedStatuses: ['failed'] }); +assertType({}); +assertType({ + name: 'step', + start: 0, + stop: 1, + stage: 'finished', + status: 'passed' +}); +assertType({ name: 'param', value: 'val' }); +assertType({ name: 'attach', type: 'text/plain', source: 'path/to/file' }); +assertType