Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-08-13 06:10:15 +00:00
parent ed01bf9b25
commit e9626c2383
19 changed files with 206 additions and 30 deletions

View File

@ -93,7 +93,12 @@ export default {
<div> <div>
<editor-state-observer @docUpdate="notifyChange" @focus="focus" @blur="blur" /> <editor-state-observer @docUpdate="notifyChange" @focus="focus" @blur="blur" />
<content-editor-error /> <content-editor-error />
<div data-testid="content-editor" class="md-area" :class="{ 'is-focused': focused }"> <div
data-testid="content-editor"
data-qa-selector="content_editor_container"
class="md-area"
:class="{ 'is-focused': focused }"
>
<top-toolbar ref="toolbar" class="gl-mb-4" /> <top-toolbar ref="toolbar" class="gl-mb-4" />
<formatting-bubble-menu /> <formatting-bubble-menu />
<div v-if="isLoadingContent" class="gl-w-full gl-display-flex gl-justify-content-center"> <div v-if="isLoadingContent" class="gl-w-full gl-display-flex gl-justify-content-center">

View File

@ -98,6 +98,7 @@ export default {
name="content_editor_image" name="content_editor_image"
:accept="$options.acceptedMimes" :accept="$options.acceptedMimes"
class="gl-display-none" class="gl-display-none"
data-qa-selector="file_upload_field"
@change="onFileSelect" @change="onFileSelect"
/> />
</gl-dropdown> </gl-dropdown>

View File

@ -61,6 +61,7 @@ export default {
<gl-dropdown <gl-dropdown
v-gl-tooltip="$options.i18n.placeholder" v-gl-tooltip="$options.i18n.placeholder"
size="small" size="small"
data-qa-selector="text_style_dropdown"
:disabled="!activeItem" :disabled="!activeItem"
:text="activeItemLabel" :text="activeItemLabel"
> >
@ -69,6 +70,8 @@ export default {
:key="index" :key="index"
is-check-item is-check-item
:is-checked="isActive(item)" :is-checked="isActive(item)"
data-qa-selector="text_style_menu_item"
:data-qa-text-style="item.label"
@click="execute(item)" @click="execute(item)"
> >
{{ item.label }} {{ item.label }}

View File

@ -397,6 +397,7 @@ export default {
v-if="showContentEditorAlert" v-if="showContentEditorAlert"
class="gl-mb-6" class="gl-mb-6"
variant="info" variant="info"
data-qa-selector="try_new_editor_container"
:primary-button-text="$options.i18n.contentEditor.useNewEditor.primaryLabel" :primary-button-text="$options.i18n.contentEditor.useNewEditor.primaryLabel"
:secondary-button-text="$options.i18n.contentEditor.useNewEditor.secondaryLabel" :secondary-button-text="$options.i18n.contentEditor.useNewEditor.secondaryLabel"
:dismiss-label="$options.i18n.contentEditor.useNewEditor.secondaryLabel" :dismiss-label="$options.i18n.contentEditor.useNewEditor.secondaryLabel"

View File

@ -18,7 +18,7 @@ module SpammableActions::CaptchaCheck::JsonFormatActionsSupport
def with_captcha_check_json_format(&block) def with_captcha_check_json_format(&block)
# NOTE: "409 - Conflict" seems to be the most appropriate HTTP status code for a response # NOTE: "409 - Conflict" seems to be the most appropriate HTTP status code for a response
# which requires a CAPTCHA to be solved in order for the request to be resubmitted. # which requires a CAPTCHA to be solved in order for the request to be resubmitted.
# See https://stackoverflow.com/q/26547466/25192 # https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.10
captcha_render_lambda = -> { render json: spam_action_response_fields(spammable), status: :conflict } captcha_render_lambda = -> { render json: spam_action_response_fields(spammable), status: :conflict }
with_captcha_check_common(captcha_render_lambda: captcha_render_lambda, &block) with_captcha_check_common(captcha_render_lambda: captcha_render_lambda, &block)
end end

View File

@ -1,20 +1,19 @@
--- ---
data_category: Optional data_category: Optional
key_path: usage_activity_by_stage_monthly.plan.epics key_path: usage_activity_by_stage_monthly.plan.epics
description: description: Count distinct author ids from epics
product_section: dev product_section: dev
product_stage: product_stage: plan
product_group: group::plan product_group: group::plan
product_category: product_category: epics
value_type: number value_type: number
status: data_available status: data_available
time_frame: 28d time_frame: 28d
data_source: data_source: database
distribution: distribution:
- ce - ee
tier: tier:
- free - premium
skip_validation: true
performance_indicator_type: performance_indicator_type:
- gmau - gmau
- paid_gmau - paid_gmau

View File

@ -1,17 +1,16 @@
--- ---
data_category: Operational data_category: Operational
key_path: usage_activity_by_stage.plan.epics key_path: usage_activity_by_stage.plan.epics
description: description: Count distinct author ids from epics
product_section: dev product_section: dev
product_stage: product_stage: plan
product_group: group::plan product_group: group::plan
product_category: product_category: epics
value_type: number value_type: number
status: data_available status: data_available
time_frame: all time_frame: all
data_source: data_source: database
distribution: distribution:
- ce - ee
tier: tier:
- free - premium
skip_validation: true

View File

@ -167,7 +167,11 @@ curl --header "Authorization: Bearer OAUTH-TOKEN" "https://gitlab.example.com/ap
Read more about [GitLab as an OAuth2 provider](oauth2.md). Read more about [GitLab as an OAuth2 provider](oauth2.md).
NOTE: NOTE:
We recommend that OAuth access tokens have an expiration. You can use a `refresh_token` to refresh tokens. Integrations may need to be updated to refresh tokens prior to expiration, which is based on the [expires_in](https://datatracker.ietf.org/doc/html/rfc6749#appendix-A.14) property in the token endpoint response. We recommend OAuth access tokens have an expiration. You can use the `refresh_token` parameter
to refresh tokens. Integrations may need to be updated to use refresh tokens prior to
expiration, which is based on the [expires_in](https://datatracker.ietf.org/doc/html/rfc6749#appendix-A.14)
property in the token endpoint response. See [OAuth2 token](oauth2.md) documentation
for examples requesting a new access token using a refresh token.
A default refresh setting of two hours is tracked in [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/336598). A default refresh setting of two hours is tracked in [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/336598).

View File

@ -123,6 +123,28 @@ Before starting the flow, generate the `STATE`, the `CODE_VERIFIER` and the `COD
"created_at": 1607635748 "created_at": 1607635748
} }
``` ```
1. To retrieve a new `access_token`, use the `refresh_token` parameter. Refresh tokens may
be used even after the `access_token` itself expires. This request:
- Invalidates the existing `access_token` and `refresh_token`.
- Sends new tokens in the response.
```ruby
parameters = 'client_id=APP_ID&client_secret=APP_SECRET&refresh_token=REFRESH_TOKEN&grant_type=refresh_token&redirect_uri=REDIRECT_URI&code_verifier=CODE_VERIFIER'
RestClient.post 'https://gitlab.example.com/oauth/token', parameters
```
Example response:
```json
{
"access_token": "c97d1fe52119f38c7f67f0a14db68d60caa35ddc86fd12401718b649dcfa9c68",
"token_type": "bearer",
"expires_in": 7200,
"refresh_token": "803c1fd487fec35562c205dac93e9d8e08f9d3652a24079d704df3039df1158f",
"created_at": 1628711391
}
```
NOTE: NOTE:
The `redirect_uri` must match the `redirect_uri` used in the original The `redirect_uri` must match the `redirect_uri` used in the original
@ -181,6 +203,28 @@ be used as a CSRF token.
"created_at": 1607635748 "created_at": 1607635748
} }
``` ```
1. To retrieve a new `access_token`, use the `refresh_token` parameter. Refresh tokens may
be used even after the `access_token` itself expires. This request:
- Invalidates the existing `access_token` and `refresh_token`.
- Sends new tokens in the response.
```ruby
parameters = 'client_id=APP_ID&client_secret=APP_SECRET&refresh_token=REFRESH_TOKEN&grant_type=refresh_token&redirect_uri=REDIRECT_URI'
RestClient.post 'https://gitlab.example.com/oauth/token', parameters
```
Example response:
```json
{
"access_token": "c97d1fe52119f38c7f67f0a14db68d60caa35ddc86fd12401718b649dcfa9c68",
"token_type": "bearer",
"expires_in": 7200,
"refresh_token": "803c1fd487fec35562c205dac93e9d8e08f9d3652a24079d704df3039df1158f",
"created_at": 1628711391
}
```
NOTE: NOTE:
The `redirect_uri` must match the `redirect_uri` used in the original The `redirect_uri` must match the `redirect_uri` used in the original

View File

@ -1546,7 +1546,7 @@ curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitla
Returns: Returns:
- `201 OK` on success. - `201 Created` on success.
- `404 User Not Found` if user cannot be found. - `404 User Not Found` if user cannot be found.
- `403 Forbidden` if the user cannot be approved because they are blocked by an administrator or by LDAP synchronization. - `403 Forbidden` if the user cannot be approved because they are blocked by an administrator or by LDAP synchronization.

View File

@ -39,8 +39,8 @@ more complicated issues.
To validate the configuration by running a pipeline simulation: To validate the configuration by running a pipeline simulation:
1. Paste the GitLab CI configuration to verify into the text box. 1. Paste the GitLab CI configuration to verify into the text box.
1. Click the **Simulate pipeline creation for the default branch** checkbox. 1. Select the **Simulate pipeline creation for the default branch** checkbox.
1. Click **Validate**. 1. Select **Validate**.
![Dry run](img/ci_lint_dry_run.png) ![Dry run](img/ci_lint_dry_run.png)

View File

@ -135,13 +135,13 @@ operation of the pipeline.
To execute a pipeline manually: To execute a pipeline manually:
1. Navigate to your project's **CI/CD > Pipelines**. 1. On the top bar, select **Menu > Projects** and find your project.
1. Select the **Run pipeline** button. 1. On the left sidebar, select **CI/CD > Pipelines**.
1. On the **Run pipeline** page: 1. Select **Run pipeline**.
1. Select the branch or tag to run the pipeline for in the **Run for branch name or tag** field. 1. In the **Run for branch name or tag** field, select the branch or tag to run the pipeline for.
1. Enter any [environment variables](../variables/index.md) required for the pipeline run. 1. Enter any [environment variables](../variables/index.md) required for the pipeline to run.
You can set specific variables to have their [values prefilled in the form](#prefill-variables-in-manual-pipelines). You can set specific variables to have their [values prefilled in the form](#prefill-variables-in-manual-pipelines).
1. Click the **Run pipeline** button. 1. Select **Run pipeline**.
The pipeline now executes the jobs as configured. The pipeline now executes the jobs as configured.
@ -413,7 +413,7 @@ Feature.disable(:pipeline_graph_layers_view)
Pipeline mini graphs take less space and can tell you at a Pipeline mini graphs take less space and can tell you at a
quick glance if all jobs passed or something failed. The pipeline mini graph can quick glance if all jobs passed or something failed. The pipeline mini graph can
be found when you navigate to: be found when you go to:
- The pipelines index page. - The pipelines index page.
- A single commit page. - A single commit page.

View File

@ -911,14 +911,16 @@ describe '#show', :snowplow do
expect_snowplow_event( expect_snowplow_event(
category: 'Experiment', category: 'Experiment',
action: 'start', action: 'start',
standard_context: { namespace: group, project: project } namespace: group,
project: project
) )
expect_snowplow_event( expect_snowplow_event(
category: 'Experiment', category: 'Experiment',
action: 'sent', action: 'sent',
property: 'property', property: 'property',
label: 'label', label: 'label',
standard_context: { namespace: group, project: project } namespace: group,
project: project
) )
end end
end end

View File

@ -544,6 +544,7 @@ module QA
autoload :AccessTokens, 'qa/page/component/access_tokens' autoload :AccessTokens, 'qa/page/component/access_tokens'
autoload :CommitModal, 'qa/page/component/commit_modal' autoload :CommitModal, 'qa/page/component/commit_modal'
autoload :VisibilitySetting, 'qa/page/component/visibility_setting' autoload :VisibilitySetting, 'qa/page/component/visibility_setting'
autoload :ContentEditor, 'qa/page/component/content_editor'
module Import module Import
autoload :Gitlab, 'qa/page/component/import/gitlab' autoload :Gitlab, 'qa/page/component/import/gitlab'

View File

@ -0,0 +1,54 @@
# frozen_string_literal: true
module QA
module Page
module Component
module ContentEditor
extend QA::Page::PageConcern
def self.included(base)
super
base.view 'app/assets/javascripts/content_editor/components/content_editor.vue' do
element :content_editor_container
end
base.view 'app/assets/javascripts/content_editor/components/toolbar_text_style_dropdown.vue' do
element :text_style_dropdown
element :text_style_menu_item
end
base.view 'app/assets/javascripts/content_editor/components/toolbar_image_button.vue' do
element :file_upload_field
end
end
def add_heading(heading, text)
within_element(:content_editor_container) do
text_area.set(text)
# wait for text style option to become active after typing
has_active_element?(:text_style_dropdown, wait: 1)
click_element(:text_style_dropdown)
within_element(:text_style_dropdown) do
click_element(:text_style_menu_item, text_style: heading)
end
end
end
def upload_image(image_path)
within_element(:content_editor_container) do
# add image on a new line
text_area.send_keys(:return)
find_element(:file_upload_field, visible: false).send_keys(image_path)
end
end
private
def text_area
find('[contenteditable="true"]', visible: false)
end
end
end
end
end

View File

@ -68,6 +68,18 @@ module QA
def has_no_page? def has_no_page?
has_element?(:create_first_page_link) has_element?(:create_first_page_link)
end end
def has_heading?(heading_type, text)
within_element(:wiki_page_content) do
has_css?(heading_type, text: text)
end
end
def has_image?(image_file_name)
within_element(:wiki_page_content) do
has_css?("img[src$='#{image_file_name}']")
end
end
end end
end end
end end

View File

@ -14,6 +14,7 @@ module QA
element :wiki_content_textarea element :wiki_content_textarea
element :wiki_message_textbox element :wiki_message_textbox
element :wiki_submit_button element :wiki_submit_button
element :try_new_editor_container
end end
base.view 'app/assets/javascripts/pages/shared/wikis/components/delete_wiki_modal.vue' do base.view 'app/assets/javascripts/pages/shared/wikis/components/delete_wiki_modal.vue' do
@ -41,6 +42,12 @@ module QA
click_element(:delete_button, Page::Modal::DeleteWiki) click_element(:delete_button, Page::Modal::DeleteWiki)
Page::Modal::DeleteWiki.perform(&:confirm_deletion) Page::Modal::DeleteWiki.perform(&:confirm_deletion)
end end
def use_new_editor
within_element(:try_new_editor_container) do
click_button('Use the new editor')
end
end
end end
end end
end end

View File

@ -7,6 +7,7 @@ module QA
class Edit < Base class Edit < Base
include Page::Component::WikiPageForm include Page::Component::WikiPageForm
include Page::Component::WikiSidebar include Page::Component::WikiSidebar
include Page::Component::ContentEditor
end end
end end
end end

View File

@ -0,0 +1,43 @@
# frozen_string_literal: true
module QA
RSpec.describe 'Create' do
context 'Content Editor' do
let(:initial_wiki) { Resource::Wiki::ProjectPage.fabricate_via_api! }
let(:page_title) { 'Content Editor Page' }
let(:heading_text) { 'My New Heading' }
let(:image_file_name) { 'testfile.png' }
before do
Flow::Login.sign_in
end
after do
initial_wiki.project.remove_via_api!
end
it 'creates a formatted Wiki page with an image uploaded', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1861' do
initial_wiki.visit!
Page::Project::Wiki::Show.perform(&:click_new_page)
Page::Project::Wiki::Edit.perform do |edit|
edit.set_title(page_title)
edit.use_new_editor
edit.add_heading('Heading 1', heading_text)
edit.upload_image(File.absolute_path(File.join('qa', 'fixtures', 'designs', image_file_name)))
end
Page::Project::Wiki::Edit.perform(&:click_submit)
Page::Project::Wiki::Show.perform do |wiki|
aggregate_failures 'page shows expected content' do
expect(wiki).to have_title(page_title)
expect(wiki).to have_heading('h1', heading_text)
expect(wiki).to have_image(image_file_name)
end
end
end
end
end
end