Getting started with open source contribution
Tags: opensource, headless, vendure, codenewbie
Published: 2023-03-22 14:02:55

The best way to learn anything is by doing and writing code is not any different. While learning to code by making clones of existing software is personally beneficial, there is no use case for all the hard work you put in. Proposal- contribute to open source projects being used by lots of people, now your work will live beyond your portfolio and actually help real users and the community.

[Vendure](https://www.vendure.io/) is a modern, open-source headless commerce framework built with TypeScript & Nodejs. And there is a very vibrant and helpful [community to get help](https://join.slack.com/t/vendure-ecommerce/shared_invite/zt-1exzio25w-vjL5TYkyJZjK52d6jkOsIA) when you get stuck. Head on over to their [github issues](https://github.com/vendure-ecommerce/vendure/issues) to get the current lay of the land and when you find something of interest to you fork the repo and clone it.

Follow the readme to setup your local development environment. Vendure takes testing very seriously - and especially end-to-end (e2e) tests, which provide the maximum guarantee of real-world correctness with currently around 1,400 e2e tests covering all key functionality. You will need some additional packages for [Puppeteer](https://pptr.dev/) to run e2e tests. On a linux machine running ubuntu, install chromium and dependencies.

```shell
sudo snap install chromium
sudo apt install -y libatk1.0-0 libatk-bridge2.0-0 libcups2 libxkbcommon-x11-0 libxcomposite-dev libxdamage1 libxrandr2 libgbm1 libgtk-3-0 libasound2 libxshmfence-dev
```

Now you can run the tests with `yarn test` and `yarn e2e` it will take a while, that is how well-tested the project is. The best part is you can lookup existing code to learn and write your own features/fixes and tests. Writing tests may look like extra work on the outset but it is a one-and-done approach that ensures your code works now and in the future if breaking changes are introduced, you will not have to re-test manually but rely on these tests you have already written to remedy the breaking changes.

Here is an example test to showcase working with different parts of the app

```ts
import { CreateProductInput, ProductTranslationInput } from '@vendure/common/lib/generated-types';
import { createTestEnvironment } from '@vendure/testing';
import path from 'path';

import { testConfig, TEST_SETUP_TIMEOUT_MS } from '../../../e2e-common/test-config';
import { initialData } from '../mock-data/data-sources/initial-data';
import { FastImporterService, LanguageCode } from '../src';

import { GetProductWithVariants } from './graphql/generated-e2e-admin-types';
import { GET_PRODUCT_WITH_VARIANTS } from './graphql/shared-definitions';

describe('FastImporterService resolver', () => {
    const { server, adminClient } = createTestEnvironment(testConfig());

    let fastImporterService: FastImporterService;

    beforeAll(async () => {
        await server.init({
            initialData,
            productsCsvPath: path.join(__dirname, 'fixtures/e2e-products-full.csv'),
        });
        await adminClient.asSuperAdmin();
        fastImporterService = server.app.get(FastImporterService);
    }, TEST_SETUP_TIMEOUT_MS);

    afterAll(async () => {
        await server.destroy();
    });

    it('creates normalized slug', async () => {
        const productTranslation: ProductTranslationInput = {
            languageCode: LanguageCode.en,
            name: 'test product',
            slug: 'test product',
            description: 'test description',
        };
        const createProductInput: CreateProductInput = {
            translations: [productTranslation],
        };
        await fastImporterService.initialize();
        const productId = await fastImporterService.createProduct(createProductInput);

        const { product } = await adminClient.query<
            GetProductWithVariants.Query,
            GetProductWithVariants.Variables
        >(GET_PRODUCT_WITH_VARIANTS, {
            id: productId as string,
        });

        expect(product?.slug).toMatch('test-product');
    });
});
```
This tests a functionality in the core package, to run this specific test
```shell
cd packages/core
yarn e2e fast-importer
```

Proposal- in your own workflow, write the desired results in a test and run it to see it fail. Now you can write the actual feature/fix and run the test to get it passing. Ship your changes confidently in a pull request and now you are an open source contributor!