mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-16 16:00:45 -04:00
chore(i18n,docs): processed translations (#51879)
This commit is contained in:
@@ -10,7 +10,7 @@ pnpm run playwright:install-build-tools
|
||||
|
||||
Alternatively you can follow official documentation referenced below:
|
||||
|
||||
To install and configure Playwright on your machine check out this [documentation](https://playwright.dev/docs/intro#installing-playwright)
|
||||
To install and configure Playwright on your machine check out this [documentation](https://playwright.dev/docs/intro#installing-playwright).
|
||||
|
||||
To learn how to write Playwright tests, or 'specs', please see Playwright's official [documentation](https://playwright.dev/docs/writing-tests).
|
||||
|
||||
@@ -20,141 +20,152 @@ To learn how to write Playwright tests, or 'specs', please see Playwright's offi
|
||||
|
||||
- Playwright test files are always with a `.spec.ts` extension.
|
||||
|
||||
## Best Practices for writing e2e tests
|
||||
## Best Practices for writing E2E tests
|
||||
|
||||
This section will explain in detail about best practices for writing and documenting E2E tests based on playwright documentation and our community code-style.
|
||||
|
||||
### - Identifying a DOM element
|
||||
|
||||
Always use the `data-playwright-test-label` attribute to identify DOM elements. This attribute is used to identify elements in the DOM for testing with playwright only. It is not used for styling or any other purpose.
|
||||
|
||||
For example:
|
||||
|
||||
```html
|
||||
<div data-playwright-test-label="landing-page-figure">
|
||||
<img src="..." alt="..." />
|
||||
</div>
|
||||
```
|
||||
|
||||
Make sure you use the getByTestId method to identify the element in the test file.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
const landingPageFigure = page.getByTestId('landing-page-figure');
|
||||
```
|
||||
This section will explain in detail about best practices for writing and documenting E2E tests based on Playwright documentation and our community code-style.
|
||||
|
||||
### - Imports
|
||||
|
||||
Always start with necessary imports at the beginning of the file.
|
||||
Always start with necessary imports at the beginning of the file.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
import { test, expect, type Page } from '@playwright/test';
|
||||
```
|
||||
```ts
|
||||
import { test, expect, type Page } from '@playwright/test';
|
||||
```
|
||||
|
||||
### - Identifying a DOM element
|
||||
|
||||
Playwright comes with [multiple built-in locators](https://playwright.dev/docs/locators#quick-guide), but we recommend prioritizing the following locators:
|
||||
- `getByRole` for querying semantic elements, whose role is important and allows assistive technology to perceive the page correctly.
|
||||
- `getByText` for querying non-semantic elements such as `div`, `span`, or `p`.
|
||||
|
||||
For example:
|
||||
```ts
|
||||
await expect(page.getByRole('heading', { name: 'Sign up' })).toBeVisible();
|
||||
await expect(page.getByText('Hello World')).toBeVisible();
|
||||
```
|
||||
|
||||
In cases where the elements cannot be queried using the above-mentioned locators, you can use the `data-playwright-test-label` attribute as the last resort. This attribute is used to identify elements in the DOM for testing with playwright only. It is not used for styling or any other purpose.
|
||||
|
||||
For example:
|
||||
|
||||
```html
|
||||
<div data-playwright-test-label="landing-page-figure">
|
||||
<img src="..." alt="..." />
|
||||
</div>
|
||||
```
|
||||
|
||||
In the test file, you can use the `getByTestId` method to identify the element.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
await expect(page.getByTestId('landing-page-figure')).toBeVisible();
|
||||
```
|
||||
|
||||
### - Constants
|
||||
|
||||
Define any constant elements, data sets, or configurations used throughout your tests for easy reference.
|
||||
Define any constant elements, data sets, or configurations used throughout your tests for easy reference.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
const landingPageElements = { ... };
|
||||
const superBlocks = [ ... ];
|
||||
```
|
||||
```ts
|
||||
const landingPageElements = { ... };
|
||||
const superBlocks = [ ... ];
|
||||
```
|
||||
|
||||
### - Shared Context
|
||||
|
||||
If tests depend on a shared context (like a loaded web page), use beforeAll and afterAll hooks to set up and tear down that context.
|
||||
If tests depend on a shared context (like a loaded web page), use beforeAll and afterAll hooks to set up and tear down that context.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
let page: Page;
|
||||
```ts
|
||||
let page: Page;
|
||||
|
||||
beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
});
|
||||
beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await page.close();
|
||||
});
|
||||
```
|
||||
afterAll(async () => {
|
||||
await page.close();
|
||||
});
|
||||
```
|
||||
|
||||
### - Descriptive test names
|
||||
|
||||
Each test block should have a clear and concise name describing exactly what it's testing.
|
||||
Each test block should have a clear and concise name describing exactly what it's testing.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
test('The component landing-top renders correctly', async ({ page }) => {
|
||||
...
|
||||
});
|
||||
```
|
||||
```ts
|
||||
test('The component landing-top renders correctly', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
### - Human readable assertions
|
||||
|
||||
Each assertion should be as human readable as possible. This makes it easier to understand what the test is doing and what it's expecting.
|
||||
Each assertion should be as human readable as possible. This makes it easier to understand what the test is doing and what it's expecting.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
await expect(landingHeading1).toHaveText('Learn to code — for free.');
|
||||
```
|
||||
```ts
|
||||
await expect(landingHeading1).toHaveText('Learn to code — for free.');
|
||||
```
|
||||
|
||||
### - Keep it DRY
|
||||
|
||||
Make sure that the tests are not repeating the same code over and over again. If you find yourself repeating the same code, consider refactoring it as a loop or a function.
|
||||
Make sure that the tests are not repeating the same code over and over again. If you find yourself repeating the same code, consider refactoring it as a loop or a function.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
for (const logo of await logos.all()) {
|
||||
await expect(logo).toBeVisible();
|
||||
}
|
||||
```
|
||||
```ts
|
||||
for (const logo of await logos.all()) {
|
||||
await expect(logo).toBeVisible();
|
||||
}
|
||||
```
|
||||
|
||||
### - Tests for mobile screens
|
||||
|
||||
Use the 'isMobile' argument to run tests that incude logic that varies for mobile screens.
|
||||
Use the `isMobile` argument to run tests that include logic that varies for mobile screens.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({isMobile}) =>
|
||||
{
|
||||
const landingPageImage = page.getByTestId('landing-page-figure');
|
||||
```ts
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({
|
||||
isMobile
|
||||
}) => {
|
||||
const landingPageImage = page.getByTestId('landing-page-figure');
|
||||
|
||||
if (isMobile) {
|
||||
await expect(landingPageImage).toBeHidden();
|
||||
} else {
|
||||
await expect(landingPageImage).toBeVisible();
|
||||
}
|
||||
});
|
||||
if (isMobile) {
|
||||
await expect(landingPageImage).toBeHidden();
|
||||
} else {
|
||||
await expect(landingPageImage).toBeVisible();
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### - Group related tests
|
||||
|
||||
Group related tests together using describe blocks. This makes it easier to understand what the tests are doing and what they're testing.
|
||||
Group related tests together using describe blocks. This makes it easier to understand what the tests are doing and what they're testing.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
describe('The campers landing page', () => {
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({isMobile}) =>
|
||||
{
|
||||
...
|
||||
});
|
||||
|
||||
test('The campers landing page figure has the correct image', async () => {
|
||||
...
|
||||
});
|
||||
```ts
|
||||
describe('The campers landing page', () => {
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({
|
||||
isMobile
|
||||
}) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
test('The campers landing page figure has the correct image', async () => {
|
||||
// ...
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## How to Run Tests
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ Follow these guidelines for setting up a development environment for freeCodeCam
|
||||
|
||||
## Choose between Gitpod or your Own Machine (local setup)
|
||||
|
||||
> [!ATTENTION] **Note:** freeCodeCamp does NOT run natively on Windows 10 or 11, you will need to use WSL2. You can follow [this guide](how-to-setup-wsl.md) to set up WSL2. You can't use Command Prompt, Git Bash or PowerShell to run freeCodeCamp natively within windows.
|
||||
> [!ATTENTION] - freeCodeCamp does not build and run natively on Windows, you will [need to use WSL2](how-to-setup-wsl.md) for a Linux-like setup on Windows. - You can't use Windows Command Prompt, Git Bash or PowerShell to build and run the codebase. - Note that if using Windows, the hardware requirements need to be more than [what we mention](how-to-setup-freecodecamp-locally?id=how-to-prepare-your-local-machine) to accommodate for WSL-based setup.
|
||||
|
||||
If you are looking to make a one-off contribution, you should use Gitpod to make changes. The Gitpod setup launches a ready-to-code environment in a few minutes in your web browser. For contributing long-term, we recommend you setup freeCodeCamp on your local machine.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# The Official freeCodeCamp Moderator Onboarding Guide
|
||||
|
||||
This guide will help new moderators get up and running with the processes and procedures followed by experienced moderators on the freeCodeCamp community forum and other official communities that we foster.
|
||||
This guide will help new moderators get up and running with the processes and procedures followed by experienced moderators on the freeCodeCamp community forum and other official communities we foster.
|
||||
|
||||
> [!NOTE] If you haven't read [The Moderator Handbook](https://contribute.freecodecamp.org/#/moderator-handbook) yet, you should start there first.
|
||||
|
||||
@@ -18,33 +18,33 @@ To get familiar with the new tools and powers, you can combine one or more of th
|
||||
|
||||
### Become Familiar with the Discourse Admin Tools
|
||||
|
||||
The freeCodeCamp forum is actually a Discourse forum and follows many of the same guidelines of other forums built on Discourse. To begin to get familiar with Discourse and the moderation role, start by reading Discourse's [new user guide](https://meta.discourse.org/t/discourse-new-user-guide/96331) and Discourse's [new moderator guide](https://meta.discourse.org/t/discourse-moderation-guide/63116).
|
||||
The freeCodeCamp forum is a Discourse forum and follows many of the same guidelines of other forums built on Discourse. To begin to get familiar with Discourse and the moderation role, start by reading Discourse's [new user guide](https://meta.discourse.org/t/discourse-new-user-guide/96331) and Discourse's [new moderator guide](https://meta.discourse.org/t/discourse-moderation-guide/63116).
|
||||
|
||||
### Shadow a Mod
|
||||
|
||||
All moderator actions can be followed by reviewing the [action logs](https://forum.freecodecamp.org/admin/logs/staff_action_logs). The actions taken by automated tools like `akistmet` or `system` can mostly be ignored until they result in a post that needs to be reviewed. Posts to be reviewed will show up in the [Review](https://forum.freecodecamp.org/review) area of the forum.
|
||||
All moderator actions can be followed by reviewing the [action logs](https://forum.freecodecamp.org/admin/logs/staff_action_logs). The actions taken by automated tools like `Akismet` or `system` can mostly be ignored until they result in a post that needs to be reviewed. Posts to be reviewed will show up in the [Review](https://forum.freecodecamp.org/review) area of the forum.
|
||||
|
||||
For the first week or so you will want to pay attention to what is getting flagged and what is being reviewed, and compare that to the actions being taken upon the flagged posts. You may see the system account flag a post because the user created it too quickly. In many cases, the moderators will unflag the post by clicking on the "Approve Post" button or mark it as "Not Spam" (depending on the flag type).
|
||||
|
||||
Commonly, spam flags can also be raised by members or moderators. Common duplicitous behavior would involve opening an account, making a post that seems harmless, then editing that post later on to add a link to an external site for the purpose of advertising it. In this case, usually the member account is fairly new and has only made this one post thus far, which indicates that the account was opened for the sole purpose of spamming the community. The decision should be made to delete the account after the first offence in this case. The same applies for accounts whose first post is deemed to be spam.
|
||||
Commonly, spam flags can also be raised by members or moderators. Common duplicitous behavior would involve opening an account, making a post that seems harmless, then editing that post later on to add a link to an external site to advertise it. In this case, the member account is usually fairly new and has only made this one post thus far, which indicates that the account was opened solely for spamming the community. The decision should be made to delete the account after the first offense in this case. The same applies to accounts whose first post is deemed to be spam.
|
||||
|
||||
You may notice moderators performing a procedure called 'split topic'. This may be a case where a moderator has split a post that was made erroneously on an existing topic into a new topic, or a moderator merged duplicate topics that a single user has created for the same question. Watching this procedure will highlight different actions and their causes.
|
||||
|
||||
Another useful feature that becomes enabled for all moderators is the ability to post a "Canned Reply" which is a pre-written response that was worked out with the mod team in order to quickly respond to some well-known and repetitive scenarios. These include:
|
||||
Another useful feature that becomes enabled for all moderators is the ability to post a "Canned Reply" which is a pre-written response that was worked out with the mod team to quickly respond to some well-known and repetitive scenarios. These include:
|
||||
|
||||
- Welcoming a new forum member who has posted code without a question -> "Welcome - remind question"
|
||||
- Reminding members not to post code solutions but to provide hints and tips instead -> "Solutions Instead of Help"
|
||||
- Responding to a situation where someone's code works for you but not for them -> "Browser Issues"
|
||||
- Encouraging members to open GitHub issues when a possible bug is found -> "Bug Report"
|
||||
|
||||
There are more, which you can read through to become familiar with their respective uses. You can also find discussion around the templates in the mod-team subforum, and you are welcome to ask questions if you aren't sure how a template should be used.
|
||||
There are more, which you can read through to become familiar with their respective uses. You can also find discussions around the templates in the mod-team subforum, and you are welcome to ask questions if you aren't sure how a template should be used.
|
||||
|
||||
### Read Mod-Team Subforum Posts
|
||||
|
||||
The Mod-Team subforum contains a number of posts from past and current moderators discussing the different requirements and/or challenges of moderating the forum.
|
||||
The Mod-Team subforum contains several posts from past and current moderators discussing the different requirements and/or challenges of moderating the forum.
|
||||
|
||||
Reading back through these posts can help to uncover some of the underlying goals and processes that concern forum moderators. Some of the threads may also shed some light on handling of spam and inappropriate content on the forum.
|
||||
Reading back through these posts can help uncover some of the underlying goals and processes that concern forum moderators. Some of the threads may also shed some light on the handling of spam and inappropriate content on the forum.
|
||||
|
||||
## Where to Ask for Help
|
||||
|
||||
To get help dealing with a situation that you are either uncomfortable with or unsure of how to handle, discuss with your fellow moderators on either the [Mod-Team Subforum](https://forum.freecodecamp.org/c/mod-team/4) or the [#mod-chat](https://discord.com/channels/692816967895220344/693157007418720277) on Discord.
|
||||
To get help dealing with a situation that you are either uncomfortable with or unsure of how to handle, discuss with your fellow moderators on either the [Mod-Team Subforum](https://forum.freecodecamp.org/c/mod-team/4) or the [#mod-chat](https://discord.com/channels/692816967895220344/693157007418720277) on Discord.
|
||||
@@ -10,7 +10,7 @@ pnpm run playwright:install-build-tools
|
||||
|
||||
Alternatively you can follow official documentation referenced below:
|
||||
|
||||
To install and configure Playwright on your machine check out this [documentation](https://playwright.dev/docs/intro#installing-playwright)
|
||||
To install and configure Playwright on your machine check out this [documentation](https://playwright.dev/docs/intro#installing-playwright).
|
||||
|
||||
To learn how to write Playwright tests, or 'specs', please see Playwright's official [documentation](https://playwright.dev/docs/writing-tests).
|
||||
|
||||
@@ -20,141 +20,152 @@ To learn how to write Playwright tests, or 'specs', please see Playwright's offi
|
||||
|
||||
- Playwright test files are always with a `.spec.ts` extension.
|
||||
|
||||
## Best Practices for writing e2e tests
|
||||
## Best Practices for writing E2E tests
|
||||
|
||||
This section will explain in detail about best practices for writing and documenting E2E tests based on playwright documentation and our community code-style.
|
||||
|
||||
### - Identifying a DOM element
|
||||
|
||||
Always use the `data-playwright-test-label` attribute to identify DOM elements. This attribute is used to identify elements in the DOM for testing with playwright only. It is not used for styling or any other purpose.
|
||||
|
||||
For example:
|
||||
|
||||
```html
|
||||
<div data-playwright-test-label="landing-page-figure">
|
||||
<img src="..." alt="..." />
|
||||
</div>
|
||||
```
|
||||
|
||||
Make sure you use the getByTestId method to identify the element in the test file.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
const landingPageFigure = page.getByTestId('landing-page-figure');
|
||||
```
|
||||
This section will explain in detail about best practices for writing and documenting E2E tests based on Playwright documentation and our community code-style.
|
||||
|
||||
### - Imports
|
||||
|
||||
Always start with necessary imports at the beginning of the file.
|
||||
Always start with necessary imports at the beginning of the file.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
import { test, expect, type Page } from '@playwright/test';
|
||||
```
|
||||
```ts
|
||||
import { test, expect, type Page } from '@playwright/test';
|
||||
```
|
||||
|
||||
### - Identifying a DOM element
|
||||
|
||||
Playwright comes with [multiple built-in locators](https://playwright.dev/docs/locators#quick-guide), but we recommend prioritizing the following locators:
|
||||
- `getByRole` for querying semantic elements, whose role is important and allows assistive technology to perceive the page correctly.
|
||||
- `getByText` for querying non-semantic elements such as `div`, `span`, or `p`.
|
||||
|
||||
For example:
|
||||
```ts
|
||||
await expect(page.getByRole('heading', { name: 'Sign up' })).toBeVisible();
|
||||
await expect(page.getByText('Hello World')).toBeVisible();
|
||||
```
|
||||
|
||||
In cases where the elements cannot be queried using the above-mentioned locators, you can use the `data-playwright-test-label` attribute as the last resort. This attribute is used to identify elements in the DOM for testing with playwright only. It is not used for styling or any other purpose.
|
||||
|
||||
For example:
|
||||
|
||||
```html
|
||||
<div data-playwright-test-label="landing-page-figure">
|
||||
<img src="..." alt="..." />
|
||||
</div>
|
||||
```
|
||||
|
||||
In the test file, you can use the `getByTestId` method to identify the element.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
await expect(page.getByTestId('landing-page-figure')).toBeVisible();
|
||||
```
|
||||
|
||||
### - Constants
|
||||
|
||||
Define any constant elements, data sets, or configurations used throughout your tests for easy reference.
|
||||
Define any constant elements, data sets, or configurations used throughout your tests for easy reference.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
const landingPageElements = { ... };
|
||||
const superBlocks = [ ... ];
|
||||
```
|
||||
```ts
|
||||
const landingPageElements = { ... };
|
||||
const superBlocks = [ ... ];
|
||||
```
|
||||
|
||||
### - Shared Context
|
||||
|
||||
If tests depend on a shared context (like a loaded web page), use beforeAll and afterAll hooks to set up and tear down that context.
|
||||
If tests depend on a shared context (like a loaded web page), use beforeAll and afterAll hooks to set up and tear down that context.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
let page: Page;
|
||||
```ts
|
||||
let page: Page;
|
||||
|
||||
beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
});
|
||||
beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await page.close();
|
||||
});
|
||||
```
|
||||
afterAll(async () => {
|
||||
await page.close();
|
||||
});
|
||||
```
|
||||
|
||||
### - Descriptive test names
|
||||
|
||||
Each test block should have a clear and concise name describing exactly what it's testing.
|
||||
Each test block should have a clear and concise name describing exactly what it's testing.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
test('The component landing-top renders correctly', async ({ page }) => {
|
||||
...
|
||||
});
|
||||
```
|
||||
```ts
|
||||
test('The component landing-top renders correctly', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
### - Human readable assertions
|
||||
|
||||
Each assertion should be as human readable as possible. This makes it easier to understand what the test is doing and what it's expecting.
|
||||
Each assertion should be as human readable as possible. This makes it easier to understand what the test is doing and what it's expecting.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
await expect(landingHeading1).toHaveText('Learn to code — for free.');
|
||||
```
|
||||
```ts
|
||||
await expect(landingHeading1).toHaveText('Learn to code — for free.');
|
||||
```
|
||||
|
||||
### - Keep it DRY
|
||||
|
||||
Make sure that the tests are not repeating the same code over and over again. If you find yourself repeating the same code, consider refactoring it as a loop or a function.
|
||||
Make sure that the tests are not repeating the same code over and over again. If you find yourself repeating the same code, consider refactoring it as a loop or a function.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
for (const logo of await logos.all()) {
|
||||
await expect(logo).toBeVisible();
|
||||
}
|
||||
```
|
||||
```ts
|
||||
for (const logo of await logos.all()) {
|
||||
await expect(logo).toBeVisible();
|
||||
}
|
||||
```
|
||||
|
||||
### - Tests for mobile screens
|
||||
|
||||
Use the 'isMobile' argument to run tests that incude logic that varies for mobile screens.
|
||||
Use the `isMobile` argument to run tests that include logic that varies for mobile screens.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({isMobile}) =>
|
||||
{
|
||||
const landingPageImage = page.getByTestId('landing-page-figure');
|
||||
```ts
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({
|
||||
isMobile
|
||||
}) => {
|
||||
const landingPageImage = page.getByTestId('landing-page-figure');
|
||||
|
||||
if (isMobile) {
|
||||
await expect(landingPageImage).toBeHidden();
|
||||
} else {
|
||||
await expect(landingPageImage).toBeVisible();
|
||||
}
|
||||
});
|
||||
if (isMobile) {
|
||||
await expect(landingPageImage).toBeHidden();
|
||||
} else {
|
||||
await expect(landingPageImage).toBeVisible();
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### - Group related tests
|
||||
|
||||
Group related tests together using describe blocks. This makes it easier to understand what the tests are doing and what they're testing.
|
||||
Group related tests together using describe blocks. This makes it easier to understand what the tests are doing and what they're testing.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
describe('The campers landing page', () => {
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({isMobile}) =>
|
||||
{
|
||||
...
|
||||
});
|
||||
|
||||
test('The campers landing page figure has the correct image', async () => {
|
||||
...
|
||||
});
|
||||
```ts
|
||||
describe('The campers landing page', () => {
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({
|
||||
isMobile
|
||||
}) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
test('The campers landing page figure has the correct image', async () => {
|
||||
// ...
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## How to Run Tests
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ Follow these guidelines for setting up a development environment for freeCodeCam
|
||||
|
||||
## Choose between Gitpod or your Own Machine (local setup)
|
||||
|
||||
> [!ATTENTION] **Note:** freeCodeCamp does NOT run natively on Windows 10 or 11, you will need to use WSL2. You can follow [this guide](how-to-setup-wsl.md) to set up WSL2. You can't use Command Prompt, Git Bash or PowerShell to run freeCodeCamp natively within windows.
|
||||
> [!ATTENTION] - freeCodeCamp does not build and run natively on Windows, you will [need to use WSL2](how-to-setup-wsl.md) for a Linux-like setup on Windows. - You can't use Windows Command Prompt, Git Bash or PowerShell to build and run the codebase. - Note that if using Windows, the hardware requirements need to be more than [what we mention](how-to-setup-freecodecamp-locally?id=how-to-prepare-your-local-machine) to accommodate for WSL-based setup.
|
||||
|
||||
If you are looking to make a one-off contribution, you should use Gitpod to make changes. The Gitpod setup launches a ready-to-code environment in a few minutes in your web browser. For contributing long-term, we recommend you setup freeCodeCamp on your local machine.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# The Official freeCodeCamp Moderator Onboarding Guide
|
||||
|
||||
This guide will help new moderators get up and running with the processes and procedures followed by experienced moderators on the freeCodeCamp community forum and other official communities that we foster.
|
||||
This guide will help new moderators get up and running with the processes and procedures followed by experienced moderators on the freeCodeCamp community forum and other official communities we foster.
|
||||
|
||||
> [!NOTE] If you haven't read [The Moderator Handbook](https://contribute.freecodecamp.org/#/moderator-handbook) yet, you should start there first.
|
||||
|
||||
@@ -18,33 +18,33 @@ To get familiar with the new tools and powers, you can combine one or more of th
|
||||
|
||||
### Become Familiar with the Discourse Admin Tools
|
||||
|
||||
The freeCodeCamp forum is actually a Discourse forum and follows many of the same guidelines of other forums built on Discourse. To begin to get familiar with Discourse and the moderation role, start by reading Discourse's [new user guide](https://meta.discourse.org/t/discourse-new-user-guide/96331) and Discourse's [new moderator guide](https://meta.discourse.org/t/discourse-moderation-guide/63116).
|
||||
The freeCodeCamp forum is a Discourse forum and follows many of the same guidelines of other forums built on Discourse. To begin to get familiar with Discourse and the moderation role, start by reading Discourse's [new user guide](https://meta.discourse.org/t/discourse-new-user-guide/96331) and Discourse's [new moderator guide](https://meta.discourse.org/t/discourse-moderation-guide/63116).
|
||||
|
||||
### Shadow a Mod
|
||||
|
||||
All moderator actions can be followed by reviewing the [action logs](https://forum.freecodecamp.org/admin/logs/staff_action_logs). The actions taken by automated tools like `akistmet` or `system` can mostly be ignored until they result in a post that needs to be reviewed. Posts to be reviewed will show up in the [Review](https://forum.freecodecamp.org/review) area of the forum.
|
||||
All moderator actions can be followed by reviewing the [action logs](https://forum.freecodecamp.org/admin/logs/staff_action_logs). The actions taken by automated tools like `Akismet` or `system` can mostly be ignored until they result in a post that needs to be reviewed. Posts to be reviewed will show up in the [Review](https://forum.freecodecamp.org/review) area of the forum.
|
||||
|
||||
For the first week or so you will want to pay attention to what is getting flagged and what is being reviewed, and compare that to the actions being taken upon the flagged posts. You may see the system account flag a post because the user created it too quickly. In many cases, the moderators will unflag the post by clicking on the "Approve Post" button or mark it as "Not Spam" (depending on the flag type).
|
||||
|
||||
Commonly, spam flags can also be raised by members or moderators. Common duplicitous behavior would involve opening an account, making a post that seems harmless, then editing that post later on to add a link to an external site for the purpose of advertising it. In this case, usually the member account is fairly new and has only made this one post thus far, which indicates that the account was opened for the sole purpose of spamming the community. The decision should be made to delete the account after the first offence in this case. The same applies for accounts whose first post is deemed to be spam.
|
||||
Commonly, spam flags can also be raised by members or moderators. Common duplicitous behavior would involve opening an account, making a post that seems harmless, then editing that post later on to add a link to an external site to advertise it. In this case, the member account is usually fairly new and has only made this one post thus far, which indicates that the account was opened solely for spamming the community. The decision should be made to delete the account after the first offense in this case. The same applies to accounts whose first post is deemed to be spam.
|
||||
|
||||
You may notice moderators performing a procedure called 'split topic'. This may be a case where a moderator has split a post that was made erroneously on an existing topic into a new topic, or a moderator merged duplicate topics that a single user has created for the same question. Watching this procedure will highlight different actions and their causes.
|
||||
|
||||
Another useful feature that becomes enabled for all moderators is the ability to post a "Canned Reply" which is a pre-written response that was worked out with the mod team in order to quickly respond to some well-known and repetitive scenarios. These include:
|
||||
Another useful feature that becomes enabled for all moderators is the ability to post a "Canned Reply" which is a pre-written response that was worked out with the mod team to quickly respond to some well-known and repetitive scenarios. These include:
|
||||
|
||||
- Welcoming a new forum member who has posted code without a question -> "Welcome - remind question"
|
||||
- Reminding members not to post code solutions but to provide hints and tips instead -> "Solutions Instead of Help"
|
||||
- Responding to a situation where someone's code works for you but not for them -> "Browser Issues"
|
||||
- Encouraging members to open GitHub issues when a possible bug is found -> "Bug Report"
|
||||
|
||||
There are more, which you can read through to become familiar with their respective uses. You can also find discussion around the templates in the mod-team subforum, and you are welcome to ask questions if you aren't sure how a template should be used.
|
||||
There are more, which you can read through to become familiar with their respective uses. You can also find discussions around the templates in the mod-team subforum, and you are welcome to ask questions if you aren't sure how a template should be used.
|
||||
|
||||
### Read Mod-Team Subforum Posts
|
||||
|
||||
The Mod-Team subforum contains a number of posts from past and current moderators discussing the different requirements and/or challenges of moderating the forum.
|
||||
The Mod-Team subforum contains several posts from past and current moderators discussing the different requirements and/or challenges of moderating the forum.
|
||||
|
||||
Reading back through these posts can help to uncover some of the underlying goals and processes that concern forum moderators. Some of the threads may also shed some light on handling of spam and inappropriate content on the forum.
|
||||
Reading back through these posts can help uncover some of the underlying goals and processes that concern forum moderators. Some of the threads may also shed some light on the handling of spam and inappropriate content on the forum.
|
||||
|
||||
## Where to Ask for Help
|
||||
|
||||
To get help dealing with a situation that you are either uncomfortable with or unsure of how to handle, discuss with your fellow moderators on either the [Mod-Team Subforum](https://forum.freecodecamp.org/c/mod-team/4) or the [#mod-chat](https://discord.com/channels/692816967895220344/693157007418720277) on Discord.
|
||||
To get help dealing with a situation that you are either uncomfortable with or unsure of how to handle, discuss with your fellow moderators on either the [Mod-Team Subforum](https://forum.freecodecamp.org/c/mod-team/4) or the [#mod-chat](https://discord.com/channels/692816967895220344/693157007418720277) on Discord.
|
||||
@@ -10,7 +10,7 @@ pnpm run playwright:install-build-tools
|
||||
|
||||
Alternatively you can follow official documentation referenced below:
|
||||
|
||||
To install and configure Playwright on your machine check out this [documentation](https://playwright.dev/docs/intro#installing-playwright)
|
||||
To install and configure Playwright on your machine check out this [documentation](https://playwright.dev/docs/intro#installing-playwright).
|
||||
|
||||
To learn how to write Playwright tests, or 'specs', please see Playwright's official [documentation](https://playwright.dev/docs/writing-tests).
|
||||
|
||||
@@ -20,141 +20,152 @@ To learn how to write Playwright tests, or 'specs', please see Playwright's offi
|
||||
|
||||
- Playwright test files are always with a `.spec.ts` extension.
|
||||
|
||||
## Best Practices for writing e2e tests
|
||||
## Best Practices for writing E2E tests
|
||||
|
||||
This section will explain in detail about best practices for writing and documenting E2E tests based on playwright documentation and our community code-style.
|
||||
|
||||
### - Identifying a DOM element
|
||||
|
||||
Always use the `data-playwright-test-label` attribute to identify DOM elements. This attribute is used to identify elements in the DOM for testing with playwright only. It is not used for styling or any other purpose.
|
||||
|
||||
For example:
|
||||
|
||||
```html
|
||||
<div data-playwright-test-label="landing-page-figure">
|
||||
<img src="..." alt="..." />
|
||||
</div>
|
||||
```
|
||||
|
||||
Make sure you use the getByTestId method to identify the element in the test file.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
const landingPageFigure = page.getByTestId('landing-page-figure');
|
||||
```
|
||||
This section will explain in detail about best practices for writing and documenting E2E tests based on Playwright documentation and our community code-style.
|
||||
|
||||
### - Imports
|
||||
|
||||
Always start with necessary imports at the beginning of the file.
|
||||
Always start with necessary imports at the beginning of the file.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
import { test, expect, type Page } from '@playwright/test';
|
||||
```
|
||||
```ts
|
||||
import { test, expect, type Page } from '@playwright/test';
|
||||
```
|
||||
|
||||
### - Identifying a DOM element
|
||||
|
||||
Playwright comes with [multiple built-in locators](https://playwright.dev/docs/locators#quick-guide), but we recommend prioritizing the following locators:
|
||||
- `getByRole` for querying semantic elements, whose role is important and allows assistive technology to perceive the page correctly.
|
||||
- `getByText` for querying non-semantic elements such as `div`, `span`, or `p`.
|
||||
|
||||
For example:
|
||||
```ts
|
||||
await expect(page.getByRole('heading', { name: 'Sign up' })).toBeVisible();
|
||||
await expect(page.getByText('Hello World')).toBeVisible();
|
||||
```
|
||||
|
||||
In cases where the elements cannot be queried using the above-mentioned locators, you can use the `data-playwright-test-label` attribute as the last resort. This attribute is used to identify elements in the DOM for testing with playwright only. It is not used for styling or any other purpose.
|
||||
|
||||
For example:
|
||||
|
||||
```html
|
||||
<div data-playwright-test-label="landing-page-figure">
|
||||
<img src="..." alt="..." />
|
||||
</div>
|
||||
```
|
||||
|
||||
In the test file, you can use the `getByTestId` method to identify the element.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
await expect(page.getByTestId('landing-page-figure')).toBeVisible();
|
||||
```
|
||||
|
||||
### - Constants
|
||||
|
||||
Define any constant elements, data sets, or configurations used throughout your tests for easy reference.
|
||||
Define any constant elements, data sets, or configurations used throughout your tests for easy reference.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
const landingPageElements = { ... };
|
||||
const superBlocks = [ ... ];
|
||||
```
|
||||
```ts
|
||||
const landingPageElements = { ... };
|
||||
const superBlocks = [ ... ];
|
||||
```
|
||||
|
||||
### - Shared Context
|
||||
|
||||
If tests depend on a shared context (like a loaded web page), use beforeAll and afterAll hooks to set up and tear down that context.
|
||||
If tests depend on a shared context (like a loaded web page), use beforeAll and afterAll hooks to set up and tear down that context.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
let page: Page;
|
||||
```ts
|
||||
let page: Page;
|
||||
|
||||
beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
});
|
||||
beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await page.close();
|
||||
});
|
||||
```
|
||||
afterAll(async () => {
|
||||
await page.close();
|
||||
});
|
||||
```
|
||||
|
||||
### - Descriptive test names
|
||||
|
||||
Each test block should have a clear and concise name describing exactly what it's testing.
|
||||
Each test block should have a clear and concise name describing exactly what it's testing.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
test('The component landing-top renders correctly', async ({ page }) => {
|
||||
...
|
||||
});
|
||||
```
|
||||
```ts
|
||||
test('The component landing-top renders correctly', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
### - Human readable assertions
|
||||
|
||||
Each assertion should be as human readable as possible. This makes it easier to understand what the test is doing and what it's expecting.
|
||||
Each assertion should be as human readable as possible. This makes it easier to understand what the test is doing and what it's expecting.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
await expect(landingHeading1).toHaveText('Learn to code — for free.');
|
||||
```
|
||||
```ts
|
||||
await expect(landingHeading1).toHaveText('Learn to code — for free.');
|
||||
```
|
||||
|
||||
### - Keep it DRY
|
||||
|
||||
Make sure that the tests are not repeating the same code over and over again. If you find yourself repeating the same code, consider refactoring it as a loop or a function.
|
||||
Make sure that the tests are not repeating the same code over and over again. If you find yourself repeating the same code, consider refactoring it as a loop or a function.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
for (const logo of await logos.all()) {
|
||||
await expect(logo).toBeVisible();
|
||||
}
|
||||
```
|
||||
```ts
|
||||
for (const logo of await logos.all()) {
|
||||
await expect(logo).toBeVisible();
|
||||
}
|
||||
```
|
||||
|
||||
### - Tests for mobile screens
|
||||
|
||||
Use the 'isMobile' argument to run tests that incude logic that varies for mobile screens.
|
||||
Use the `isMobile` argument to run tests that include logic that varies for mobile screens.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({isMobile}) =>
|
||||
{
|
||||
const landingPageImage = page.getByTestId('landing-page-figure');
|
||||
```ts
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({
|
||||
isMobile
|
||||
}) => {
|
||||
const landingPageImage = page.getByTestId('landing-page-figure');
|
||||
|
||||
if (isMobile) {
|
||||
await expect(landingPageImage).toBeHidden();
|
||||
} else {
|
||||
await expect(landingPageImage).toBeVisible();
|
||||
}
|
||||
});
|
||||
if (isMobile) {
|
||||
await expect(landingPageImage).toBeHidden();
|
||||
} else {
|
||||
await expect(landingPageImage).toBeVisible();
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### - Group related tests
|
||||
|
||||
Group related tests together using describe blocks. This makes it easier to understand what the tests are doing and what they're testing.
|
||||
Group related tests together using describe blocks. This makes it easier to understand what the tests are doing and what they're testing.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
describe('The campers landing page', () => {
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({isMobile}) =>
|
||||
{
|
||||
...
|
||||
});
|
||||
|
||||
test('The campers landing page figure has the correct image', async () => {
|
||||
...
|
||||
});
|
||||
```ts
|
||||
describe('The campers landing page', () => {
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({
|
||||
isMobile
|
||||
}) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
test('The campers landing page figure has the correct image', async () => {
|
||||
// ...
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## How to Run Tests
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ Sigue estas directrices para configurar un entorno de desarrollo para freeCodeCa
|
||||
|
||||
## Choose between Gitpod or your Own Machine (local setup)
|
||||
|
||||
> [!ATTENTION] **Note:** freeCodeCamp does NOT run natively on Windows 10 or 11, you will need to use WSL2. Puedes seguir [esta guía](how-to-setup-wsl.md) para configurar WSL2. No puedes utilizar Command Prompt, Git Bash o PowerShell para ejecutar freeCodeCamp de forma nativa dentro de windows.
|
||||
> [!ATTENTION] - freeCodeCamp does not build and run natively on Windows, you will [need to use WSL2](how-to-setup-wsl.md) for a Linux-like setup on Windows. - You can't use Windows Command Prompt, Git Bash or PowerShell to build and run the codebase. - Note that if using Windows, the hardware requirements need to be more than [what we mention](how-to-setup-freecodecamp-locally?id=how-to-prepare-your-local-machine) to accommodate for WSL-based setup.
|
||||
|
||||
Si deseas hacer una contribución puntual, debes utilizar Gitpod para realizar cambios. La configuración de Gitpod lanza un entorno listo para codificar en pocos minutos en tu navegador web. Para contribuir a largo plazo, te recomendamos que instales freeCodeCamp en tu máquina local.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Guía oficial de incorporación de moderadores de freeCodeCamp
|
||||
|
||||
Esta guía ayudará a los nuevos moderadores a ponerse en marcha con los procesos y procedimientos que siguen los moderadores experimentados en el foro de la comunidad freeCodeCamp y otras comunidades oficiales que fomentamos.
|
||||
This guide will help new moderators get up and running with the processes and procedures followed by experienced moderators on the freeCodeCamp community forum and other official communities we foster.
|
||||
|
||||
> [!NOTE] Si aún no ha leído el [Manual del moderador](https://contribute.freecodecamp.org/#/moderator-handbook), deberia empezar por ahí primero.
|
||||
|
||||
@@ -18,33 +18,33 @@ Para familiarizarse con las nuevas herramientas y poderes, puede combinar uno o
|
||||
|
||||
### Familiarícese con las herramientas de administración de discord
|
||||
|
||||
El foro freeCodeCamp es en realidad un foro de Discord y sigue muchas de las mismas pautas de otros foros creados en Discord. Para comenzar a familiarizarse con Discord y la función de moderación, comience leyendo la [nueva guía del usuario](https://meta.discourse.org/t/discourse-new-user-guide/96331) de Discord y la [nueva guía del moderador](https://meta.discourse.org/t/discourse-moderation-guide/63116) de Discord.
|
||||
The freeCodeCamp forum is a Discourse forum and follows many of the same guidelines of other forums built on Discourse. Para comenzar a familiarizarse con Discord y la función de moderación, comience leyendo la [nueva guía del usuario](https://meta.discourse.org/t/discourse-new-user-guide/96331) de Discord y la [nueva guía del moderador](https://meta.discourse.org/t/discourse-moderation-guide/63116) de Discord.
|
||||
|
||||
### Shadow a Mod
|
||||
|
||||
Todas las acciones del moderador se pueden seguir revisando los [registros de acciones](https://forum.freecodecamp.org/admin/logs/staff_action_logs). Las acciones realizadas por herramientas automatizadas como `akistmet` o `system` pueden ignorarse en su mayoría hasta que dan como resultado una publicación que debe revisarse. Posts to be reviewed will show up in the [Review](https://forum.freecodecamp.org/review) area of the forum.
|
||||
Todas las acciones del moderador se pueden seguir revisando los [registros de acciones](https://forum.freecodecamp.org/admin/logs/staff_action_logs). The actions taken by automated tools like `Akismet` or `system` can mostly be ignored until they result in a post that needs to be reviewed. Posts to be reviewed will show up in the [Review](https://forum.freecodecamp.org/review) area of the forum.
|
||||
|
||||
For the first week or so you will want to pay attention to what is getting flagged and what is being reviewed, and compare that to the actions being taken upon the flagged posts. You may see the system account flag a post because the user created it too quickly. In many cases, the moderators will unflag the post by clicking on the "Approve Post" button or mark it as "Not Spam" (depending on the flag type).
|
||||
|
||||
Commonly, spam flags can also be raised by members or moderators. Common duplicitous behavior would involve opening an account, making a post that seems harmless, then editing that post later on to add a link to an external site for the purpose of advertising it. In this case, usually the member account is fairly new and has only made this one post thus far, which indicates that the account was opened for the sole purpose of spamming the community. The decision should be made to delete the account after the first offence in this case. The same applies for accounts whose first post is deemed to be spam.
|
||||
Commonly, spam flags can also be raised by members or moderators. Common duplicitous behavior would involve opening an account, making a post that seems harmless, then editing that post later on to add a link to an external site to advertise it. In this case, the member account is usually fairly new and has only made this one post thus far, which indicates that the account was opened solely for spamming the community. The decision should be made to delete the account after the first offense in this case. The same applies to accounts whose first post is deemed to be spam.
|
||||
|
||||
You may notice moderators performing a procedure called 'split topic'. This may be a case where a moderator has split a post that was made erroneously on an existing topic into a new topic, or a moderator merged duplicate topics that a single user has created for the same question. Watching this procedure will highlight different actions and their causes.
|
||||
|
||||
Another useful feature that becomes enabled for all moderators is the ability to post a "Canned Reply" which is a pre-written response that was worked out with the mod team in order to quickly respond to some well-known and repetitive scenarios. These include:
|
||||
Another useful feature that becomes enabled for all moderators is the ability to post a "Canned Reply" which is a pre-written response that was worked out with the mod team to quickly respond to some well-known and repetitive scenarios. These include:
|
||||
|
||||
- Welcoming a new forum member who has posted code without a question -> "Welcome - remind question"
|
||||
- Reminding members not to post code solutions but to provide hints and tips instead -> "Solutions Instead of Help"
|
||||
- Responding to a situation where someone's code works for you but not for them -> "Browser Issues"
|
||||
- Encouraging members to open GitHub issues when a possible bug is found -> "Bug Report"
|
||||
|
||||
There are more, which you can read through to become familiar with their respective uses. You can also find discussion around the templates in the mod-team subforum, and you are welcome to ask questions if you aren't sure how a template should be used.
|
||||
There are more, which you can read through to become familiar with their respective uses. You can also find discussions around the templates in the mod-team subforum, and you are welcome to ask questions if you aren't sure how a template should be used.
|
||||
|
||||
### Read Mod-Team Subforum Posts
|
||||
|
||||
The Mod-Team subforum contains a number of posts from past and current moderators discussing the different requirements and/or challenges of moderating the forum.
|
||||
The Mod-Team subforum contains several posts from past and current moderators discussing the different requirements and/or challenges of moderating the forum.
|
||||
|
||||
Reading back through these posts can help to uncover some of the underlying goals and processes that concern forum moderators. Some of the threads may also shed some light on handling of spam and inappropriate content on the forum.
|
||||
Reading back through these posts can help uncover some of the underlying goals and processes that concern forum moderators. Some of the threads may also shed some light on the handling of spam and inappropriate content on the forum.
|
||||
|
||||
## Where to Ask for Help
|
||||
|
||||
To get help dealing with a situation that you are either uncomfortable with or unsure of how to handle, discuss with your fellow moderators on either the [Mod-Team Subforum](https://forum.freecodecamp.org/c/mod-team/4) or the [#mod-chat](https://discord.com/channels/692816967895220344/693157007418720277) on Discord.
|
||||
To get help dealing with a situation that you are either uncomfortable with or unsure of how to handle, discuss with your fellow moderators on either the [Mod-Team Subforum](https://forum.freecodecamp.org/c/mod-team/4) or the [#mod-chat](https://discord.com/channels/692816967895220344/693157007418720277) on Discord.
|
||||
@@ -10,7 +10,7 @@ pnpm run playwright:install-build-tools
|
||||
|
||||
Alternatively you can follow official documentation referenced below:
|
||||
|
||||
To install and configure Playwright on your machine check out this [documentation](https://playwright.dev/docs/intro#installing-playwright)
|
||||
To install and configure Playwright on your machine check out this [documentation](https://playwright.dev/docs/intro#installing-playwright).
|
||||
|
||||
To learn how to write Playwright tests, or 'specs', please see Playwright's official [documentation](https://playwright.dev/docs/writing-tests).
|
||||
|
||||
@@ -20,141 +20,152 @@ To learn how to write Playwright tests, or 'specs', please see Playwright's offi
|
||||
|
||||
- Playwright test files are always with a `.spec.ts` extension.
|
||||
|
||||
## Best Practices for writing e2e tests
|
||||
## Best Practices for writing E2E tests
|
||||
|
||||
This section will explain in detail about best practices for writing and documenting E2E tests based on playwright documentation and our community code-style.
|
||||
|
||||
### - Identifying a DOM element
|
||||
|
||||
Always use the `data-playwright-test-label` attribute to identify DOM elements. This attribute is used to identify elements in the DOM for testing with playwright only. It is not used for styling or any other purpose.
|
||||
|
||||
For example:
|
||||
|
||||
```html
|
||||
<div data-playwright-test-label="landing-page-figure">
|
||||
<img src="..." alt="..." />
|
||||
</div>
|
||||
```
|
||||
|
||||
Make sure you use the getByTestId method to identify the element in the test file.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
const landingPageFigure = page.getByTestId('landing-page-figure');
|
||||
```
|
||||
This section will explain in detail about best practices for writing and documenting E2E tests based on Playwright documentation and our community code-style.
|
||||
|
||||
### - Imports
|
||||
|
||||
Always start with necessary imports at the beginning of the file.
|
||||
Always start with necessary imports at the beginning of the file.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
import { test, expect, type Page } from '@playwright/test';
|
||||
```
|
||||
```ts
|
||||
import { test, expect, type Page } from '@playwright/test';
|
||||
```
|
||||
|
||||
### - Identifying a DOM element
|
||||
|
||||
Playwright comes with [multiple built-in locators](https://playwright.dev/docs/locators#quick-guide), but we recommend prioritizing the following locators:
|
||||
- `getByRole` for querying semantic elements, whose role is important and allows assistive technology to perceive the page correctly.
|
||||
- `getByText` for querying non-semantic elements such as `div`, `span`, or `p`.
|
||||
|
||||
For example:
|
||||
```ts
|
||||
await expect(page.getByRole('heading', { name: 'Sign up' })).toBeVisible();
|
||||
await expect(page.getByText('Hello World')).toBeVisible();
|
||||
```
|
||||
|
||||
In cases where the elements cannot be queried using the above-mentioned locators, you can use the `data-playwright-test-label` attribute as the last resort. This attribute is used to identify elements in the DOM for testing with playwright only. It is not used for styling or any other purpose.
|
||||
|
||||
For example:
|
||||
|
||||
```html
|
||||
<div data-playwright-test-label="landing-page-figure">
|
||||
<img src="..." alt="..." />
|
||||
</div>
|
||||
```
|
||||
|
||||
In the test file, you can use the `getByTestId` method to identify the element.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
await expect(page.getByTestId('landing-page-figure')).toBeVisible();
|
||||
```
|
||||
|
||||
### - Constants
|
||||
|
||||
Define any constant elements, data sets, or configurations used throughout your tests for easy reference.
|
||||
Define any constant elements, data sets, or configurations used throughout your tests for easy reference.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
const landingPageElements = { ... };
|
||||
const superBlocks = [ ... ];
|
||||
```
|
||||
```ts
|
||||
const landingPageElements = { ... };
|
||||
const superBlocks = [ ... ];
|
||||
```
|
||||
|
||||
### - Shared Context
|
||||
|
||||
If tests depend on a shared context (like a loaded web page), use beforeAll and afterAll hooks to set up and tear down that context.
|
||||
If tests depend on a shared context (like a loaded web page), use beforeAll and afterAll hooks to set up and tear down that context.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
let page: Page;
|
||||
```ts
|
||||
let page: Page;
|
||||
|
||||
beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
});
|
||||
beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await page.close();
|
||||
});
|
||||
```
|
||||
afterAll(async () => {
|
||||
await page.close();
|
||||
});
|
||||
```
|
||||
|
||||
### - Descriptive test names
|
||||
|
||||
Each test block should have a clear and concise name describing exactly what it's testing.
|
||||
Each test block should have a clear and concise name describing exactly what it's testing.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
test('The component landing-top renders correctly', async ({ page }) => {
|
||||
...
|
||||
});
|
||||
```
|
||||
```ts
|
||||
test('The component landing-top renders correctly', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
### - Human readable assertions
|
||||
|
||||
Each assertion should be as human readable as possible. This makes it easier to understand what the test is doing and what it's expecting.
|
||||
Each assertion should be as human readable as possible. This makes it easier to understand what the test is doing and what it's expecting.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
await expect(landingHeading1).toHaveText('Learn to code — for free.');
|
||||
```
|
||||
```ts
|
||||
await expect(landingHeading1).toHaveText('Learn to code — for free.');
|
||||
```
|
||||
|
||||
### - Keep it DRY
|
||||
|
||||
Make sure that the tests are not repeating the same code over and over again. If you find yourself repeating the same code, consider refactoring it as a loop or a function.
|
||||
Make sure that the tests are not repeating the same code over and over again. If you find yourself repeating the same code, consider refactoring it as a loop or a function.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
for (const logo of await logos.all()) {
|
||||
await expect(logo).toBeVisible();
|
||||
}
|
||||
```
|
||||
```ts
|
||||
for (const logo of await logos.all()) {
|
||||
await expect(logo).toBeVisible();
|
||||
}
|
||||
```
|
||||
|
||||
### - Tests for mobile screens
|
||||
|
||||
Use the 'isMobile' argument to run tests that incude logic that varies for mobile screens.
|
||||
Use the `isMobile` argument to run tests that include logic that varies for mobile screens.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({isMobile}) =>
|
||||
{
|
||||
const landingPageImage = page.getByTestId('landing-page-figure');
|
||||
```ts
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({
|
||||
isMobile
|
||||
}) => {
|
||||
const landingPageImage = page.getByTestId('landing-page-figure');
|
||||
|
||||
if (isMobile) {
|
||||
await expect(landingPageImage).toBeHidden();
|
||||
} else {
|
||||
await expect(landingPageImage).toBeVisible();
|
||||
}
|
||||
});
|
||||
if (isMobile) {
|
||||
await expect(landingPageImage).toBeHidden();
|
||||
} else {
|
||||
await expect(landingPageImage).toBeVisible();
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### - Group related tests
|
||||
|
||||
Group related tests together using describe blocks. This makes it easier to understand what the tests are doing and what they're testing.
|
||||
Group related tests together using describe blocks. This makes it easier to understand what the tests are doing and what they're testing.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
describe('The campers landing page', () => {
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({isMobile}) =>
|
||||
{
|
||||
...
|
||||
});
|
||||
|
||||
test('The campers landing page figure has the correct image', async () => {
|
||||
...
|
||||
});
|
||||
```ts
|
||||
describe('The campers landing page', () => {
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({
|
||||
isMobile
|
||||
}) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
test('The campers landing page figure has the correct image', async () => {
|
||||
// ...
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## How to Run Tests
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ Follow these guidelines for setting up a development environment for freeCodeCam
|
||||
|
||||
## Choose between Gitpod or your Own Machine (local setup)
|
||||
|
||||
> [!ATTENTION] **Note:** freeCodeCamp does NOT run natively on Windows 10 or 11, you will need to use WSL2. You can follow [this guide](how-to-setup-wsl.md) to set up WSL2. You can't use Command Prompt, Git Bash or PowerShell to run freeCodeCamp natively within windows.
|
||||
> [!ATTENTION] - freeCodeCamp does not build and run natively on Windows, you will [need to use WSL2](how-to-setup-wsl.md) for a Linux-like setup on Windows. - You can't use Windows Command Prompt, Git Bash or PowerShell to build and run the codebase. - Note that if using Windows, the hardware requirements need to be more than [what we mention](how-to-setup-freecodecamp-locally?id=how-to-prepare-your-local-machine) to accommodate for WSL-based setup.
|
||||
|
||||
If you are looking to make a one-off contribution, you should use Gitpod to make changes. The Gitpod setup launches a ready-to-code environment in a few minutes in your web browser. For contributing long-term, we recommend you setup freeCodeCamp on your local machine.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Der offizielle freeCodeCamp Moderator Onboarding Leitfaden
|
||||
|
||||
Dieser Leitfaden hilft neuen Moderatoren dabei, sich mit den Prozessen und Verfahren vertraut zu machen, die erfahrene Moderatoren im freeCodeCamp-Community-Forum und anderen offiziellen Communities, die wir betreuen, anwenden.
|
||||
This guide will help new moderators get up and running with the processes and procedures followed by experienced moderators on the freeCodeCamp community forum and other official communities we foster.
|
||||
|
||||
> [!NOTE] Wenn du [Das Moderatorenhandbuch](https://contribute.freecodecamp.org/#/moderator-handbook) noch nicht gelesen hast, solltest du dort zuerst anfangen.
|
||||
|
||||
@@ -18,33 +18,33 @@ Um dich mit den neuen Werkzeugen und Rechten vertraut zu machen, kannst du in de
|
||||
|
||||
### Mach dich mit den Discourse Admin Tools vertraut
|
||||
|
||||
Das freeCodeCamp-Forum ist eigentlich ein Discourse-Forum und folgt vielen gleichen Richtlinien anderer Foren, die auf Discourse aufbauen. Um dich mit Discourse und der Moderatorenrolle vertraut zu machen, lies zunächst den [Leitfaden für neue Benutzer](https://meta.discourse.org/t/discourse-new-user-guide/96331) und den [Leitfaden für neue Moderatoren](https://meta.discourse.org/t/discourse-moderation-guide/63116) von Discourse.
|
||||
The freeCodeCamp forum is a Discourse forum and follows many of the same guidelines of other forums built on Discourse. Um dich mit Discourse und der Moderatorenrolle vertraut zu machen, lies zunächst den [Leitfaden für neue Benutzer](https://meta.discourse.org/t/discourse-new-user-guide/96331) und den [Leitfaden für neue Moderatoren](https://meta.discourse.org/t/discourse-moderation-guide/63116) von Discourse.
|
||||
|
||||
### Folge einem Moderator aufmerksam
|
||||
|
||||
Alle Aktionen der Moderatoren können in den [Aktionsprotokollen](https://forum.freecodecamp.org/admin/logs/staff_action_logs) nachverfolgt werden. Die Aktionen, die von automatisierten Tools wie `akistmet` oder `system` durchgeführt werden, können meist ignoriert werden, bis sie zu einem Beitrag führen, der überprüft werden muss. Beiträge, die überprüft werden sollen, werden im Bereich [Review](https://forum.freecodecamp.org/review) des Forums angezeigt.
|
||||
Alle Aktionen der Moderatoren können in den [Aktionsprotokollen](https://forum.freecodecamp.org/admin/logs/staff_action_logs) nachverfolgt werden. The actions taken by automated tools like `Akismet` or `system` can mostly be ignored until they result in a post that needs to be reviewed. Beiträge, die überprüft werden sollen, werden im Bereich [Review](https://forum.freecodecamp.org/review) des Forums angezeigt.
|
||||
|
||||
In der ersten Woche solltest du darauf achten, was markiert und was überprüft wird, und dies mit den Maßnahmen vergleichen, die aufgrund der markierten Beiträge ergriffen werden. Es kann vorkommen, dass das Systemkonto einen Beitrag markiert, weil der Benutzer ihn zu schnell erstellt hat. In vielen Fällen heben die Moderatoren die Markierung des Beitrags auf, indem sie auf die Schaltfläche "Approve Post" klicken oder ihn als "Not Spam" markieren (je nach Art der Markierung).
|
||||
|
||||
In der Regel können Spam-Markierungen auch von Mitgliedern oder Moderatoren gesetzt werden. Common duplicitous behavior would involve opening an account, making a post that seems harmless, then editing that post later on to add a link to an external site for the purpose of advertising it. In diesem Fall ist das Mitgliedskonto in der Regel recht neu und hat bisher nur diesen einen Beitrag verfasst, was darauf hindeutet, dass das Konto nur zu dem Zweck eröffnet wurde, die Community zu spammen. In diesem Fall sollte die Entscheidung getroffen werden, das Konto nach dem ersten Verstoß zu löschen. Das Gleiche gilt für Konten, deren erster Beitrag als Spam eingestuft wird.
|
||||
In der Regel können Spam-Markierungen auch von Mitgliedern oder Moderatoren gesetzt werden. Common duplicitous behavior would involve opening an account, making a post that seems harmless, then editing that post later on to add a link to an external site to advertise it. In this case, the member account is usually fairly new and has only made this one post thus far, which indicates that the account was opened solely for spamming the community. The decision should be made to delete the account after the first offense in this case. The same applies to accounts whose first post is deemed to be spam.
|
||||
|
||||
Vielleicht bemerkst du, dass die Moderatoren ein Verfahren namens "Split Topic" anwenden. Dies kann der Fall sein, wenn ein Moderator einen Beitrag, der fälschlicherweise in einem bestehenden Thema verfasst wurde, in ein neues Thema getrennt hat, oder wenn ein Moderator doppelte Themen zusammengeführt hat, die ein einzelner Benutzer für dieselbe Frage erstellt hat. Wenn du dir diesen Vorgang ansiehst, werden verschiedene Aktionen und ihre Ursachen deutlich.
|
||||
|
||||
Eine weitere nützliche Funktion, die für alle Moderatoren aktiviert wird, ist die Möglichkeit, eine "Canned Reply" zu posten. Dabei handelt es sich um eine vorformulierte Antwort, die mit dem Mod-Team ausgearbeitet wurde, um schnell auf einige bekannte und sich wiederholende Szenarien reagieren zu können. Dazu gehören:
|
||||
Another useful feature that becomes enabled for all moderators is the ability to post a "Canned Reply" which is a pre-written response that was worked out with the mod team to quickly respond to some well-known and repetitive scenarios. Dazu gehören:
|
||||
|
||||
- Begrüßung eines neuen Forumsmitglieds, das Code ohne eine Frage gepostet hat -> " Welcome - remind question"
|
||||
- Erinnerung an Mitglieder, keine Code-Lösungen zu posten, sondern stattdessen Hinweise und Tipps zu geben -> " Solutions Instead of Help"
|
||||
- Reagiere auf eine Situation, in der der Code von jemandem bei dir funktioniert, bei ihm aber nicht -> " Browser Issues"
|
||||
- Ermutigung der Mitglieder, GitHub-Issues zu erstellen, wenn ein möglicher Fehler gefunden wird -> "Bug Report"
|
||||
|
||||
Es gibt noch mehr, die du dir durchlesen kannst, um dich mit ihren jeweiligen Einsatzmöglichkeiten vertraut zu machen. Du kannst auch im Subforum des Mod-Teams über die Vorlagen diskutieren und du kannst gerne Fragen stellen, wenn du dir nicht sicher bist, wie eine Vorlage verwendet werden sollte.
|
||||
Es gibt noch mehr, die du dir durchlesen kannst, um dich mit ihren jeweiligen Einsatzmöglichkeiten vertraut zu machen. You can also find discussions around the templates in the mod-team subforum, and you are welcome to ask questions if you aren't sure how a template should be used.
|
||||
|
||||
### Lies die Beiträge des Mod-Teams im Subforum
|
||||
|
||||
Das Subforum des Mod-Teams enthält eine Reihe von Beiträgen ehemaliger und aktueller Moderatoren, die über die verschiedenen Anforderungen und/oder Herausforderungen der Moderation des Forums diskutieren.
|
||||
The Mod-Team subforum contains several posts from past and current moderators discussing the different requirements and/or challenges of moderating the forum.
|
||||
|
||||
Das Lesen dieser Beiträge kann dabei helfen, einige der zugrundeliegenden Ziele und Prozesse aufzudecken, die die Forenmoderatoren betreffen. Einige der Threads können auch Aufschluss über den Umgang mit Spam und unangemessenen Inhalten im Forum geben.
|
||||
Reading back through these posts can help uncover some of the underlying goals and processes that concern forum moderators. Some of the threads may also shed some light on the handling of spam and inappropriate content on the forum.
|
||||
|
||||
## Wo du um Hilfe bitten kannst
|
||||
|
||||
Wenn du Hilfe brauchst, um mit einer Situation umzugehen, die dir unangenehm ist oder bei der du unsicher bist, diskutiere mit deinen Moderationskollegen entweder im [Mod-Team Subforum](https://forum.freecodecamp.org/c/mod-team/4) oder im [#mod-chat](https://discord.com/channels/692816967895220344/693157007418720277) auf Discord.
|
||||
Wenn du Hilfe brauchst, um mit einer Situation umzugehen, die dir unangenehm ist oder bei der du unsicher bist, diskutiere mit deinen Moderationskollegen entweder im [Mod-Team Subforum](https://forum.freecodecamp.org/c/mod-team/4) oder im [#mod-chat](https://discord.com/channels/692816967895220344/693157007418720277) auf Discord.
|
||||
@@ -10,7 +10,7 @@ pnpm run playwright:install-build-tools
|
||||
|
||||
Alternatively you can follow official documentation referenced below:
|
||||
|
||||
To install and configure Playwright on your machine check out this [documentation](https://playwright.dev/docs/intro#installing-playwright)
|
||||
To install and configure Playwright on your machine check out this [documentation](https://playwright.dev/docs/intro#installing-playwright).
|
||||
|
||||
To learn how to write Playwright tests, or 'specs', please see Playwright's official [documentation](https://playwright.dev/docs/writing-tests).
|
||||
|
||||
@@ -20,141 +20,152 @@ To learn how to write Playwright tests, or 'specs', please see Playwright's offi
|
||||
|
||||
- Playwright test files are always with a `.spec.ts` extension.
|
||||
|
||||
## Best Practices for writing e2e tests
|
||||
## Best Practices for writing E2E tests
|
||||
|
||||
This section will explain in detail about best practices for writing and documenting E2E tests based on playwright documentation and our community code-style.
|
||||
|
||||
### - Identifying a DOM element
|
||||
|
||||
Always use the `data-playwright-test-label` attribute to identify DOM elements. This attribute is used to identify elements in the DOM for testing with playwright only. It is not used for styling or any other purpose.
|
||||
|
||||
For example:
|
||||
|
||||
```html
|
||||
<div data-playwright-test-label="landing-page-figure">
|
||||
<img src="..." alt="..." />
|
||||
</div>
|
||||
```
|
||||
|
||||
Make sure you use the getByTestId method to identify the element in the test file.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
const landingPageFigure = page.getByTestId('landing-page-figure');
|
||||
```
|
||||
This section will explain in detail about best practices for writing and documenting E2E tests based on Playwright documentation and our community code-style.
|
||||
|
||||
### - Imports
|
||||
|
||||
Always start with necessary imports at the beginning of the file.
|
||||
Always start with necessary imports at the beginning of the file.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
import { test, expect, type Page } from '@playwright/test';
|
||||
```
|
||||
```ts
|
||||
import { test, expect, type Page } from '@playwright/test';
|
||||
```
|
||||
|
||||
### - Identifying a DOM element
|
||||
|
||||
Playwright comes with [multiple built-in locators](https://playwright.dev/docs/locators#quick-guide), but we recommend prioritizing the following locators:
|
||||
- `getByRole` for querying semantic elements, whose role is important and allows assistive technology to perceive the page correctly.
|
||||
- `getByText` for querying non-semantic elements such as `div`, `span`, or `p`.
|
||||
|
||||
For example:
|
||||
```ts
|
||||
await expect(page.getByRole('heading', { name: 'Sign up' })).toBeVisible();
|
||||
await expect(page.getByText('Hello World')).toBeVisible();
|
||||
```
|
||||
|
||||
In cases where the elements cannot be queried using the above-mentioned locators, you can use the `data-playwright-test-label` attribute as the last resort. This attribute is used to identify elements in the DOM for testing with playwright only. It is not used for styling or any other purpose.
|
||||
|
||||
For example:
|
||||
|
||||
```html
|
||||
<div data-playwright-test-label="landing-page-figure">
|
||||
<img src="..." alt="..." />
|
||||
</div>
|
||||
```
|
||||
|
||||
In the test file, you can use the `getByTestId` method to identify the element.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
await expect(page.getByTestId('landing-page-figure')).toBeVisible();
|
||||
```
|
||||
|
||||
### - Constants
|
||||
|
||||
Define any constant elements, data sets, or configurations used throughout your tests for easy reference.
|
||||
Define any constant elements, data sets, or configurations used throughout your tests for easy reference.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
const landingPageElements = { ... };
|
||||
const superBlocks = [ ... ];
|
||||
```
|
||||
```ts
|
||||
const landingPageElements = { ... };
|
||||
const superBlocks = [ ... ];
|
||||
```
|
||||
|
||||
### - Shared Context
|
||||
|
||||
If tests depend on a shared context (like a loaded web page), use beforeAll and afterAll hooks to set up and tear down that context.
|
||||
If tests depend on a shared context (like a loaded web page), use beforeAll and afterAll hooks to set up and tear down that context.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
let page: Page;
|
||||
```ts
|
||||
let page: Page;
|
||||
|
||||
beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
});
|
||||
beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await page.close();
|
||||
});
|
||||
```
|
||||
afterAll(async () => {
|
||||
await page.close();
|
||||
});
|
||||
```
|
||||
|
||||
### - Descriptive test names
|
||||
|
||||
Each test block should have a clear and concise name describing exactly what it's testing.
|
||||
Each test block should have a clear and concise name describing exactly what it's testing.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
test('The component landing-top renders correctly', async ({ page }) => {
|
||||
...
|
||||
});
|
||||
```
|
||||
```ts
|
||||
test('The component landing-top renders correctly', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
### - Human readable assertions
|
||||
|
||||
Each assertion should be as human readable as possible. This makes it easier to understand what the test is doing and what it's expecting.
|
||||
Each assertion should be as human readable as possible. This makes it easier to understand what the test is doing and what it's expecting.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
await expect(landingHeading1).toHaveText('Learn to code — for free.');
|
||||
```
|
||||
```ts
|
||||
await expect(landingHeading1).toHaveText('Learn to code — for free.');
|
||||
```
|
||||
|
||||
### - Keep it DRY
|
||||
|
||||
Make sure that the tests are not repeating the same code over and over again. If you find yourself repeating the same code, consider refactoring it as a loop or a function.
|
||||
Make sure that the tests are not repeating the same code over and over again. If you find yourself repeating the same code, consider refactoring it as a loop or a function.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
for (const logo of await logos.all()) {
|
||||
await expect(logo).toBeVisible();
|
||||
}
|
||||
```
|
||||
```ts
|
||||
for (const logo of await logos.all()) {
|
||||
await expect(logo).toBeVisible();
|
||||
}
|
||||
```
|
||||
|
||||
### - Tests for mobile screens
|
||||
|
||||
Use the 'isMobile' argument to run tests that incude logic that varies for mobile screens.
|
||||
Use the `isMobile` argument to run tests that include logic that varies for mobile screens.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({isMobile}) =>
|
||||
{
|
||||
const landingPageImage = page.getByTestId('landing-page-figure');
|
||||
```ts
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({
|
||||
isMobile
|
||||
}) => {
|
||||
const landingPageImage = page.getByTestId('landing-page-figure');
|
||||
|
||||
if (isMobile) {
|
||||
await expect(landingPageImage).toBeHidden();
|
||||
} else {
|
||||
await expect(landingPageImage).toBeVisible();
|
||||
}
|
||||
});
|
||||
if (isMobile) {
|
||||
await expect(landingPageImage).toBeHidden();
|
||||
} else {
|
||||
await expect(landingPageImage).toBeVisible();
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### - Group related tests
|
||||
|
||||
Group related tests together using describe blocks. This makes it easier to understand what the tests are doing and what they're testing.
|
||||
Group related tests together using describe blocks. This makes it easier to understand what the tests are doing and what they're testing.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
describe('The campers landing page', () => {
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({isMobile}) =>
|
||||
{
|
||||
...
|
||||
});
|
||||
|
||||
test('The campers landing page figure has the correct image', async () => {
|
||||
...
|
||||
});
|
||||
```ts
|
||||
describe('The campers landing page', () => {
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({
|
||||
isMobile
|
||||
}) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
test('The campers landing page figure has the correct image', async () => {
|
||||
// ...
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## How to Run Tests
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ Follow these guidelines for setting up a development environment for freeCodeCam
|
||||
|
||||
## Choose between Gitpod or your Own Machine (local setup)
|
||||
|
||||
> [!ATTENTION] **Note:** freeCodeCamp does NOT run natively on Windows 10 or 11, you will need to use WSL2. You can follow [this guide](how-to-setup-wsl.md) to set up WSL2. You can't use Command Prompt, Git Bash or PowerShell to run freeCodeCamp natively within windows.
|
||||
> [!ATTENTION] - freeCodeCamp does not build and run natively on Windows, you will [need to use WSL2](how-to-setup-wsl.md) for a Linux-like setup on Windows. - You can't use Windows Command Prompt, Git Bash or PowerShell to build and run the codebase. - Note that if using Windows, the hardware requirements need to be more than [what we mention](how-to-setup-freecodecamp-locally?id=how-to-prepare-your-local-machine) to accommodate for WSL-based setup.
|
||||
|
||||
If you are looking to make a one-off contribution, you should use Gitpod to make changes. The Gitpod setup launches a ready-to-code environment in a few minutes in your web browser. For contributing long-term, we recommend you setup freeCodeCamp on your local machine.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# La guida di onboarding ufficiale del moderatore di freeCodeCamp
|
||||
|
||||
Questa guida aiuterà i nuovi moderatori a prendere parte ed eseguire i processi e le procedure seguiti da moderatori esperti sul forum della comunità di freeCodeCamp e altre comunità ufficiali che promuoviamo.
|
||||
This guide will help new moderators get up and running with the processes and procedures followed by experienced moderators on the freeCodeCamp community forum and other official communities we foster.
|
||||
|
||||
> [!NOTE] Se non hai ancora letto [Il manuale del moderatore](https://contribute.freecodecamp.org/#/i18n/italian/moderator-handbook) dovresti iniziare da lì.
|
||||
|
||||
@@ -18,33 +18,33 @@ Per acquisire familiarità con i nuovi strumenti e poteri, puoi combinare uno o
|
||||
|
||||
### Acquisisci familiarità con gli strumenti admin di Discourse
|
||||
|
||||
Il forum freeCodeCamp è in realtà un forum Discourse e segue molte delle stesse linee guida di altri forum costruiti su Discourse. Per iniziare a prendere confidenza con il ruolo di moderatore di Discourse, inizia a leggere la [guida per i nuovi utenti](https://meta.discourse.org/t/discourse-new-user-guide/96331) di Discourse e la[guida per i nuovi moderatori](https://meta.discourse.org/t/discourse-moderation-guide/63116) di Discourse.
|
||||
The freeCodeCamp forum is a Discourse forum and follows many of the same guidelines of other forums built on Discourse. Per iniziare a prendere confidenza con il ruolo di moderatore di Discourse, inizia a leggere la [guida per i nuovi utenti](https://meta.discourse.org/t/discourse-new-user-guide/96331) di Discourse e la[guida per i nuovi moderatori](https://meta.discourse.org/t/discourse-moderation-guide/63116) di Discourse.
|
||||
|
||||
### Seguire un moderatore
|
||||
|
||||
Tutte le azioni da moderatore possono essere seguite rivedendo gli [action log](https://forum.freecodecamp.org/admin/logs/staff_action_logs). Le azioni intraprese tramite strumenti automatizzati come `akistmet` o `system` possono essere per lo più ignorate finché non hanno come conseguenza un post che deve essere revisionato. I post da revisionare appariranno nell'area [Review](https://forum.freecodecamp.org/review) del forum.
|
||||
Tutte le azioni da moderatore possono essere seguite rivedendo gli [action log](https://forum.freecodecamp.org/admin/logs/staff_action_logs). The actions taken by automated tools like `Akismet` or `system` can mostly be ignored until they result in a post that needs to be reviewed. I post da revisionare appariranno nell'area [Review](https://forum.freecodecamp.org/review) del forum.
|
||||
|
||||
Per la prima settimana o giù di lì, presta attenzione a ciò che viene contrassegnato e ciò che è in fase di revisione, e confrontalo con le azioni intraprese sui post contrassegnati. Potresti vedere l'account di sistema contrassegnare un post perché l'utente lo ha creato troppo rapidamente. In molti casi, i moderatori cancelleranno il flag del post cliccando sul pulsante "Approve Post" o contrassegnandolo come "Not Spam" (a seconda del tipo di flag).
|
||||
|
||||
Comunemente, i flag di spam possono anche essere usati da membri o moderatori. Common duplicitous behavior would involve opening an account, making a post that seems harmless, then editing that post later on to add a link to an external site for the purpose of advertising it. In questo caso, di solito l'account del membro è abbastanza nuovo e ha fatto questo solo post finora, il che indica che l'account è stato aperto al solo scopo di spamming. È opportuno decidere di cancellare l'account dopo la prima infrazione in questo caso. Lo stesso vale per gli account il cui primo post è considerato spam.
|
||||
Comunemente, i flag di spam possono anche essere usati da membri o moderatori. Common duplicitous behavior would involve opening an account, making a post that seems harmless, then editing that post later on to add a link to an external site to advertise it. In this case, the member account is usually fairly new and has only made this one post thus far, which indicates that the account was opened solely for spamming the community. The decision should be made to delete the account after the first offense in this case. The same applies to accounts whose first post is deemed to be spam.
|
||||
|
||||
Puoi notare moderatori che eseguono una procedura chiamata 'split topic'. Questo può essere un caso in cui un moderatore ha smistato un post che è stato fatto erroneamente su un argomento esistente in un nuovo argomento, o un moderatore ha unito argomenti duplicati che un singolo utente ha creato per la stessa domanda. Guardare questa procedura metterà in evidenza le diverse azioni e le loro cause.
|
||||
|
||||
Un'altra caratteristica utile che vine abilitata per tutti i moderatori è la possibilità di pubblicare una "Canned Reply", che è una risposta già scritta che è stata elaborata con il team dei mod al fine di rispondere rapidamente ad alcuni scenari ben noti e ripetuti. Questi comprendono:
|
||||
Another useful feature that becomes enabled for all moderators is the ability to post a "Canned Reply" which is a pre-written response that was worked out with the mod team to quickly respond to some well-known and repetitive scenarios. Questi comprendono:
|
||||
|
||||
- Accogliere un nuovo membro del forum che ha postato del codice senza una domanda -> "Welcome - remind question"
|
||||
- Ricordare ai membri di non postare il codice delle soluzioni ma di fornire indizi e suggerimenti -> "Solutions Instead of Help"
|
||||
- Rispondere a una situazione in cui il codice di qualcuno funziona per te ma non per lui -> "Browser Issues"
|
||||
- Incoraggiare i membri ad aprire una issue su GitHub quando viene trovato un possibile bug -> "Bug Report"
|
||||
|
||||
Ce ne sono altre, che puoi leggere per acquisire familiarità con i rispettivi utilizzi. Puoi anche trovare una discussione sui modelli nel subforum mod-team, e sei invitato a fare domande se non sei sicuro di come dovrebbe essere utilizzato un modello.
|
||||
Ce ne sono altre, che puoi leggere per acquisire familiarità con i rispettivi utilizzi. You can also find discussions around the templates in the mod-team subforum, and you are welcome to ask questions if you aren't sure how a template should be used.
|
||||
|
||||
### Leggere i post del subforum Mod-Team
|
||||
|
||||
Il subforum Mod-Team contiene una serie di post di moderatori passati e attuali che discutono le diverse esigenze e/o sfide di moderare il forum.
|
||||
The Mod-Team subforum contains several posts from past and current moderators discussing the different requirements and/or challenges of moderating the forum.
|
||||
|
||||
Rileggere questi post può aiutare a scoprire alcuni degli obiettivi e dei processi fondamentali che riguardano i moderatori del forum. Alcuni dei thread possono anche fare luce sulla gestione dello spam e dei contenuti inappropriati sul forum.
|
||||
Reading back through these posts can help uncover some of the underlying goals and processes that concern forum moderators. Some of the threads may also shed some light on the handling of spam and inappropriate content on the forum.
|
||||
|
||||
## Dove chiedere aiuto
|
||||
|
||||
Per ottenere aiuto con delle situazioni con cui non ti senti a tuo agio o che non sei sicuro di come gestire, discuti con i tuoi compagni moderatori nel [Subforum Mod-Team](https://forum.freecodecamp.org/c/mod-team/4) o nella [#mod-chat](https://discord.com/channels/692816967895220344/693157007418720277) su Discord.
|
||||
Per ottenere aiuto con delle situazioni con cui non ti senti a tuo agio o che non sei sicuro di come gestire, discuti con i tuoi compagni moderatori nel [Subforum Mod-Team](https://forum.freecodecamp.org/c/mod-team/4) o nella [#mod-chat](https://discord.com/channels/692816967895220344/693157007418720277) su Discord.
|
||||
@@ -10,7 +10,7 @@ pnpm run playwright:install-build-tools
|
||||
|
||||
Alternatively you can follow official documentation referenced below:
|
||||
|
||||
To install and configure Playwright on your machine check out this [documentation](https://playwright.dev/docs/intro#installing-playwright)
|
||||
To install and configure Playwright on your machine check out this [documentation](https://playwright.dev/docs/intro#installing-playwright).
|
||||
|
||||
To learn how to write Playwright tests, or 'specs', please see Playwright's official [documentation](https://playwright.dev/docs/writing-tests).
|
||||
|
||||
@@ -20,141 +20,152 @@ To learn how to write Playwright tests, or 'specs', please see Playwright's offi
|
||||
|
||||
- Playwright test files are always with a `.spec.ts` extension.
|
||||
|
||||
## Best Practices for writing e2e tests
|
||||
## Best Practices for writing E2E tests
|
||||
|
||||
This section will explain in detail about best practices for writing and documenting E2E tests based on playwright documentation and our community code-style.
|
||||
|
||||
### - Identifying a DOM element
|
||||
|
||||
Always use the `data-playwright-test-label` attribute to identify DOM elements. This attribute is used to identify elements in the DOM for testing with playwright only. It is not used for styling or any other purpose.
|
||||
|
||||
For example:
|
||||
|
||||
```html
|
||||
<div data-playwright-test-label="landing-page-figure">
|
||||
<img src="..." alt="..." />
|
||||
</div>
|
||||
```
|
||||
|
||||
Make sure you use the getByTestId method to identify the element in the test file.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
const landingPageFigure = page.getByTestId('landing-page-figure');
|
||||
```
|
||||
This section will explain in detail about best practices for writing and documenting E2E tests based on Playwright documentation and our community code-style.
|
||||
|
||||
### - Imports
|
||||
|
||||
Always start with necessary imports at the beginning of the file.
|
||||
Always start with necessary imports at the beginning of the file.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
import { test, expect, type Page } from '@playwright/test';
|
||||
```
|
||||
```ts
|
||||
import { test, expect, type Page } from '@playwright/test';
|
||||
```
|
||||
|
||||
### - Identifying a DOM element
|
||||
|
||||
Playwright comes with [multiple built-in locators](https://playwright.dev/docs/locators#quick-guide), but we recommend prioritizing the following locators:
|
||||
- `getByRole` for querying semantic elements, whose role is important and allows assistive technology to perceive the page correctly.
|
||||
- `getByText` for querying non-semantic elements such as `div`, `span`, or `p`.
|
||||
|
||||
For example:
|
||||
```ts
|
||||
await expect(page.getByRole('heading', { name: 'Sign up' })).toBeVisible();
|
||||
await expect(page.getByText('Hello World')).toBeVisible();
|
||||
```
|
||||
|
||||
In cases where the elements cannot be queried using the above-mentioned locators, you can use the `data-playwright-test-label` attribute as the last resort. This attribute is used to identify elements in the DOM for testing with playwright only. It is not used for styling or any other purpose.
|
||||
|
||||
For example:
|
||||
|
||||
```html
|
||||
<div data-playwright-test-label="landing-page-figure">
|
||||
<img src="..." alt="..." />
|
||||
</div>
|
||||
```
|
||||
|
||||
In the test file, you can use the `getByTestId` method to identify the element.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
await expect(page.getByTestId('landing-page-figure')).toBeVisible();
|
||||
```
|
||||
|
||||
### - Constants
|
||||
|
||||
Define any constant elements, data sets, or configurations used throughout your tests for easy reference.
|
||||
Define any constant elements, data sets, or configurations used throughout your tests for easy reference.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
const landingPageElements = { ... };
|
||||
const superBlocks = [ ... ];
|
||||
```
|
||||
```ts
|
||||
const landingPageElements = { ... };
|
||||
const superBlocks = [ ... ];
|
||||
```
|
||||
|
||||
### - Shared Context
|
||||
|
||||
If tests depend on a shared context (like a loaded web page), use beforeAll and afterAll hooks to set up and tear down that context.
|
||||
If tests depend on a shared context (like a loaded web page), use beforeAll and afterAll hooks to set up and tear down that context.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
let page: Page;
|
||||
```ts
|
||||
let page: Page;
|
||||
|
||||
beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
});
|
||||
beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await page.close();
|
||||
});
|
||||
```
|
||||
afterAll(async () => {
|
||||
await page.close();
|
||||
});
|
||||
```
|
||||
|
||||
### - Descriptive test names
|
||||
|
||||
Each test block should have a clear and concise name describing exactly what it's testing.
|
||||
Each test block should have a clear and concise name describing exactly what it's testing.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
test('The component landing-top renders correctly', async ({ page }) => {
|
||||
...
|
||||
});
|
||||
```
|
||||
```ts
|
||||
test('The component landing-top renders correctly', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
### - Human readable assertions
|
||||
|
||||
Each assertion should be as human readable as possible. This makes it easier to understand what the test is doing and what it's expecting.
|
||||
Each assertion should be as human readable as possible. This makes it easier to understand what the test is doing and what it's expecting.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
await expect(landingHeading1).toHaveText('Learn to code — for free.');
|
||||
```
|
||||
```ts
|
||||
await expect(landingHeading1).toHaveText('Learn to code — for free.');
|
||||
```
|
||||
|
||||
### - Keep it DRY
|
||||
|
||||
Make sure that the tests are not repeating the same code over and over again. If you find yourself repeating the same code, consider refactoring it as a loop or a function.
|
||||
Make sure that the tests are not repeating the same code over and over again. If you find yourself repeating the same code, consider refactoring it as a loop or a function.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
for (const logo of await logos.all()) {
|
||||
await expect(logo).toBeVisible();
|
||||
}
|
||||
```
|
||||
```ts
|
||||
for (const logo of await logos.all()) {
|
||||
await expect(logo).toBeVisible();
|
||||
}
|
||||
```
|
||||
|
||||
### - Tests for mobile screens
|
||||
|
||||
Use the 'isMobile' argument to run tests that incude logic that varies for mobile screens.
|
||||
Use the `isMobile` argument to run tests that include logic that varies for mobile screens.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({isMobile}) =>
|
||||
{
|
||||
const landingPageImage = page.getByTestId('landing-page-figure');
|
||||
```ts
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({
|
||||
isMobile
|
||||
}) => {
|
||||
const landingPageImage = page.getByTestId('landing-page-figure');
|
||||
|
||||
if (isMobile) {
|
||||
await expect(landingPageImage).toBeHidden();
|
||||
} else {
|
||||
await expect(landingPageImage).toBeVisible();
|
||||
}
|
||||
});
|
||||
if (isMobile) {
|
||||
await expect(landingPageImage).toBeHidden();
|
||||
} else {
|
||||
await expect(landingPageImage).toBeVisible();
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### - Group related tests
|
||||
|
||||
Group related tests together using describe blocks. This makes it easier to understand what the tests are doing and what they're testing.
|
||||
Group related tests together using describe blocks. This makes it easier to understand what the tests are doing and what they're testing.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
```ts
|
||||
describe('The campers landing page', () => {
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({isMobile}) =>
|
||||
{
|
||||
...
|
||||
});
|
||||
|
||||
test('The campers landing page figure has the correct image', async () => {
|
||||
...
|
||||
});
|
||||
```ts
|
||||
describe('The campers landing page', () => {
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({
|
||||
isMobile
|
||||
}) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
test('The campers landing page figure has the correct image', async () => {
|
||||
// ...
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## How to Run Tests
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ Follow these guidelines for setting up a development environment for freeCodeCam
|
||||
|
||||
## Choose between Gitpod or your Own Machine (local setup)
|
||||
|
||||
> [!ATTENTION] **Note:** freeCodeCamp does NOT run natively on Windows 10 or 11, you will need to use WSL2. You can follow [this guide](how-to-setup-wsl.md) to set up WSL2. You can't use Command Prompt, Git Bash or PowerShell to run freeCodeCamp natively within windows.
|
||||
> [!ATTENTION] - freeCodeCamp does not build and run natively on Windows, you will [need to use WSL2](how-to-setup-wsl.md) for a Linux-like setup on Windows. - You can't use Windows Command Prompt, Git Bash or PowerShell to build and run the codebase. - Note that if using Windows, the hardware requirements need to be more than [what we mention](how-to-setup-freecodecamp-locally?id=how-to-prepare-your-local-machine) to accommodate for WSL-based setup.
|
||||
|
||||
If you are looking to make a one-off contribution, you should use Gitpod to make changes. The Gitpod setup launches a ready-to-code environment in a few minutes in your web browser. For contributing long-term, we recommend you setup freeCodeCamp on your local machine.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# The Official freeCodeCamp Moderator Onboarding Guide
|
||||
|
||||
This guide will help new moderators get up and running with the processes and procedures followed by experienced moderators on the freeCodeCamp community forum and other official communities that we foster.
|
||||
This guide will help new moderators get up and running with the processes and procedures followed by experienced moderators on the freeCodeCamp community forum and other official communities we foster.
|
||||
|
||||
> [!NOTE] If you haven't read [The Moderator Handbook](https://contribute.freecodecamp.org/#/moderator-handbook) yet, you should start there first.
|
||||
|
||||
@@ -18,33 +18,33 @@ To get familiar with the new tools and powers, you can combine one or more of th
|
||||
|
||||
### Become Familiar with the Discourse Admin Tools
|
||||
|
||||
The freeCodeCamp forum is actually a Discourse forum and follows many of the same guidelines of other forums built on Discourse. To begin to get familiar with Discourse and the moderation role, start by reading Discourse's [new user guide](https://meta.discourse.org/t/discourse-new-user-guide/96331) and Discourse's [new moderator guide](https://meta.discourse.org/t/discourse-moderation-guide/63116).
|
||||
The freeCodeCamp forum is a Discourse forum and follows many of the same guidelines of other forums built on Discourse. To begin to get familiar with Discourse and the moderation role, start by reading Discourse's [new user guide](https://meta.discourse.org/t/discourse-new-user-guide/96331) and Discourse's [new moderator guide](https://meta.discourse.org/t/discourse-moderation-guide/63116).
|
||||
|
||||
### Shadow a Mod
|
||||
|
||||
All moderator actions can be followed by reviewing the [action logs](https://forum.freecodecamp.org/admin/logs/staff_action_logs). The actions taken by automated tools like `akistmet` or `system` can mostly be ignored until they result in a post that needs to be reviewed. Posts to be reviewed will show up in the [Review](https://forum.freecodecamp.org/review) area of the forum.
|
||||
All moderator actions can be followed by reviewing the [action logs](https://forum.freecodecamp.org/admin/logs/staff_action_logs). The actions taken by automated tools like `Akismet` or `system` can mostly be ignored until they result in a post that needs to be reviewed. Posts to be reviewed will show up in the [Review](https://forum.freecodecamp.org/review) area of the forum.
|
||||
|
||||
For the first week or so you will want to pay attention to what is getting flagged and what is being reviewed, and compare that to the actions being taken upon the flagged posts. You may see the system account flag a post because the user created it too quickly. In many cases, the moderators will unflag the post by clicking on the "Approve Post" button or mark it as "Not Spam" (depending on the flag type).
|
||||
|
||||
Commonly, spam flags can also be raised by members or moderators. Common duplicitous behavior would involve opening an account, making a post that seems harmless, then editing that post later on to add a link to an external site for the purpose of advertising it. In this case, usually the member account is fairly new and has only made this one post thus far, which indicates that the account was opened for the sole purpose of spamming the community. The decision should be made to delete the account after the first offence in this case. The same applies for accounts whose first post is deemed to be spam.
|
||||
Commonly, spam flags can also be raised by members or moderators. Common duplicitous behavior would involve opening an account, making a post that seems harmless, then editing that post later on to add a link to an external site to advertise it. In this case, the member account is usually fairly new and has only made this one post thus far, which indicates that the account was opened solely for spamming the community. The decision should be made to delete the account after the first offense in this case. The same applies to accounts whose first post is deemed to be spam.
|
||||
|
||||
You may notice moderators performing a procedure called 'split topic'. This may be a case where a moderator has split a post that was made erroneously on an existing topic into a new topic, or a moderator merged duplicate topics that a single user has created for the same question. Watching this procedure will highlight different actions and their causes.
|
||||
|
||||
Another useful feature that becomes enabled for all moderators is the ability to post a "Canned Reply" which is a pre-written response that was worked out with the mod team in order to quickly respond to some well-known and repetitive scenarios. These include:
|
||||
Another useful feature that becomes enabled for all moderators is the ability to post a "Canned Reply" which is a pre-written response that was worked out with the mod team to quickly respond to some well-known and repetitive scenarios. These include:
|
||||
|
||||
- Welcoming a new forum member who has posted code without a question -> "Welcome - remind question"
|
||||
- Reminding members not to post code solutions but to provide hints and tips instead -> "Solutions Instead of Help"
|
||||
- Responding to a situation where someone's code works for you but not for them -> "Browser Issues"
|
||||
- Encouraging members to open GitHub issues when a possible bug is found -> "Bug Report"
|
||||
|
||||
There are more, which you can read through to become familiar with their respective uses. You can also find discussion around the templates in the mod-team subforum, and you are welcome to ask questions if you aren't sure how a template should be used.
|
||||
There are more, which you can read through to become familiar with their respective uses. You can also find discussions around the templates in the mod-team subforum, and you are welcome to ask questions if you aren't sure how a template should be used.
|
||||
|
||||
### Read Mod-Team Subforum Posts
|
||||
|
||||
The Mod-Team subforum contains a number of posts from past and current moderators discussing the different requirements and/or challenges of moderating the forum.
|
||||
The Mod-Team subforum contains several posts from past and current moderators discussing the different requirements and/or challenges of moderating the forum.
|
||||
|
||||
Reading back through these posts can help to uncover some of the underlying goals and processes that concern forum moderators. Some of the threads may also shed some light on handling of spam and inappropriate content on the forum.
|
||||
Reading back through these posts can help uncover some of the underlying goals and processes that concern forum moderators. Some of the threads may also shed some light on the handling of spam and inappropriate content on the forum.
|
||||
|
||||
## Where to Ask for Help
|
||||
|
||||
To get help dealing with a situation that you are either uncomfortable with or unsure of how to handle, discuss with your fellow moderators on either the [Mod-Team Subforum](https://forum.freecodecamp.org/c/mod-team/4) or the [#mod-chat](https://discord.com/channels/692816967895220344/693157007418720277) on Discord.
|
||||
To get help dealing with a situation that you are either uncomfortable with or unsure of how to handle, discuss with your fellow moderators on either the [Mod-Team Subforum](https://forum.freecodecamp.org/c/mod-team/4) or the [#mod-chat](https://discord.com/channels/692816967895220344/693157007418720277) on Discord.
|
||||
@@ -10,7 +10,7 @@ pnpm run playwright:install-build-tools
|
||||
|
||||
Como alternativa, você pode seguir a documentação oficial referenciada abaixo:
|
||||
|
||||
Para instalar e configurar o Playwright na sua máquina, confira a [documentação](https://playwright.dev/docs/intro#installing-playwright)
|
||||
Para instalar e configurar o Playwright na sua máquina, confira a [documentação](https://playwright.dev/docs/intro#installing-playwright).
|
||||
|
||||
Para aprender a escrever testes do Playwright ou 'specs', confira a [documentação](https://playwright.dev/docs/writing-tests) oficial.
|
||||
|
||||
@@ -20,141 +20,152 @@ Para aprender a escrever testes do Playwright ou 'specs', confira a [documentaç
|
||||
|
||||
- Os arquivos de teste do Playwright têm sempre uma extensão `.spec.ts`.
|
||||
|
||||
## Melhores práticas para a escrita de testes e2e
|
||||
## Melhores práticas para a escrita de testes E2E
|
||||
|
||||
Esta seção explicará em detalhes as melhores práticas para escrever e documentar testes E2E com base na documentação do playwright e no nosso estilo de código comunitário.
|
||||
|
||||
### - Identificando um elemento do DOM
|
||||
|
||||
Sempre use o atributo `data-playwright-test-label` para identificar elementos do DOM. Esse atributo é usado para identificar elementos no DOM para testes somente com o playwright. Ele não é usado para estilização ou para qualquer outra finalidade.
|
||||
|
||||
Por exemplo:
|
||||
|
||||
```html
|
||||
<div data-playwright-test-label="landing-page-figure">
|
||||
<img src="..." alt="..." />
|
||||
</div>
|
||||
```
|
||||
|
||||
Certifique-se de usar o método getByTestId para identificar o elemento no arquivo de teste.
|
||||
|
||||
Por exemplo:
|
||||
|
||||
```ts
|
||||
const landingPageFigure = page.getByTestId('landing-page-figure');
|
||||
```
|
||||
Esta seção explicará em detalhes as melhores práticas para escrever e documentar testes E2E com base na documentação do Playwright e no nosso estilo de código comunitário.
|
||||
|
||||
### - Importações
|
||||
|
||||
Sempre comece com as importações necessárias no início do arquivo.
|
||||
Sempre comece com as importações necessárias no início do arquivo.
|
||||
|
||||
Por exemplo:
|
||||
Por exemplo:
|
||||
|
||||
```ts
|
||||
import { test, expect, type Page } from '@playwright/test';
|
||||
```
|
||||
```ts
|
||||
import { test, expect, type Page } from '@playwright/test';
|
||||
```
|
||||
|
||||
### - Identificando um elemento do DOM
|
||||
|
||||
O Playwright vem com [vários localizadores integrados](https://playwright.dev/docs/locators#quick-guide), mas recomendamos a priorização dos seguintes localizadores:
|
||||
- `getByRole` para consultar elementos semânticos de função importante e que permitam que a tecnologia assistiva perceba a página corretamente.
|
||||
- `getByText` para consultar elementos não semânticos, como `div`, `span` ou `p`.
|
||||
|
||||
Por exemplo:
|
||||
```ts
|
||||
await expect(page.getByRole('heading', { name: 'Sign up' })).toBeVisible();
|
||||
await expect(page.getByText('Hello World')).toBeVisible();
|
||||
```
|
||||
|
||||
Nos casos em que os elementos não podem ser consultados usando os localizadores mencionados acima, você pode usar o atributo `data-playwright-test-label` como último recurso. Esse atributo é usado para identificar elementos no DOM para testes somente com o playwright. Ele não é usado para estilização ou para qualquer outra finalidade.
|
||||
|
||||
Por exemplo:
|
||||
|
||||
```html
|
||||
<div data-playwright-test-label="landing-page-figure">
|
||||
<img src="..." alt="..." />
|
||||
</div>
|
||||
```
|
||||
|
||||
No arquivo de teste, você pode usar o método `getByTestId` para identificar o elemento.
|
||||
|
||||
Por exemplo:
|
||||
|
||||
```ts
|
||||
await expect(page.getByTestId('landing-page-figure')).toBeVisible();
|
||||
```
|
||||
|
||||
### - Constantes
|
||||
|
||||
Defina quaisquer elementos constantes, conjuntos de dados ou configurações usadas durante seus testes para fácil referência.
|
||||
Defina quaisquer elementos constantes, conjuntos de dados ou configurações usadas durante seus testes para fácil referência.
|
||||
|
||||
Por exemplo:
|
||||
Por exemplo:
|
||||
|
||||
```ts
|
||||
const landingPageElements = { ... };
|
||||
const superBlocks = [ ... ];
|
||||
```
|
||||
```ts
|
||||
const landingPageElements = { ... };
|
||||
const superBlocks = [ ... ];
|
||||
```
|
||||
|
||||
### - Contexto compartilhado
|
||||
|
||||
Se os testes dependem de um contexto compartilhado (como uma página da web carregada), use os hooks beforeAll e afterAll para configurar e encerrar esse contexto.
|
||||
Se os testes dependem de um contexto compartilhado (como uma página da web carregada), use os hooks beforeAll e afterAll para configurar e encerrar esse contexto.
|
||||
|
||||
Por exemplo:
|
||||
Por exemplo:
|
||||
|
||||
```ts
|
||||
let page: Page;
|
||||
```ts
|
||||
let page: Page;
|
||||
|
||||
beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
});
|
||||
beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await page.close();
|
||||
});
|
||||
```
|
||||
afterAll(async () => {
|
||||
await page.close();
|
||||
});
|
||||
```
|
||||
|
||||
### - Nomes de testes descritivos
|
||||
|
||||
Cada bloco de teste deve ter um nome claro e conciso descrevendo exatamente o que ele está testando.
|
||||
Cada bloco de teste deve ter um nome claro e conciso descrevendo exatamente o que ele está testando.
|
||||
|
||||
Por exemplo:
|
||||
Por exemplo:
|
||||
|
||||
```ts
|
||||
test('The component landing-top renders correctly', async ({ page }) => {
|
||||
...
|
||||
});
|
||||
```
|
||||
```ts
|
||||
test('The component landing-top renders correctly', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
### - Declarações legíveis
|
||||
|
||||
Cada declaração deve ser o mais legível possível. Isso torna mais fácil entender o que o teste está fazendo e o que está esperando.
|
||||
Cada declaração deve ser o mais legível possível. Isso torna mais fácil entender o que o teste está fazendo e o que está esperando.
|
||||
|
||||
Por exemplo:
|
||||
Por exemplo:
|
||||
|
||||
```ts
|
||||
await expect(landingHeading1).toHaveText('Learn to code — for free.');
|
||||
```
|
||||
```ts
|
||||
await expect(landingHeading1).toHaveText('Learn to code — for free.');
|
||||
```
|
||||
|
||||
### - Evite repetições
|
||||
|
||||
Certifique-se de que os testes não estão repetindo o mesmo código várias vezes. Se você estiver repetindo o mesmo código, considere refatorá-lo como um laço ou uma função.
|
||||
Certifique-se de que os testes não estão repetindo o mesmo código várias vezes. Se você estiver repetindo o mesmo código, considere refatorá-lo como um laço ou uma função.
|
||||
|
||||
Por exemplo:
|
||||
Por exemplo:
|
||||
|
||||
```ts
|
||||
for (const logo of await logos.all()) {
|
||||
await expect(logo).toBeVisible();
|
||||
}
|
||||
```
|
||||
```ts
|
||||
for (const logo of await logos.all()) {
|
||||
await expect(logo).toBeVisible();
|
||||
}
|
||||
```
|
||||
|
||||
### - Testes para telas de dispositivos móveis
|
||||
|
||||
Use o argumento 'isMobile' para executar testes que influenciam a lógica que varia para telas de dispositivos móveis.
|
||||
Use o argumento `'isMobile'` para executar testes que incluam lógica que varia para telas de dispositivos móveis.
|
||||
|
||||
Por exemplo:
|
||||
Por exemplo:
|
||||
|
||||
```ts
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({isMobile}) =>
|
||||
{
|
||||
const landingPageImage = page.getByTestId('landing-page-figure');
|
||||
```ts
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({
|
||||
isMobile
|
||||
}) => {
|
||||
const landingPageImage = page.getByTestId('landing-page-figure');
|
||||
|
||||
if (isMobile) {
|
||||
await expect(landingPageImage).toBeHidden();
|
||||
} else {
|
||||
await expect(landingPageImage).toBeVisible();
|
||||
}
|
||||
});
|
||||
if (isMobile) {
|
||||
await expect(landingPageImage).toBeHidden();
|
||||
} else {
|
||||
await expect(landingPageImage).toBeVisible();
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### - Agrupamento de testes relacionados
|
||||
|
||||
Agrupe testes relacionados em conjunto usando blocos "descrite". Isso torna mais fácil entender o que os testes estão fazendo e o que estão testando.
|
||||
Agrupe testes relacionados em conjunto usando blocos "descrite". Isso torna mais fácil entender o que os testes estão fazendo e o que estão testando.
|
||||
|
||||
Por exemplo:
|
||||
Por exemplo:
|
||||
|
||||
```ts
|
||||
describe('The campers landing page', () => {
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({isMobile}) =>
|
||||
{
|
||||
...
|
||||
});
|
||||
|
||||
test('The campers landing page figure has the correct image', async () => {
|
||||
...
|
||||
});
|
||||
```ts
|
||||
describe('The campers landing page', () => {
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({
|
||||
isMobile
|
||||
}) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
test('The campers landing page figure has the correct image', async () => {
|
||||
// ...
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Como executar testes
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ Siga estas orientações para criar um ambiente de desenvolvimento para o freeCo
|
||||
|
||||
## Escolha entre o Gitpod ou seu próprio computador (configuração local)
|
||||
|
||||
> [!ATTENTION] **Observação:** o freeCodeCamp não roda nativamente no Windows 10 ou 11. Você precisará usar o WSL2. Você pode seguir [este guia](how-to-setup-wsl.md) para configurar o WSL2. Você não pode usar o prompt de comando, o Git Bash ou o PowerShell para executar freeCodeCamp nativamente no Windows.
|
||||
> [!ATTENTION] - o freeCodeCamp não faz a build nem é executado nativamente no Windows. É [preciso usar o WSL2](how-to-setup-wsl.md) para ter um ambiente similar ao do Linux no Windows. - Você não pode usar o prompt de comando do Windows, o Git Bash nem PowerShell para fazer a build e executar o código. - Observe que, se estiver usando o Windows, os requisitos de hardware precisam ser mais do que [aquele que mencionamos](how-to-setup-freecodecamp-locally?id=how-to-prepare-your-local-machine) para acomodar a configuração baseada em WSL.
|
||||
|
||||
Se você deseja fazer uma contribuição única, use o Gitpod para fazer alterações. A configuração do Gitpod abre um ambiente pronto para código em poucos minutos no seu navegador. Para contribuir a longo prazo, recomendamos que você instale o freeCodeCamp em seu computador.
|
||||
|
||||
|
||||
@@ -18,11 +18,11 @@ Para se familiarizar com as novas ferramentas e poderes, você pode combinar um
|
||||
|
||||
### Familiarize-se com as ferramentas administrativas do Discourse
|
||||
|
||||
O fórum do freeCodeCamp é, na verdade, um fórum do Discourse e segue muitas das mesmas orientações de outros fóruns criados na plataforma. Para começar a se familiarizar com o Discourse e o papel de moderação, primeiro leia o [novo guia do usuário](https://meta.discourse.org/t/discourse-new-user-guide/96331) e o [novo guia do moderador](https://meta.discourse.org/t/discourse-moderation-guide/63116) do Discourse.
|
||||
O fórum do freeCodeCamp é um fórum do Discourse e segue muitas das mesmas orientações de outros fóruns criados na plataforma. Para começar a se familiarizar com o Discourse e o papel de moderação, primeiro leia o [novo guia do usuário](https://meta.discourse.org/t/discourse-new-user-guide/96331) e o [novo guia do moderador](https://meta.discourse.org/t/discourse-moderation-guide/63116) do Discourse.
|
||||
|
||||
### Acompanhe de perto um moderador
|
||||
|
||||
Todas as ações dos moderadores podem ser seguidas analisando os [logs de ação](https://forum.freecodecamp.org/admin/logs/staff_action_logs). As ações tomadas por ferramentas automatizadas como o `akistmet` ou o `system` podem ser, em grande parte, ignoradas até que resultem em uma postagem que precisa ser analisada. Publicações a serem revisadas aparecerão na área do fórum chamada [Review](https://forum.freecodecamp.org/review).
|
||||
Todas as ações dos moderadores podem ser seguidas analisando os [logs de ação](https://forum.freecodecamp.org/admin/logs/staff_action_logs). As ações tomadas por ferramentas automatizadas como o `Akismet` ou o `system` podem ser, em grande parte, ignoradas até que resultem em uma postagem que precisa ser analisada. Publicações a serem revisadas aparecerão na área do fórum chamada [Review](https://forum.freecodecamp.org/review).
|
||||
|
||||
Na primeira semana, aproximadamente, você vai querer prestar atenção ao que está sendo sinalizado e ao que está sendo analisado. Compare isso com as ações que estão sendo tomadas sobre os posts sinalizados. Você pode ver a conta do sistema sinalizar uma publicação porque o usuário a criou muito rapidamente. Em muitos casos, os moderadores desmarcarão a publicação clicando no botão "Approve post" ou a marcarão como "Not Spam" (dependendo do tipo de sinalização).
|
||||
|
||||
@@ -47,4 +47,4 @@ Ler essas publicações pode ajudar a descobrir algumas das metas e processos su
|
||||
|
||||
## Onde pedir ajuda
|
||||
|
||||
Para obter ajuda para lidar com uma situação com a qual você está desconfortável ou incerto sobre como lidar, discuta com seus colegas moderadores no [sub-fórum Mod-Team](https://forum.freecodecamp.org/c/mod-team/4) ou no [#mod-chat](https://discord.com/channels/692816967895220344/693157007418720277) no Discord.
|
||||
Para obter ajuda para lidar com uma situação com a qual você está desconfortável ou incerto sobre como lidar, discuta com seus colegas moderadores no [sub-fórum Mod-Team](https://forum.freecodecamp.org/c/mod-team/4) ou no [#mod-chat](https://discord.com/channels/692816967895220344/693157007418720277) no Discord.
|
||||
@@ -10,7 +10,7 @@ pnpm run playwright:install-build-tools
|
||||
|
||||
Або ж ви можете дотримуватись офіційної документації:
|
||||
|
||||
Щоб встановити та налаштувати Playwright на своїй машині, див. [документацію](https://playwright.dev/docs/intro#installing-playwright)
|
||||
Щоб встановити та налаштувати Playwright на своїй машині, див. [документацію](https://playwright.dev/docs/intro#installing-playwright).
|
||||
|
||||
Щоб дізнатися, як писати тести Playwright, або «специфікації», зверніться до офіційної [документації Playwright](https://playwright.dev/docs/writing-tests).
|
||||
|
||||
@@ -20,141 +20,152 @@ pnpm run playwright:install-build-tools
|
||||
|
||||
- Файли тестів Playwright завжди мають розширення `.spec.ts`.
|
||||
|
||||
## Найкращі практики для написання тестів e2e
|
||||
## Найкращі практики для написання тестів E2E
|
||||
|
||||
Цей розділ детально пояснить найкращі практики написання та документування тестів E2E на основі документації Playwright та кодового стилю нашої спільноти.
|
||||
|
||||
### - Визначення елемента DOM
|
||||
|
||||
Завжди використовуйте атрибут `data-playwright-test-label`, щоб ідентифікувати елементи DOM. Цей атрибут використовують, щоб ідентифікувати елементи в DOM лише для тестування Playwright. Його не використовують для стилізації або будь-чого іншого.
|
||||
|
||||
Наприклад:
|
||||
|
||||
```html
|
||||
<div data-playwright-test-label="landing-page-figure">
|
||||
<img src="..." alt="..." />
|
||||
</div>
|
||||
```
|
||||
|
||||
Переконайтесь, що використовуєте метод getByTestId, щоб ідентифікувати елементи в тестовому файлі.
|
||||
|
||||
Наприклад:
|
||||
|
||||
```ts
|
||||
const landingPageFigure = page.getByTestId('landing-page-figure');
|
||||
```
|
||||
|
||||
### - Імпорт
|
||||
|
||||
Завжди починайте необхідні імпорти на початку файлу.
|
||||
Завжди починайте необхідні імпорти на початку файлу.
|
||||
|
||||
Наприклад:
|
||||
Наприклад:
|
||||
|
||||
```ts
|
||||
import { test, expect, type Page } from '@playwright/test';
|
||||
```
|
||||
```ts
|
||||
import { test, expect, type Page } from '@playwright/test';
|
||||
```
|
||||
|
||||
### - Визначення елемента DOM
|
||||
|
||||
Playwright поставляється з [декількома вбудованими локаторами](https://playwright.dev/docs/locators#quick-guide), але ми рекомендуємо взяти до уваги наступні:
|
||||
- `getByRole` для запиту семантичних елементів, роль яких важлива та дозволяє технічним засобам реабілітації правильно сприймати сторінку.
|
||||
- `getByText` для запитів не семантичних елементів, таких як `div`, `span` чи `p`.
|
||||
|
||||
Наприклад:
|
||||
```ts
|
||||
await expect(page.getByRole('heading', { name: 'Sign up' })).toBeVisible();
|
||||
await expect(page.getByText('Hello World')).toBeVisible();
|
||||
```
|
||||
|
||||
У крайніх випадках, коли запит елементів не можна здійснити за допомогою локаторів вище, використайте атрибут `data-playwright-test-label`. Цей атрибут використовують, щоб ідентифікувати елементи в DOM лише для тестування Playwright. Його не використовують для стилізації або будь-чого іншого.
|
||||
|
||||
Наприклад:
|
||||
|
||||
```html
|
||||
<div data-playwright-test-label="landing-page-figure">
|
||||
<img src="..." alt="..." />
|
||||
</div>
|
||||
```
|
||||
|
||||
У файлі тестів можна використати метод `getByTestId`, щоб ідентифікувати елемент.
|
||||
|
||||
Наприклад:
|
||||
|
||||
```ts
|
||||
await expect(page.getByTestId('landing-page-figure')).toBeVisible();
|
||||
```
|
||||
|
||||
### - Константи
|
||||
|
||||
Визначте будь-які константні елементи, набори даних чи конфігурації, використані в тестах, для спрощеного посилання.
|
||||
Визначте будь-які константні елементи, набори даних чи конфігурації, використані в тестах, для спрощеного посилання.
|
||||
|
||||
Наприклад:
|
||||
Наприклад:
|
||||
|
||||
```ts
|
||||
const landingPageElements = { ... };
|
||||
const superBlocks = [ ... ];
|
||||
```
|
||||
```ts
|
||||
const landingPageElements = { ... };
|
||||
const superBlocks = [ ... ];
|
||||
```
|
||||
|
||||
### - Спільний контекст
|
||||
|
||||
Якщо тести залежать від спільного контексту (наприклад, завантаженої сторінки), використайте хуки beforeAll та afterAll, щоб налаштувати та розбити контекст.
|
||||
Якщо тести залежать від спільного контексту (наприклад, завантаженої сторінки), використайте хуки beforeAll та afterAll, щоб налаштувати та розбити контекст.
|
||||
|
||||
Наприклад:
|
||||
Наприклад:
|
||||
|
||||
```ts
|
||||
let page: Page;
|
||||
```ts
|
||||
let page: Page;
|
||||
|
||||
beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
});
|
||||
beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await page.close();
|
||||
});
|
||||
```
|
||||
afterAll(async () => {
|
||||
await page.close();
|
||||
});
|
||||
```
|
||||
|
||||
### - Описові назви тестів
|
||||
|
||||
Кожен тестовий блок повинен мати чітку і лаконічну назву, описуючи саме те, що перевіряє.
|
||||
Кожен тестовий блок повинен мати чітку і лаконічну назву, описуючи саме те, що перевіряє.
|
||||
|
||||
Наприклад:
|
||||
Наприклад:
|
||||
|
||||
```ts
|
||||
test('The component landing-top renders correctly', async ({ page }) => {
|
||||
...
|
||||
});
|
||||
```
|
||||
```ts
|
||||
test('The component landing-top renders correctly', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
### - Людиносприйнятні твердження
|
||||
|
||||
Кожне твердження має бути максимально розбірливим для людини. Таким чином простіше зрозуміти, що робить тест та чого очікувати.
|
||||
Кожне твердження має бути максимально розбірливим для людини. Таким чином простіше зрозуміти, що робить тест та чого очікувати.
|
||||
|
||||
Наприклад:
|
||||
Наприклад:
|
||||
|
||||
```ts
|
||||
await expect(landingHeading1).toHaveText('Learn to code — for free.');
|
||||
```
|
||||
```ts
|
||||
await expect(landingHeading1).toHaveText('Learn to code — for free.');
|
||||
```
|
||||
|
||||
### - Дотримуйтесь принципу DRY
|
||||
|
||||
Переконайтеся, що тести не повторюють однаковий код знову і знову. Якщо однаковий код повторюється, реорганізуйте його як цикл або функцію.
|
||||
Переконайтеся, що тести не повторюють однаковий код знову і знову. Якщо однаковий код повторюється, реорганізуйте його як цикл або функцію.
|
||||
|
||||
Наприклад:
|
||||
Наприклад:
|
||||
|
||||
```ts
|
||||
for (const logo of await logos.all()) {
|
||||
await expect(logo).toBeVisible();
|
||||
}
|
||||
```
|
||||
```ts
|
||||
for (const logo of await logos.all()) {
|
||||
await expect(logo).toBeVisible();
|
||||
}
|
||||
```
|
||||
|
||||
### - Тести для мобільних екранів
|
||||
|
||||
Використайте аргумент isMobile, щоб запустити тести, які містять логіку, що змінюється для мобільних екранів.
|
||||
Використайте аргумент `isMobile`, щоб запустити тести, які містять логіку, що змінюється для мобільних екранів.
|
||||
|
||||
Наприклад:
|
||||
Наприклад:
|
||||
|
||||
```ts
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({isMobile}) =>
|
||||
{
|
||||
const landingPageImage = page.getByTestId('landing-page-figure');
|
||||
```ts
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({
|
||||
isMobile
|
||||
}) => {
|
||||
const landingPageImage = page.getByTestId('landing-page-figure');
|
||||
|
||||
if (isMobile) {
|
||||
await expect(landingPageImage).toBeHidden();
|
||||
} else {
|
||||
await expect(landingPageImage).toBeVisible();
|
||||
}
|
||||
});
|
||||
if (isMobile) {
|
||||
await expect(landingPageImage).toBeHidden();
|
||||
} else {
|
||||
await expect(landingPageImage).toBeVisible();
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### - Групові тести
|
||||
|
||||
Згрупуйте пов’язані тести, використовуючи описові блоки. Таким чином простіше зрозуміти, що роблять тести та чого очікувати.
|
||||
Згрупуйте пов’язані тести, використовуючи описові блоки. Таким чином простіше зрозуміти, що роблять тести та чого очікувати.
|
||||
|
||||
Наприклад:
|
||||
Наприклад:
|
||||
|
||||
```ts
|
||||
describe('The campers landing page', () => {
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({isMobile}) =>
|
||||
{
|
||||
...
|
||||
});
|
||||
|
||||
test('The campers landing page figure has the correct image', async () => {
|
||||
...
|
||||
});
|
||||
```ts
|
||||
describe('The campers landing page', () => {
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({
|
||||
isMobile
|
||||
}) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
test('The campers landing page figure has the correct image', async () => {
|
||||
// ...
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Як проводити тести
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Оберіть між Gitpod чи власною машиною (локальне налаштування)
|
||||
|
||||
> [!ATTENTION] **Примітка:** freeCodeCamp НЕ працює належним чином на Windows 10 чи 11, вам потрібно використовувати WSL2. Використовуйте [цей посібник](how-to-setup-wsl.md), щоб налаштувати WSL2. Ви не можете використовувати командний рядок, Git Bash або PowerShell для запуску freeCodeCamp на Windows.
|
||||
> [!ATTENTION] - freeCodeCamp не збирається та не запускається на Windows, тому вам [потрібно використати WSL2](how-to-setup-wsl.md) для налаштування типу Linux на Windows. - Ви не можете використовувати командний рядок Windows, Git Bash або PowerShell, щоб створити та запустити кодову базу. - Зверніть увагу, що вимоги до комп’ютерного устаткування при використанні Windows відрізнятимуться [від вказаних](how-to-setup-freecodecamp-locally?id=how-to-prepare-your-local-machine), щоб відповідати налаштуванню на основі WSL.
|
||||
|
||||
Якщо ви бажаєте зробити одноразовий внесок, використовуйте Gitpod. Налаштування Gitpod надає готове середовище у вашому браузері за декілька хвилин. Для тривалих внесків ми рекомендуємо налаштувати freeCodeCamp на локальній машині.
|
||||
|
||||
|
||||
@@ -18,11 +18,11 @@
|
||||
|
||||
### Ознайомтесь з інструментами адміністратора на Discourse
|
||||
|
||||
Насправді форум freeCodeCamp є форумом Discourse, тому ми дотримуємось правил інших форумів, створених на Discourse. Щоб ознайомитись з Discourse та модераторством, прочитайте [довідник нового користувача Discourse](https://meta.discourse.org/t/discourse-new-user-guide/96331) та [довідник нового модератора Discourse](https://meta.discourse.org/t/discourse-moderation-guide/63116).
|
||||
Форум freeCodeCamp є форумом Discourse, тому ми дотримуємось правил інших форумів, створених на Discourse. Щоб ознайомитись з Discourse та модераторством, прочитайте [довідник нового користувача Discourse](https://meta.discourse.org/t/discourse-new-user-guide/96331) та [довідник нового модератора Discourse](https://meta.discourse.org/t/discourse-moderation-guide/63116).
|
||||
|
||||
### Стежте за іншими модераторами
|
||||
|
||||
Усі дії модераторів можна переглянути у [журналі дій](https://forum.freecodecamp.org/admin/logs/staff_action_logs). Дії автоматичних інструментів (наприклад, `akistmet` чи `system`) можна ігнорувати, якщо вони не стосуються допису, який потрібно переглянути. Дописи, які потрібно переглянути, розміщені на форумі у розділі [Review](https://forum.freecodecamp.org/review).
|
||||
Усі дії модераторів можна переглянути у [журналі дій](https://forum.freecodecamp.org/admin/logs/staff_action_logs). Дії автоматичних інструментів (наприклад, `Akismet` чи `system`) можна ігнорувати, якщо вони не стосуються допису, який потрібно переглянути. Дописи, які потрібно переглянути, розміщені на форумі у розділі [Review](https://forum.freecodecamp.org/review).
|
||||
|
||||
Протягом першого тижня звертайте увагу на те, які дописи позначаються прапорцем та розглядаються, а також на застосовані до них дії. Ви можете побачити, що системний обліковий запис позначає публікацію, оскільки користувач створив її надто швидко. У багатьох випадках модератори заберуть прапорець, натиснувши кнопку «Approve Post» або позначивши допис як «Not Spam» (залежно від типу прапорця).
|
||||
|
||||
@@ -47,4 +47,4 @@
|
||||
|
||||
## Де просити про допомогу
|
||||
|
||||
Щоб отримати допомогу щодо незручної чи незрозумілої ситуації, порадьтесь з іншими модераторами на [підфорумі Mod-Team](https://forum.freecodecamp.org/c/mod-team/4) або в [#mod-chat](https://discord.com/channels/692816967895220344/693157007418720277) на дискорді.
|
||||
Щоб отримати допомогу щодо незручної чи незрозумілої ситуації, порадьтесь з іншими модераторами на [підфорумі Mod-Team](https://forum.freecodecamp.org/c/mod-team/4) або в [#mod-chat](https://discord.com/channels/692816967895220344/693157007418720277) на дискорді.
|
||||
Reference in New Issue
Block a user