Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#5341 code analysis documentation #5882

Merged
merged 19 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
95 changes: 67 additions & 28 deletions docs/source/contributing/acceptance-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,80 +7,116 @@ myst:
"keywords": "Volto, Plone, frontend, React, helper command, redux, acceptance, tests, Cypress"
---

# Acceptance testing
# Acceptance tests

Volto uses [Cypress](https://www.cypress.io/) for browser-based acceptance testing.
Volto uses [Cypress](https://www.cypress.io/) for browser-based acceptance tests.

There are a number of fixtures available covering all the configuration use cases.
These fixtures have both a specific backend and frontend configuration setup and a related set of tests.
The CI infrastructure runs them all automatically on every push to a branch or PR.
There are a number of tests available covering all the configuration use cases.
These tests have both a specific backend and frontend configuration setup and a related set of tests.
The continuous integration infrastructure runs them all automatically on every push to a branch or a pull request.

The tests can be run in headless mode (same as the CI does), or within the Cypress user interface.
The latter is the one that you run under development.


## How to run acceptance tests locally (during development)

When writing new acceptance tests, you usually want to minimize the time it takes to run the tests, while also being able to debug or inspect what's going on.

Being able to restart individual components also comes in handy.
It's recommended to start three individual terminal sessions, one each for running the Plone backend, the Volto frontend, and the acceptance tests.
All sessions should start from the `packages/volto` directory.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not true. You can run them from the root too, they have similar proxy commands to packages/volto

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just because you can do something doesn't mean you should do it. We are documenting to beginners how they can run the acceptance testing and if they really care they can see that the commands expand to the volto package.
Within the volto package you have everything you need from the news folder to lint to run to test and although power users can do whatever they want from volto repo, well that's a power user move :).
Although I didn't write it this way exactly I agree with Steve's directive to assume all commands for volto core run from packages/volto folder.

EDIT:
Another reason to use the workflow of go inside packages/volto folder is that we can show the commands using only pnpm command which would have the equivalent also in projects and 17.x.x and 16.x.x branch by swapping pnpm for yarn instead of going over
pnpm --filter which doesn't have equivalent in the order, still maintain and I would even say current versions until 18 is released.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually didn't recommend one place over another. It was my interpretation of the link that @ichim-david had originally used to refer to this location. This brings up something we need to discuss and decide.

There are quite a lot of differences between the two Makefiles. It looks like the primary Makefile is at the repo root, based in its inclusion of documentation commands and reading files from the repo root. It also appears that the one in packages/volto has not been kept up to date with that at the repo root, based on the number of updates to each. For example, I would not run make build from the package, but I would from the root. Here's another significant difference where some commands fail when spaces are in the realpath, which is something that often bites first-timers on their bum.

- CHECKOUT_BASENAME=$(shell basename $(shell realpath ./))
+ CHECKOUT_BASENAME="$(shell basename $(shell realpath ./))"
- CHECKOUT_TMP_ABS=$(shell realpath $(CHECKOUT_TMP))
+ CHECKOUT_TMP_ABS="$(shell realpath $(CHECKOUT_TMP))"

After looking at these differences as they are today, I think that we should recommend all commands should be run from the root of the repo. We can also suggest a tip that they may be run from the packages/volto directory, but there is no guarantee that they will work, such as make docs-*. That is, unless and until, we decide that the Makefile in the packages/volto directory is maintained for full parity with that at the root of the repo.

@sneridagh is that interpretation of Makefiles correct?

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not true. You can run them from the root too, they have similar proxy commands to packages/volto

Not quite, https://github.com/plone/volto/blob/main/package.json#L14-L23 although yes in the root you have commands for lint, prettier and stylelint and the :fix options they run for all of the apps and packages defined in the monorepo while the commands from packages/volto only run for the volto core package.
Yes, you can also manually run the filter commands from the root but then you lose the convenience of simply writing pnpm command and getting the right outcome.

We can enhance the docs with another section for the apps and other packages from the volto umbrella but now we should ensure that we have the docs for how to contribute to Volto core in my opinion.


1. Run the backend fixture.
1. In the first session, start the backend server.

```shell
make start-test-acceptance-server
```

2. Run the frontend fixture.
1. In the second session, start the frontend server.

```shell
make start-test-acceptance-frontend-dev
```

3. Run the Cypress tests for that fixture.
1. In the third session, start the Cypress tests runner.

```shell
make test-acceptance
```

Available fixtures:
1. In the Cypress pop-up test style, choose `E2E Testing`, since Volto's tests are end-to-end tests.

1. In the next section, select the browser you want Cypress to run in.
Although the core tests use `headless Electron` by default, you can choose your preferred browser for the tests development.

1. In the main Cypress runner section, you will see all of the test specs that Volto developers have written to test Volto and its packages.

1. To run a test, interact with the file based tree that displays all possible tests to run, and click on the test spec you need to run.

We provide the following major test specs:

- Core (`core` or not special naming in the test commands)
- Multilingual (`multilingual`)
- Working Copy (`workingCopy`)
- Core Sandbox (`coresandbox`)
- Core (`core` used to test the core functionality of Volto)
- Multilingual (`multilingual` tests the multilingual support of Volto)
- Working Copy (`workingCopy` tests the working copy feature of Volto)
- Core Sandbox (`coresandbox` tests Volto using configuration and elements that are not present in vanilla Volto)

There are convenience commands for each of these fixtures. See `Makefile` for more information.
There are convenience commands for each of these specs.
See `Makefile` at the root of the repository for more information.

### Writing new acceptance tests

Go to the `cypress/tests` folder to see existing tests.
There is a directory per fixture.
### Write new acceptance tests

Go to the folder `packages/volto/cypress/tests` to see existing tests.
There is a directory per spec.
This directory is hot reloaded with your changes as you write the tests.
For more information on how to write Cypress tests:

https://docs.cypress.io
```{seealso}
[Cypress documentation](https://docs.cypress.io/guides/overview/why-cypress)
```


## Helper commands

There are some artifacts available for the acceptance tests made accessible to Cypress.
There are some helper commands in {file}`packages/volto/cypress/support/commands.js` written by Volto contributors and made available for the acceptance tests using Cypress.

### Access History, Redux Store and Settings
Volto core makes heavy use of these helpers in the core tests to avoid verbose duplication, and they can make your life easier.
The following is an example of commands used in tests:

We expose the History, {term}`Redux` Store and Settings from the app (only for Cypress environments) so we can easily access them and execute actions (like navigate using the router), dispatch Redux actions or change app settings "on the fly".
```js
beforeEach(() => {
cy.autologin();
cy.createContent({
contentType: 'Document',
contentId: 'my-page-1',
contentTitle: 'My Page-1',
allow_discussion: true,
});
cy.visit('/contents');
});
```

#### Navigate using React Router
`cy.autologin` and `cy.createContent` are commands that will auto login, then create the entered content before each test will run.
This makes it easier to focus on the `act` and `assert` actions of the tests that make use of this test hook.

You can navigate using the React Router (ie. not reloading the page) with this command:

### Access history, Redux store, and settings

We expose the history, {term}`Redux` store, and settings from the app (only for Cypress environments) so we can easily access them and execute actions (like navigate using the router), dispatch Redux actions, or change app settings "on the fly".


#### Navigate using React router

You can navigate using the React router without reloading the page with the following command:

```js
cy.navigate('/events');
```

#### Redux Store

You can access the Redux store and check for specific states and dispatch actions by:
#### Redux store

You can access the Redux store and check for specific states and dispatch actions as shown:

```js
import { updateIntl } from 'react-intl-redux';
Expand All @@ -100,11 +136,14 @@ dispatch(
);
```

More information about this: https://www.cypress.io/blog/2018/11/14/testing-redux-store/
```{seealso}
[Testing Redux Store](https://www.cypress.io/blog/2018/11/14/testing-redux-store/)
```


#### Volto settings

You can modify on the fly the main Volto settings like this:
You can modify the main Volto settings on the fly.

```js
cy.settings().then(settings => {
Expand Down
44 changes: 28 additions & 16 deletions docs/source/contributing/developing-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,18 @@ To create a full Plone project with both frontend and backend, see {doc}`plone:i
```


(developing-core-monorepo-structure-label)=

## Monorepo structure

The Volto core repository has the shape of a monorepo, where "mono" means "single" and "repo" is short for "repository".
This means that several apps and libraries related to each other are stored in the same repository.
They are managed together but released individually.
This allows the code to be shared effectively, and unifies tracking of changes across all of the apps and libraries.

This monorepo uses pnpm as a package manager, extensively using the workspaces feature.
This monorepo uses pnpm as a package manager, extensively using its {term}`workspace` feature.
It's organized in two folders, depending on whether it's a library (package) or an app.
They are located in the `packages` or `apps` folder.
They are declared as pnpm workspaces.
This means they can be managed from the root, using the package manager `--filter` feature.

```{seealso}
For more information about pnpm workspaces, read the [documentation of pnpm workspaces](https://pnpm.io/workspaces).
```
The workspaces are located in the `packages` or `apps` folder.


### Folder layout
Expand Down Expand Up @@ -153,7 +149,6 @@ pnpm --version

Compare the output to the [latest pnpm release number](https://www.npmjs.com/package/pnpm).


```{seealso}
[pnpm installation](https://pnpm.io/installation).
```
Expand Down Expand Up @@ -220,20 +215,37 @@ Browse to the frontend running at http://localhost:3000.
To stop either the backend or frontend, use {kbd}`ctrl-c`.


## Running commands
(developing-core-run-commands-for-pnpm-workspaces-label)=

## Run commands for pnpm workspaces

As mentioned in {ref}`developing-core-monorepo-structure-label`, pnpm has the concept of {term}`workspace`.
Every package or app located in the `packages` or `apps` folders is declared as a pnpm workspace.

pnpm has the concept of `workspaces`.
Every package or app located in the `packages` or `apps` folders are declared as a pnpm workspace.
They can be managed using the pnpm `--filter` feature, with either of the following commands:
When developing Volto, you can run pnpm commands from either the repository root or inside the package's or app's workspace in `packages/<package_name>` or `apps/<app_name>`.

pnpm commands will apply in the context from which they are run.
That means when you run a pnpm command from the repository root, it will apply to all workspaces.
It also means when you run a pnpm command from inside a workspace, it will apply only to that workspace.

You can also use the pnpm `--filter` feature from the repository root to apply to only the specified workspaces, as shown in the following examples.

```shell
pnpm --filter @plone/volto start
```

The above command when run from the repository root will start Volto.

```shell
pnpm --filter @plone/registry build
```

The above command when run from the repository root will build the Volto registry.

```{seealso}
For more information about pnpm workspaces, read the [documentation of pnpm workspaces](https://pnpm.io/workspaces).
```


## Developing Volto

Expand All @@ -250,10 +262,10 @@ pnpm start
```
````

You can also run commands of specific workspaces using the `--filter` feature as shown in the previous section.
You can also run commands for a specific workspace using the `--filter` feature as shown in the previous section, {ref}`developing-core-run-commands-for-pnpm-workspaces-label`.


## Developing other libraries
## Develop other libraries in a workspace

If a package is a dependency of another package in the monorepo, and it's declared as a workspace, they can be declared as usual in the {file}`package.json` as follows:

Expand All @@ -264,7 +276,7 @@ If a package is a dependency of another package in the monorepo, and it's declar
```

```{seealso}
[pnpm workspaces](https://pnpm.io/workspaces)
[Documentation of pnpm workspaces](https://pnpm.io/workspaces).
```


Expand Down
112 changes: 93 additions & 19 deletions docs/source/contributing/linting.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,103 @@ myst:

# Linting

```{note}
This documentation is a work in progress. Any help is welcome to fill in the
gaps!
Volto developers can enjoy a lot of freedom in their choice of text editors and IDEs, thanks to the strong tooling provided by the JavaScript ecosystem.

Volto uses {term}`ESLint`, the advanced JavaScript linting and formatting tool, {term}`Stylelint`, and {term}`Prettier`.


(linting-editor-integration-label)=

## Editor integration

For Visual Studio Code, you'll need to install [VS Code ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint).

For Vim and NeoVim, you can use [Asynchronous Lint Engine (ALE)](https://github.com/dense-analysis/ale)
It provides out-of-the box integration with all the tooling provided by Volto.

PyCharm Professional includes [ESLint](https://www.jetbrains.com/help/pycharm/eslint.html), [Stylelint](https://www.jetbrains.com/help/pycharm/using-stylelint-code-quality-tool.html), and [Prettier](https://www.jetbrains.com/help/pycharm/prettier.html).

Use this checklist to make sure you have correctly configured your editor, most importantly for `.js` and `.jsx` files, the editor should automatically:

- flag syntax errors
- flag unused imports
- properly flag imported modules that are not found
- format code on save


## Lint Volto core

If you want to contribute to Volto core, you must perform several code quality control tasks.
Your commits must not break the automated tests, or {term}`GitHub workflows`, that Volto performs on every push or pull request.

Code linting is the first step in the testing hierarchy.

Volto core should automatically perform linting commands when you commit locally, as provided by the {term}`husky` integration.
However if the automated check doesn't happen when performing a commit, or you want to get less information, you can also run each linting task manually, as described in {ref}`linting-eslint-prettier-and-stylelint-label`.

If you want to see exactly which linting commands are set to run after a commit, look at the {file}`.lintstagedrc` at the root of the repository.

Volto core performs linting using the following commands:

`eslint`
: For finding problems in the project's code files.

`prettier`
: For uniform code formatting.

`stylelint`
: For uniform style formatting.

Although we can run the linting commands from the root of the repository, it is easier to run the commands only for Volto core within the Volto core folder:

```shell
cd packages/volto
```

From here we will have access to the commands to check for errors and to fix them.

```{seealso}
{ref}`developing-core-run-commands-for-pnpm-workspaces-label`
```


(linting-eslint-prettier-and-stylelint-label)=

### Eslint, Prettier, and Stylelint

You can run the pnpm `eslint`, `prettier`, and `stylelint` commands from the Volto package folder:

```shell
pnpm lint
pnpm prettier
pnpm stylelint
```

Volto developers can enjoy a lot of freedom in their choice of text editors and
IDEs, thanks to the strong tooling provided by the JavaScript ecosystem.
If we get any errors, some of them can be solved automatically by running pnpm commands as `<lint_command>:fix`:

At the core of these capabilities is ESLint, the advanced JavaScript linting
and formatting tool. Also included with Volto is integration with Stylelint and
Prettier.
```shell
pnpm lint:fix
pnpm prettier:fix
pnpm stylelint:fix
```

For Visual Studio Code you'll need to integrate an
[ESLint plugin](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint).
````{note}
The same commands can be found in your Volto add-on projects, as seen in the [`package.json.tpl`](https://github.com/plone/volto/blob/main/packages/generator-volto/generators/app/templates/package.json.tpl#L10) file.

For VIM you can use the [awesome ALE](https://github.com/dense-analysis/ale),
which provides out-of-the box integration with all the tooling provided by
Volto.
You will use similar commands to run the linting commands, but with `yarn` instead of `pnpm`:

Use this checklist to make sure your editor integration is properly integrated,
most importantly for .js/jsx files:
```shell
yarn lint
yarn lint:fix
yarn prettier
yarn prettier:fix
yarn stylelint
yarn stylelint:fix
```
````

- The editor should automatically flag syntax errors
- The editor should automatically flag unused imports
- The editor should automatically (and properly) flag imported modules that are not found
- The editor should provide automatic code formatting on save
```{important}
If the `fix` commands cannot fix the errors given by the linting commands, you will need to fix the errors manually.
Do not push commits that do not pass lint checks.
It will not pass GitHub workflow checks, and your contribution will not be merged.
```