Commit 968ae2ae authored by Amy Qualls's avatar Amy Qualls Committed by Craig Norris

Fix future tense and add spelling exception

Fixes future tense on two documents in the development directory,
and adds variations on 'transpile' to the spelling exceptions
dictionary. A quick web search demonstrates it's a real term.
parent 523df990
...@@ -495,6 +495,9 @@ toolchain ...@@ -495,6 +495,9 @@ toolchain
toolchains toolchains
tooltip tooltip
tooltips tooltips
transpile
transpiles
transpiling
Trello Trello
triaging triaging
Twilio Twilio
......
...@@ -42,8 +42,8 @@ without needing to explicitly list all their queue names. If, for example, all ...@@ -42,8 +42,8 @@ without needing to explicitly list all their queue names. If, for example, all
workers that are managed by `sidekiq-cron` use the `cronjob` queue namespace, we workers that are managed by `sidekiq-cron` use the `cronjob` queue namespace, we
can spin up a Sidekiq process specifically for these kinds of scheduled jobs. can spin up a Sidekiq process specifically for these kinds of scheduled jobs.
If a new worker using the `cronjob` namespace is added later on, the Sidekiq If a new worker using the `cronjob` namespace is added later on, the Sidekiq
process will automatically pick up jobs for that worker too (after having been process also picks up jobs for that worker (after having been restarted),
restarted), without the need to change any configuration. without the need to change any configuration.
A queue namespace can be set using the `queue_namespace` DSL class method: A queue namespace can be set using the `queue_namespace` DSL class method:
...@@ -57,19 +57,19 @@ class SomeScheduledTaskWorker ...@@ -57,19 +57,19 @@ class SomeScheduledTaskWorker
end end
``` ```
Behind the scenes, this will set `SomeScheduledTaskWorker.queue` to Behind the scenes, this sets `SomeScheduledTaskWorker.queue` to
`cronjob:some_scheduled_task`. Commonly used namespaces will have their own `cronjob:some_scheduled_task`. Commonly used namespaces have their own
concern module that can easily be included into the worker class, and that may concern module that can easily be included into the worker class, and that may
set other Sidekiq options besides the queue namespace. `CronjobQueue`, for set other Sidekiq options besides the queue namespace. `CronjobQueue`, for
example, sets the namespace, but also disables retries. example, sets the namespace, but also disables retries.
`bundle exec sidekiq` is namespace-aware, and will automatically listen on all `bundle exec sidekiq` is namespace-aware, and listens on all
queues in a namespace (technically: all queues prefixed with the namespace name) queues in a namespace (technically: all queues prefixed with the namespace name)
when a namespace is provided instead of a simple queue name in the `--queue` when a namespace is provided instead of a simple queue name in the `--queue`
(`-q`) option, or in the `:queues:` section in `config/sidekiq_queues.yml`. (`-q`) option, or in the `:queues:` section in `config/sidekiq_queues.yml`.
Note that adding a worker to an existing namespace should be done with care, as Note that adding a worker to an existing namespace should be done with care, as
the extra jobs will take resources away from jobs from workers that were already the extra jobs take resources away from jobs from workers that were already
there, if the resources available to the Sidekiq process handling the namespace there, if the resources available to the Sidekiq process handling the namespace
are not adjusted appropriately. are not adjusted appropriately.
...@@ -121,9 +121,8 @@ As a general rule, a worker can be considered idempotent if: ...@@ -121,9 +121,8 @@ As a general rule, a worker can be considered idempotent if:
A good example of that would be a cache expiration worker. A good example of that would be a cache expiration worker.
A job scheduled for an idempotent worker will automatically be A job scheduled for an idempotent worker is [deduplicated](#deduplication) when
[deduplicated](#deduplication) when an unstarted job with the same an unstarted job with the same arguments is already in the queue.
arguments is already in the queue.
### Ensuring a worker is idempotent ### Ensuring a worker is idempotent
...@@ -160,9 +159,8 @@ end ...@@ -160,9 +159,8 @@ end
It's encouraged to only have the `idempotent!` call in the top-most worker class, even if It's encouraged to only have the `idempotent!` call in the top-most worker class, even if
the `perform` method is defined in another class or module. the `perform` method is defined in another class or module.
If the worker class is not marked as idempotent, a cop will fail. If the worker class isn't marked as idempotent, a cop fails. Consider skipping
Consider skipping the cop if you're not confident your job can safely the cop if you're not confident your job can safely run multiple times.
run multiple times.
### Deduplication ### Deduplication
...@@ -230,7 +228,7 @@ end ...@@ -230,7 +228,7 @@ end
#### Scheduling jobs in the future #### Scheduling jobs in the future
GitLab doesn't skip jobs scheduled in the future, as we assume that GitLab doesn't skip jobs scheduled in the future, as we assume that
the state will have changed by the time the job is scheduled to the state has changed by the time the job is scheduled to
execute. Deduplication of jobs scheduled in the feature is possible execute. Deduplication of jobs scheduled in the feature is possible
for both `until_executed` and `until_executing` strategies. for both `until_executed` and `until_executing` strategies.
...@@ -258,10 +256,10 @@ by using the `LimitedCapacity::Worker` concern. ...@@ -258,10 +256,10 @@ by using the `LimitedCapacity::Worker` concern.
The worker must implement three methods: The worker must implement three methods:
- `perform_work` - the concern implements the usual `perform` method and calls - `perform_work`: The concern implements the usual `perform` method and calls
`perform_work` if there is any capacity available. `perform_work` if there's any available capacity.
- `remaining_work_count` - number of jobs that will have work to perform. - `remaining_work_count`: Number of jobs that have work to perform.
- `max_running_jobs` - maximum number of jobs allowed to run concurrently. - `max_running_jobs`: Maximum number of jobs allowed to run concurrently.
```ruby ```ruby
class MyDummyWorker class MyDummyWorker
...@@ -283,7 +281,7 @@ end ...@@ -283,7 +281,7 @@ end
Additional to the regular worker, a cron worker must be defined as well to Additional to the regular worker, a cron worker must be defined as well to
backfill the queue with jobs. the arguments passed to `perform_with_capacity` backfill the queue with jobs. the arguments passed to `perform_with_capacity`
will be passed along to the `perform_work` method. are passed to the `perform_work` method.
```ruby ```ruby
class ScheduleMyDummyCronWorker class ScheduleMyDummyCronWorker
...@@ -298,10 +296,10 @@ end ...@@ -298,10 +296,10 @@ end
### How many jobs are running? ### How many jobs are running?
It will be running `max_running_jobs` at almost all times. It runs `max_running_jobs` at almost all times.
The cron worker will check the remaining capacity on each execution and it The cron worker checks the remaining capacity on each execution and it
will schedule at most `max_running_jobs` jobs. Those jobs on completion will schedules at most `max_running_jobs` jobs. Those jobs on completion
re-enqueue themselves immediately, but not on failure. The cron worker is in re-enqueue themselves immediately, but not on failure. The cron worker is in
charge of replacing those failed jobs. charge of replacing those failed jobs.
...@@ -309,11 +307,11 @@ charge of replacing those failed jobs. ...@@ -309,11 +307,11 @@ charge of replacing those failed jobs.
This concern disables Sidekiq retries, logs the errors, and sends the job to the This concern disables Sidekiq retries, logs the errors, and sends the job to the
dead queue. This is done to have only one source that produces jobs and because dead queue. This is done to have only one source that produces jobs and because
the retry would occupy a slot with a job that will be performed in the distant future. the retry would occupy a slot with a job to perform in the distant future.
We let the cron worker enqueue new jobs, this could be seen as our retry and We let the cron worker enqueue new jobs, this could be seen as our retry and
back off mechanism because the job might fail again if executed immediately. back off mechanism because the job might fail again if executed immediately.
This means that for every failed job, we will be running at a lower capacity This means that for every failed job, we run at a lower capacity
until the cron worker fills the capacity again. If it is important for the until the cron worker fills the capacity again. If it is important for the
worker not to get a backlog, exceptions must be handled in `#perform_work` and worker not to get a backlog, exceptions must be handled in `#perform_work` and
the job should not raise. the job should not raise.
...@@ -396,7 +394,7 @@ each of which represents a particular type of workload. ...@@ -396,7 +394,7 @@ each of which represents a particular type of workload.
When changing a queue's urgency, or adding a new queue, we need to take When changing a queue's urgency, or adding a new queue, we need to take
into account the expected workload on the new shard. Note that, if we're into account the expected workload on the new shard. Note that, if we're
changing an existing queue, there is also an effect on the old shard, changing an existing queue, there is also an effect on the old shard,
but that will always be a reduction in work. but that always reduces work.
To do this, we want to calculate the expected increase in total execution time To do this, we want to calculate the expected increase in total execution time
and RPS (throughput) for the new shard. We can get these values from: and RPS (throughput) for the new shard. We can get these values from:
...@@ -409,7 +407,7 @@ and RPS (throughput) for the new shard. We can get these values from: ...@@ -409,7 +407,7 @@ and RPS (throughput) for the new shard. We can get these values from:
- The [Shard Detail - The [Shard Detail
dashboard](https://dashboards.gitlab.net/d/sidekiq-shard-detail/sidekiq-shard-detail) dashboard](https://dashboards.gitlab.net/d/sidekiq-shard-detail/sidekiq-shard-detail)
has Total Execution Time and Throughput (RPS). The Shard Utilization has Total Execution Time and Throughput (RPS). The Shard Utilization
panel will show if there is currently any excess capacity for this panel displays if there is currently any excess capacity for this
shard. shard.
We can then calculate the RPS * average runtime (estimated for new jobs) We can then calculate the RPS * average runtime (estimated for new jobs)
...@@ -434,7 +432,7 @@ Most background jobs in the GitLab application communicate with other GitLab ...@@ -434,7 +432,7 @@ Most background jobs in the GitLab application communicate with other GitLab
services. For example, PostgreSQL, Redis, Gitaly, and Object Storage. These are considered services. For example, PostgreSQL, Redis, Gitaly, and Object Storage. These are considered
to be "internal" dependencies for a job. to be "internal" dependencies for a job.
However, some jobs will be dependent on external services in order to complete However, some jobs are dependent on external services in order to complete
successfully. Some examples include: successfully. Some examples include:
1. Jobs which call web-hooks configured by a user. 1. Jobs which call web-hooks configured by a user.
...@@ -485,8 +483,8 @@ hosting the process has. For IO bound workers, this is not a problem, since most ...@@ -485,8 +483,8 @@ hosting the process has. For IO bound workers, this is not a problem, since most
of the threads are blocked in underlying libraries (which are outside of the of the threads are blocked in underlying libraries (which are outside of the
GIL). GIL).
If many threads are attempting to run Ruby code simultaneously, this will lead If many threads are attempting to run Ruby code simultaneously, this leads
to contention on the GIL which will have the affect of slowing down all to contention on the GIL which has the effect of slowing down all
processes. processes.
In high-traffic environments, knowing that a worker is CPU-bound allows us to In high-traffic environments, knowing that a worker is CPU-bound allows us to
...@@ -497,9 +495,9 @@ Likewise, if a worker uses large amounts of memory, we can run these on a ...@@ -497,9 +495,9 @@ Likewise, if a worker uses large amounts of memory, we can run these on a
bespoke low concurrency, high memory fleet. bespoke low concurrency, high memory fleet.
Note that memory-bound workers create heavy GC workloads, with pauses of Note that memory-bound workers create heavy GC workloads, with pauses of
10-50ms. This will have an impact on the latency requirements for the 10-50ms. This has an impact on the latency requirements for the
worker. For this reason, `memory` bound, `urgency :high` jobs are not worker. For this reason, `memory` bound, `urgency :high` jobs are not
permitted and will fail CI. In general, `memory` bound workers are permitted and fail CI. In general, `memory` bound workers are
discouraged, and alternative approaches to processing the work should be discouraged, and alternative approaches to processing the work should be
considered. considered.
...@@ -563,12 +561,11 @@ default weight, which is 1. ...@@ -563,12 +561,11 @@ default weight, which is 1.
To have some more information about workers in the logs, we add To have some more information about workers in the logs, we add
[metadata to the jobs in the form of an [metadata to the jobs in the form of an
`ApplicationContext`](logging.md#logging-context-metadata-through-rails-or-grape-requests). `ApplicationContext`](logging.md#logging-context-metadata-through-rails-or-grape-requests).
In most cases, when scheduling a job from a request, this context will In most cases, when scheduling a job from a request, this context is already
already be deducted from the request and added to the scheduled deducted from the request and added to the scheduled job.
job.
When a job runs, the context that was active when it was scheduled When a job runs, the context that was active when it was scheduled
will be restored. This causes the context to be propagated to any job is restored. This causes the context to be propagated to any job
scheduled from within the running job. scheduled from within the running job.
All this means that in most cases, to add context to jobs, we don't All this means that in most cases, to add context to jobs, we don't
...@@ -583,7 +580,7 @@ As with most our cops, there are perfectly valid reasons for disabling ...@@ -583,7 +580,7 @@ As with most our cops, there are perfectly valid reasons for disabling
them. In this case it could be that the context from the request is them. In this case it could be that the context from the request is
correct. Or maybe you've specified a context already in a way that correct. Or maybe you've specified a context already in a way that
isn't picked up by the cops. In any case, leave a code comment isn't picked up by the cops. In any case, leave a code comment
pointing to which context will be used when disabling the cops. pointing to which context to use when disabling the cops.
When you do provide objects to the context, make sure that the When you do provide objects to the context, make sure that the
route for namespaces and projects is pre-loaded. This can be done by using route for namespaces and projects is pre-loaded. This can be done by using
...@@ -679,7 +676,7 @@ blocks: ...@@ -679,7 +676,7 @@ blocks:
## Arguments logging ## Arguments logging
As of GitLab 13.6, Sidekiq job arguments will be logged by default, unless [`SIDEKIQ_LOG_ARGUMENTS`](../administration/troubleshooting/sidekiq.md#log-arguments-to-sidekiq-jobs) As of GitLab 13.6, Sidekiq job arguments are logged by default, unless [`SIDEKIQ_LOG_ARGUMENTS`](../administration/troubleshooting/sidekiq.md#log-arguments-to-sidekiq-jobs)
is disabled. is disabled.
By default, the only arguments logged are numeric arguments, because By default, the only arguments logged are numeric arguments, because
...@@ -800,7 +797,7 @@ This approach requires multiple releases. ...@@ -800,7 +797,7 @@ This approach requires multiple releases.
##### Parameter hash ##### Parameter hash
This approach will not require multiple releases if an existing worker already This approach doesn't require multiple releases if an existing worker already
uses a parameter hash. uses a parameter hash.
1. Use a parameter hash in the worker to allow future flexibility. 1. Use a parameter hash in the worker to allow future flexibility.
......
...@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w ...@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Frontend testing standards and style guidelines # Frontend testing standards and style guidelines
There are two types of test suites you'll encounter while developing frontend code There are two types of test suites encountered while developing frontend code
at GitLab. We use Karma with Jasmine and Jest for JavaScript unit and integration testing, at GitLab. We use Karma with Jasmine and Jest for JavaScript unit and integration testing,
and RSpec feature tests with Capybara for e2e (end-to-end) integration testing. and RSpec feature tests with Capybara for e2e (end-to-end) integration testing.
...@@ -30,9 +30,9 @@ Jest tests can be found in `/spec/frontend` and `/ee/spec/frontend` in EE. ...@@ -30,9 +30,9 @@ Jest tests can be found in `/spec/frontend` and `/ee/spec/frontend` in EE.
## Karma test suite ## Karma test suite
While GitLab has switched over to [Jest](https://jestjs.io) you'll still find Karma tests in our While GitLab has switched over to [Jest](https://jestjs.io), Karma tests still exist in our
application because some of our specs require a browser and can't be easiliy migrated to Jest. application because some of our specs require a browser and can't be easiliy migrated to Jest.
Those specs will eventually drop Karma in favor of either Jest or RSpec. You can track this migration Those specs intend to eventually drop Karma in favor of either Jest or RSpec. You can track this migration
in the [related epic](https://gitlab.com/groups/gitlab-org/-/epics/4900). in the [related epic](https://gitlab.com/groups/gitlab-org/-/epics/4900).
[Karma](http://karma-runner.github.io/) is a test runner which uses [Karma](http://karma-runner.github.io/) is a test runner which uses
...@@ -45,7 +45,7 @@ Karma tests live in `spec/javascripts/` and `/ee/spec/javascripts` in EE. ...@@ -45,7 +45,7 @@ Karma tests live in `spec/javascripts/` and `/ee/spec/javascripts` in EE.
might have a corresponding `spec/javascripts/behaviors/autosize_spec.js` file. might have a corresponding `spec/javascripts/behaviors/autosize_spec.js` file.
Keep in mind that in a CI environment, these tests are run in a headless Keep in mind that in a CI environment, these tests are run in a headless
browser and you will not have access to certain APIs, such as browser and you don't have access to certain APIs, such as
[`Notification`](https://developer.mozilla.org/en-US/docs/Web/API/notification), [`Notification`](https://developer.mozilla.org/en-US/docs/Web/API/notification),
which have to be stubbed. which have to be stubbed.
...@@ -60,7 +60,7 @@ which have to be stubbed. ...@@ -60,7 +60,7 @@ which have to be stubbed.
- No [context object](https://jasmine.github.io/tutorials/your_first_suite#section-The_%3Ccode%3Ethis%3C/code%3E_keyword) is passed to tests in Jest. - No [context object](https://jasmine.github.io/tutorials/your_first_suite#section-The_%3Ccode%3Ethis%3C/code%3E_keyword) is passed to tests in Jest.
This means sharing `this.something` between `beforeEach()` and `it()` for example does not work. This means sharing `this.something` between `beforeEach()` and `it()` for example does not work.
Instead you should declare shared variables in the context that they are needed (via `const` / `let`). Instead you should declare shared variables in the context that they are needed (via `const` / `let`).
- The following will cause tests to fail in Jest: - The following cause tests to fail in Jest:
- Unmocked requests. - Unmocked requests.
- Unhandled Promise rejections. - Unhandled Promise rejections.
- Calls to `console.warn`, including warnings from libraries like Vue. - Calls to `console.warn`, including warnings from libraries like Vue.
...@@ -78,14 +78,14 @@ See also the issue for [support running Jest tests in browsers](https://gitlab.c ...@@ -78,14 +78,14 @@ See also the issue for [support running Jest tests in browsers](https://gitlab.c
### Debugging Jest tests ### Debugging Jest tests
Running `yarn jest-debug` will run Jest in debug mode, allowing you to debug/inspect as described in the [Jest docs](https://jestjs.io/docs/en/troubleshooting#tests-are-failing-and-you-don-t-know-why). Running `yarn jest-debug` runs Jest in debug mode, allowing you to debug/inspect as described in the [Jest docs](https://jestjs.io/docs/en/troubleshooting#tests-are-failing-and-you-don-t-know-why).
### Timeout error ### Timeout error
The default timeout for Jest is set in The default timeout for Jest is set in
[`/spec/frontend/test_setup.js`](https://gitlab.com/gitlab-org/gitlab/blob/master/spec/frontend/test_setup.js). [`/spec/frontend/test_setup.js`](https://gitlab.com/gitlab-org/gitlab/blob/master/spec/frontend/test_setup.js).
If your test exceeds that time, it will fail. If your test exceeds that time, it fails.
If you cannot improve the performance of the tests, you can increase the timeout If you cannot improve the performance of the tests, you can increase the timeout
for a specific test using for a specific test using
...@@ -185,7 +185,7 @@ For example, it's better to use the generated markup to trigger a button click a ...@@ -185,7 +185,7 @@ For example, it's better to use the generated markup to trigger a button click a
## Common practices ## Common practices
Following you'll find some general common practices you will find as part of our test suite. Should you stumble over something not following this guide, ideally fix it right away. 🎉 These some general common practices included as part of our test suite. Should you stumble over something not following this guide, ideally fix it right away. 🎉
### How to query DOM elements ### How to query DOM elements
...@@ -224,7 +224,7 @@ it('exists', () => { ...@@ -224,7 +224,7 @@ it('exists', () => {
wrapper.find('[data-testid="my-foo-id"]'); wrapper.find('[data-testid="my-foo-id"]');
wrapper.findByTestId('my-foo-id'); // with the extendedWrapper utility – check below wrapper.findByTestId('my-foo-id'); // with the extendedWrapper utility – check below
wrapper.find({ ref: 'foo'}); wrapper.find({ ref: 'foo'});
// Bad // Bad
wrapper.find('.js-foo'); wrapper.find('.js-foo');
wrapper.find('.btn-primary'); wrapper.find('.btn-primary');
...@@ -351,7 +351,7 @@ it('tests a promise rejection', () => { ...@@ -351,7 +351,7 @@ it('tests a promise rejection', () => {
### Manipulating Time ### Manipulating Time
Sometimes we have to test time-sensitive code. For example, recurring events that run every X amount of seconds or similar. Here you'll find some strategies to deal with that: Sometimes we have to test time-sensitive code. For example, recurring events that run every X amount of seconds or similar. Here are some strategies to deal with that:
#### `setTimeout()` / `setInterval()` in application #### `setTimeout()` / `setInterval()` in application
...@@ -397,7 +397,7 @@ it('does something', () => { ...@@ -397,7 +397,7 @@ it('does something', () => {
Sometimes a test needs to wait for something to happen in the application before it continues. Sometimes a test needs to wait for something to happen in the application before it continues.
Avoid using [`setTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout) Avoid using [`setTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout)
because it makes the reason for waiting unclear and if used within Karma with a time larger than zero it will slow down our test suite. because it makes the reason for waiting unclear and if used within Karma with a time larger than zero it slows down our test suite.
Instead use one of the following approaches. Instead use one of the following approaches.
#### Promises and Ajax calls #### Promises and Ajax calls
...@@ -561,7 +561,7 @@ Jest has [`toBe`](https://jestjs.io/docs/en/expect#tobevalue) and ...@@ -561,7 +561,7 @@ Jest has [`toBe`](https://jestjs.io/docs/en/expect#tobevalue) and
As [`toBe`](https://jestjs.io/docs/en/expect#tobevalue) uses As [`toBe`](https://jestjs.io/docs/en/expect#tobevalue) uses
[`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is)
to compare values, it's faster (by default) than using `toEqual`. to compare values, it's faster (by default) than using `toEqual`.
While the latter will eventually fallback to leverage [`Object.is`](https://github.com/facebook/jest/blob/master/packages/expect/src/jasmineUtils.ts#L91), While the latter eventually falls back to leverage [`Object.is`](https://github.com/facebook/jest/blob/master/packages/expect/src/jasmineUtils.ts#L91),
for primitive values, it should only be used when complex objects need a comparison. for primitive values, it should only be used when complex objects need a comparison.
Examples: Examples:
...@@ -707,10 +707,10 @@ a [Jest mock for the package `monaco-editor`](https://gitlab.com/gitlab-org/gitl ...@@ -707,10 +707,10 @@ a [Jest mock for the package `monaco-editor`](https://gitlab.com/gitlab-org/gitl
If a manual mock is needed for a CE module, please place it in `spec/frontend/mocks/ce`. If a manual mock is needed for a CE module, please place it in `spec/frontend/mocks/ce`.
- Files in `spec/frontend/mocks/ce` will mock the corresponding CE module from `app/assets/javascripts`, mirroring the source module's path. - Files in `spec/frontend/mocks/ce` mocks the corresponding CE module from `app/assets/javascripts`, mirroring the source module's path.
- Example: `spec/frontend/mocks/ce/lib/utils/axios_utils` will mock the module `~/lib/utils/axios_utils`. - Example: `spec/frontend/mocks/ce/lib/utils/axios_utils` mocks the module `~/lib/utils/axios_utils`.
- We don't support mocking EE modules yet. - We don't support mocking EE modules yet.
- If a mock is found for which a source module doesn't exist, the test suite will fail. 'Virtual' mocks, or mocks that don't have a 1-to-1 association with a source module, are not supported yet. - If a mock is found for which a source module doesn't exist, the test suite fails. 'Virtual' mocks, or mocks that don't have a 1-to-1 association with a source module, are not supported yet.
#### Manual mock examples #### Manual mock examples
...@@ -770,12 +770,12 @@ yarn jest term ...@@ -770,12 +770,12 @@ yarn jest term
Karma allows something similar, but it's way more costly. Karma allows something similar, but it's way more costly.
Running Karma with `yarn run karma-start` will compile the JavaScript Running Karma with `yarn run karma-start` compiles the JavaScript
assets and run a server at `http://localhost:9876/` where it will automatically assets and runs a server at `http://localhost:9876/` where it automatically
run the tests on any browser which connects to it. You can enter that URL on runs the tests on any browser which connects to it. You can enter that URL on
multiple browsers at once to have it run the tests on each in parallel. multiple browsers at once to have it run the tests on each in parallel.
While Karma is running, any changes you make will instantly trigger a recompile While Karma is running, any changes you make instantly trigger a recompile
and retest of the **entire test suite**, so you can see instantly if you've broken and retest of the **entire test suite**, so you can see instantly if you've broken
a test with your changes. You can use [Jasmine focused](https://jasmine.github.io/2.5/focused_specs.html) or a test with your changes. You can use [Jasmine focused](https://jasmine.github.io/2.5/focused_specs.html) or
excluded tests (with `fdescribe` or `xdescribe`) to get Karma to run only the excluded tests (with `fdescribe` or `xdescribe`) to get Karma to run only the
...@@ -827,8 +827,8 @@ You can find generated fixtures are in `tmp/tests/frontend/fixtures-ee`. ...@@ -827,8 +827,8 @@ You can find generated fixtures are in `tmp/tests/frontend/fixtures-ee`.
#### Creating new fixtures #### Creating new fixtures
For each fixture, you can find the content of the `response` variable in the output file. For each fixture, you can find the content of the `response` variable in the output file.
For example, test named `"merge_requests/diff_discussion.json"` in `spec/frontend/fixtures/merge_requests.rb` For example, a test named `"merge_requests/diff_discussion.json"` in `spec/frontend/fixtures/merge_requests.rb`
will produce output file `tmp/tests/frontend/fixtures-ee/merge_requests/diff_discussion.json`. produces an output file `tmp/tests/frontend/fixtures-ee/merge_requests/diff_discussion.json`.
The `response` variable gets automatically set if the test is marked as `type: :request` or `type: :controller`. The `response` variable gets automatically set if the test is marked as `type: :request` or `type: :controller`.
When creating a new fixture, it often makes sense to take a look at the corresponding tests for the When creating a new fixture, it often makes sense to take a look at the corresponding tests for the
...@@ -938,12 +938,12 @@ describe.each` ...@@ -938,12 +938,12 @@ describe.each`
### RSpec errors due to JavaScript ### RSpec errors due to JavaScript
By default RSpec unit tests will not run JavaScript in the headless browser By default RSpec unit tests don't run JavaScript in the headless browser
and will simply rely on inspecting the HTML generated by rails. and rely on inspecting the HTML generated by rails.
If an integration test depends on JavaScript to run correctly, you need to make If an integration test depends on JavaScript to run correctly, you need to make
sure the spec is configured to enable JavaScript when the tests are run. If you sure the spec is configured to enable JavaScript when the tests are run. If you
don't do this you'll see vague error messages from the spec runner. don't do this, the spec runner displays vague error messages.
To enable a JavaScript driver in an `rspec` test, add `:js` to the To enable a JavaScript driver in an `rspec` test, add `:js` to the
individual spec or the context block containing multiple specs that need individual spec or the context block containing multiple specs that need
...@@ -967,11 +967,11 @@ end ...@@ -967,11 +967,11 @@ end
### Jest test timeout due to async imports ### Jest test timeout due to async imports
If a module asynchronously imports some other modules at runtime, these modules will need to be If a module asynchronously imports some other modules at runtime, these modules must be
transpiled by the Jest loaders at runtime. It's possible that this will cause [Jest to timeout](https://gitlab.com/gitlab-org/gitlab/-/issues/280809). transpiled by the Jest loaders at runtime. It's possible that this can cause [Jest to timeout](https://gitlab.com/gitlab-org/gitlab/-/issues/280809).
If you run into this issue, consider eager importing the module so that Jest will compile If you run into this issue, consider eager importing the module so that Jest compiles
and cache it at compile-time, fixing the runtime timeout. and caches it at compile-time, fixing the runtime timeout.
Consider the following example: Consider the following example:
...@@ -986,8 +986,8 @@ export default { ...@@ -986,8 +986,8 @@ export default {
}; };
``` ```
Jest will not automatically transpile the `thing.vue` module, and depending on it's size, could Jest doesn't automatically transpile the `thing.vue` module, and depending on its size, could
cause Jest to timeout. We can force Jest to transpile and cache this module by eagerly importing cause Jest to time out. We can force Jest to transpile and cache this module by eagerly importing
it like so: it like so:
```javascript ```javascript
...@@ -1016,7 +1016,7 @@ Tests relevant for frontend development can be found at the following places: ...@@ -1016,7 +1016,7 @@ Tests relevant for frontend development can be found at the following places:
RSpec runs complete [feature tests](testing_levels.md#frontend-feature-tests), while the Jest and Karma directories contain [frontend unit tests](testing_levels.md#frontend-unit-tests), [frontend component tests](testing_levels.md#frontend-component-tests), and [frontend integration tests](testing_levels.md#frontend-integration-tests). RSpec runs complete [feature tests](testing_levels.md#frontend-feature-tests), while the Jest and Karma directories contain [frontend unit tests](testing_levels.md#frontend-unit-tests), [frontend component tests](testing_levels.md#frontend-component-tests), and [frontend integration tests](testing_levels.md#frontend-integration-tests).
All tests in `spec/javascripts/` will eventually be migrated to `spec/frontend/` (see also [#52483](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/52483)). All tests in `spec/javascripts/` are intended to be migrated to `spec/frontend/` (see also [#52483](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/52483)).
Before May 2018, `features/` also contained feature tests run by Spinach. These tests were removed from the codebase in May 2018 ([#23036](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/23036)). Before May 2018, `features/` also contained feature tests run by Spinach. These tests were removed from the codebase in May 2018 ([#23036](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/23036)).
...@@ -1071,7 +1071,7 @@ describe('FooComponent', () => { ...@@ -1071,7 +1071,7 @@ describe('FooComponent', () => {
const wrapper = extendedWrapper(shallowMount({ const wrapper = extendedWrapper(shallowMount({
template: `<div data-testid="my-test-id"></div>`, template: `<div data-testid="my-test-id"></div>`,
})); }));
it('exists', () => { it('exists', () => {
expect(wrapper.findByTestId('my-test-id').exists()).toBe(true); expect(wrapper.findByTestId('my-test-id').exists()).toBe(true);
}); });
...@@ -1099,7 +1099,7 @@ You can download any older version of Firefox from the releases FTP server, <htt ...@@ -1099,7 +1099,7 @@ You can download any older version of Firefox from the releases FTP server, <htt
1. From the website, select a version, in this case `50.0.1`. 1. From the website, select a version, in this case `50.0.1`.
1. Go to the mac folder. 1. Go to the mac folder.
1. Select your preferred language, you will find the DMG package inside, download it. 1. Select your preferred language. The DMG package is inside. Download it.
1. Drag and drop the application to any other folder but the `Applications` folder. 1. Drag and drop the application to any other folder but the `Applications` folder.
1. Rename the application to something like `Firefox_Old`. 1. Rename the application to something like `Firefox_Old`.
1. Move the application to the `Applications` folder. 1. Move the application to the `Applications` folder.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment