summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/stylesheets/components/avatar.scss240
-rw-r--r--app/assets/stylesheets/pages/search.scss10
-rw-r--r--app/views/profiles/chat_names/_chat_name.html.haml4
-rw-r--r--app/views/profiles/chat_names/index.html.haml16
-rw-r--r--changelogs/unreleased/62227-webkit-icon-overlap.yml5
-rw-r--r--changelogs/unreleased/i18n-chat-of-user-profile.yml5
-rw-r--r--doc/university/glossary/README.md2
-rw-r--r--locale/gitlab.pot21
-rw-r--r--qa/README.md6
-rw-r--r--qa/docs/GUIDELINES.md46
-rw-r--r--qa/docs/best_practices.md (renamed from qa/docs/BEST_PRACTICES.md)2
-rw-r--r--qa/docs/guidelines.md97
-rw-r--r--qa/docs/writing_tests_from_scratch.md (renamed from qa/docs/WRITING_TESTS_FROM_SCRATCH.md)4
13 files changed, 297 insertions, 161 deletions
diff --git a/app/assets/stylesheets/components/avatar.scss b/app/assets/stylesheets/components/avatar.scss
index 4ab197b935b..25ee3ca944d 100644
--- a/app/assets/stylesheets/components/avatar.scss
+++ b/app/assets/stylesheets/components/avatar.scss
@@ -1,28 +1,111 @@
+$avatar-sizes: (
+ 16: (
+ font-size: 10px,
+ line-height: 16px,
+ border-radius: $border-radius-small
+ ),
+ 18: (
+ border-radius: $border-radius-small
+ ),
+ 19: (
+ border-radius: $border-radius-small
+ ),
+ 20: (
+ border-radius: $border-radius-small
+ ),
+ 24: (
+ font-size: 12px,
+ line-height: 24px,
+ border-radius: $border-radius-default
+ ),
+ 26: (
+ font-size: 20px,
+ line-height: 1.33,
+ border-radius: $border-radius-default
+ ),
+ 32: (
+ font-size: 14px,
+ line-height: 32px,
+ border-radius: $border-radius-default
+ ),
+ 36: (
+ border-radius: $border-radius-default
+ ),
+ 40: (
+ font-size: 16px,
+ line-height: 38px,
+ border-radius: $border-radius-default
+ ),
+ 46: (
+ border-radius: $border-radius-default
+ ),
+ 48: (
+ font-size: 20px,
+ line-height: 48px,
+ border-radius: $border-radius-large
+ ),
+ 60: (
+ font-size: 32px,
+ line-height: 58px,
+ border-radius: $border-radius-large
+ ),
+ 64: (
+ font-size: 28px,
+ line-height: 64px,
+ border-radius: $border-radius-large
+ ),
+ 70: (
+ font-size: 34px,
+ line-height: 70px,
+ border-radius: $border-radius-large
+ ),
+ 90: (
+ font-size: 36px,
+ line-height: 88px,
+ border-radius: $border-radius-large
+ ),
+ 96: (
+ font-size: 48px,
+ line-height: 96px,
+ border-radius: $border-radius-large
+ ),
+ 100: (
+ font-size: 36px,
+ line-height: 98px,
+ border-radius: $border-radius-large
+ ),
+ 110: (
+ font-size: 40px,
+ line-height: 108px,
+ font-weight: $gl-font-weight-normal,
+ border-radius: $border-radius-large
+ ),
+ 140: (
+ font-size: 72px,
+ line-height: 138px,
+ border-radius: $border-radius-large
+ ),
+ 160: (
+ font-size: 96px,
+ line-height: 158px,
+ border-radius: $border-radius-large
+ )
+);
+
+$identicon-backgrounds: $identicon-red, $identicon-purple, $identicon-indigo, $identicon-blue, $identicon-teal,
+ $identicon-orange, $gray-darker;
+
.avatar-circle {
float: left;
margin-right: 15px;
border-radius: $avatar-radius;
border: 1px solid $gray-normal;
- &.s16 { @include avatar-size(16px, 8px); }
- &.s18 { @include avatar-size(18px, 8px); }
- &.s19 { @include avatar-size(19px, 8px); }
- &.s20 { @include avatar-size(20px, 8px); }
- &.s24 { @include avatar-size(24px, 8px); }
- &.s26 { @include avatar-size(26px, 8px); }
- &.s32 { @include avatar-size(32px, 8px); }
- &.s36 { @include avatar-size(36px, 16px); }
- &.s40 { @include avatar-size(40px, 16px); }
- &.s46 { @include avatar-size(46px, 16px); }
- &.s48 { @include avatar-size(48px, 16px); }
- &.s60 { @include avatar-size(60px, 16px); }
- &.s64 { @include avatar-size(64px, 16px); }
- &.s70 { @include avatar-size(70px, 16px); }
- &.s90 { @include avatar-size(90px, 16px); }
- &.s96 { @include avatar-size(96px, 16px); }
- &.s100 { @include avatar-size(100px, 16px); }
- &.s110 { @include avatar-size(110px, 16px); }
- &.s140 { @include avatar-size(140px, 16px); }
- &.s160 { @include avatar-size(160px, 16px); }
+
+ @each $size, $size-config in $avatar-sizes {
+ &.s#{$size} {
+ @include avatar-size(#{$size}px, if($size < 36, 8px, 16px));
+ }
+ }
}
.avatar {
@@ -42,8 +125,13 @@
margin-left: 2px;
flex-shrink: 0;
- &.s16 { margin-right: 4px; }
- &.s24 { margin-right: 4px; }
+ &.s16 {
+ margin-right: 4px;
+ }
+
+ &.s24 {
+ margin-right: 4px;
+ }
}
&.center {
@@ -69,60 +157,25 @@
background-color: $gray-darker;
// Sizes
- &.s16 { font-size: 10px;
- line-height: 16px; }
-
- &.s24 { font-size: 12px;
- line-height: 24px; }
-
- &.s26 { font-size: 20px;
- line-height: 1.33; }
-
- &.s32 { font-size: 14px;
- line-height: 32px; }
-
- &.s40 { font-size: 16px;
- line-height: 38px; }
-
- &.s48 { font-size: 20px;
- line-height: 48px; }
-
- &.s60 { font-size: 32px;
- line-height: 58px; }
-
- &.s64 { font-size: 28px;
- line-height: 64px; }
-
- &.s70 { font-size: 34px;
- line-height: 70px; }
-
- &.s90 { font-size: 36px;
- line-height: 88px; }
-
- &.s96 { font-size: 48px;
- line-height: 96px; }
-
- &.s100 { font-size: 36px;
- line-height: 98px; }
-
- &.s110 { font-size: 40px;
- line-height: 108px;
- font-weight: $gl-font-weight-normal; }
-
- &.s140 { font-size: 72px;
- line-height: 138px; }
-
- &.s160 { font-size: 96px;
- line-height: 158px; }
+ @each $size, $size-config in $avatar-sizes {
+ $keys: map-keys($size-config);
+
+ &.s#{$size} {
+ @each $key in $keys {
+ // We don't want `border-radius` to be included here.
+ @if ($key != 'border-radius') {
+ #{$key}: map-get($size-config, #{$key});
+ }
+ }
+ }
+ }
// Background colors
- &.bg1 { background-color: $identicon-red; }
- &.bg2 { background-color: $identicon-purple; }
- &.bg3 { background-color: $identicon-indigo; }
- &.bg4 { background-color: $identicon-blue; }
- &.bg5 { background-color: $identicon-teal; }
- &.bg6 { background-color: $identicon-orange; }
- &.bg7 { background-color: $gray-darker; }
+ @for $i from 1 through length($identicon-backgrounds) {
+ &.bg#{$i} {
+ background-color: nth($identicon-backgrounds, $i);
+ }
+ }
}
.avatar-container {
@@ -139,41 +192,32 @@
.avatar {
border-radius: 0;
+ border: 0;
height: auto;
width: 100%;
margin: 0;
align-self: center;
}
- &.s40 { min-width: 40px;
- min-height: 40px; }
+ &.s40 {
+ min-width: 40px;
+ min-height: 40px;
+ }
- &.s64 { min-width: 64px;
- min-height: 64px; }
+ &.s64 {
+ min-width: 64px;
+ min-height: 64px;
+ }
}
.rect-avatar {
border-radius: $border-radius-small;
- &.s16 { border-radius: $border-radius-small; }
- &.s18 { border-radius: $border-radius-small; }
- &.s19 { border-radius: $border-radius-small; }
- &.s20 { border-radius: $border-radius-small; }
- &.s24 { border-radius: $border-radius-default; }
- &.s26 { border-radius: $border-radius-default; }
- &.s32 { border-radius: $border-radius-default; }
- &.s36 { border-radius: $border-radius-default; }
- &.s40 { border-radius: $border-radius-default; }
- &.s46 { border-radius: $border-radius-default; }
- &.s48 { border-radius: $border-radius-large; }
- &.s60 { border-radius: $border-radius-large; }
- &.s64 { border-radius: $border-radius-large; }
- &.s70 { border-radius: $border-radius-large; }
- &.s90 { border-radius: $border-radius-large; }
- &.s96 { border-radius: $border-radius-large; }
- &.s100 { border-radius: $border-radius-large; }
- &.s110 { border-radius: $border-radius-large; }
- &.s140 { border-radius: $border-radius-large; }
- &.s160 { border-radius: $border-radius-large; }
+
+ @each $size, $size-config in $avatar-sizes {
+ &.s#{$size} {
+ border-radius: map-get($size-config, 'border-radius');
+ }
+ }
}
.avatar-counter {
diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss
index 37071a57bb3..dbf600df9d6 100644
--- a/app/assets/stylesheets/pages/search.scss
+++ b/app/assets/stylesheets/pages/search.scss
@@ -261,3 +261,13 @@ input[type='checkbox']:hover {
color: $blue-600;
}
}
+
+// Disable webkit input icons, link to solution: https://stackoverflow.com/questions/9421551/how-do-i-remove-all-default-webkit-search-field-styling
+/* stylelint-disable property-no-vendor-prefix */
+input[type='search']::-webkit-search-decoration,
+input[type='search']::-webkit-search-cancel-button,
+input[type='search']::-webkit-search-results-button,
+input[type='search']::-webkit-search-results-decoration {
+ -webkit-appearance: none;
+}
+/* stylelint-enable */
diff --git a/app/views/profiles/chat_names/_chat_name.html.haml b/app/views/profiles/chat_names/_chat_name.html.haml
index 9e82e47c1e1..ff67f92ad07 100644
--- a/app/views/profiles/chat_names/_chat_name.html.haml
+++ b/app/views/profiles/chat_names/_chat_name.html.haml
@@ -21,7 +21,7 @@
- if chat_name.last_used_at
= time_ago_with_tooltip(chat_name.last_used_at)
- else
- Never
+ = _('Never')
%td
- = link_to 'Remove', profile_chat_name_path(chat_name), method: :delete, class: 'btn btn-danger float-right', data: { confirm: 'Are you sure you want to revoke this nickname?' }
+ = link_to _('Remove'), profile_chat_name_path(chat_name), method: :delete, class: 'btn btn-danger float-right', data: { confirm: _('Are you sure you want to revoke this nickname?') }
diff --git a/app/views/profiles/chat_names/index.html.haml b/app/views/profiles/chat_names/index.html.haml
index 4b6e419af50..0c8098a97d5 100644
--- a/app/views/profiles/chat_names/index.html.haml
+++ b/app/views/profiles/chat_names/index.html.haml
@@ -1,4 +1,4 @@
-- page_title 'Chat'
+- page_title _('Chat')
- @content_class = "limit-container-width" unless fluid_layout
.row.prepend-top-default
@@ -6,7 +6,7 @@
%h4.prepend-top-0
= page_title
%p
- You can see your Chat accounts.
+ = _('You can see your chat accounts.')
.col-lg-8
%h5 Active chat names (#{@chat_names.size})
@@ -16,15 +16,15 @@
%table.table.chat-names
%thead
%tr
- %th Project
- %th Service
- %th Team domain
- %th Nickname
- %th Last used
+ %th= _('Project')
+ %th= _('Service')
+ %th= _('Team domain')
+ %th= _('Nickname')
+ %th= _('Last used')
%th
%tbody
= render @chat_names
- else
.settings-message.text-center
- You don't have any active chat names.
+ = _("You don't have any active chat names.")
diff --git a/changelogs/unreleased/62227-webkit-icon-overlap.yml b/changelogs/unreleased/62227-webkit-icon-overlap.yml
new file mode 100644
index 00000000000..47d7583f4c2
--- /dev/null
+++ b/changelogs/unreleased/62227-webkit-icon-overlap.yml
@@ -0,0 +1,5 @@
+---
+title: Add style to disable webkit icons for search inputs
+merge_request: 28833
+author: Jarek Ostrowski @jareko
+type: fixed
diff --git a/changelogs/unreleased/i18n-chat-of-user-profile.yml b/changelogs/unreleased/i18n-chat-of-user-profile.yml
new file mode 100644
index 00000000000..663b4ffc1a1
--- /dev/null
+++ b/changelogs/unreleased/i18n-chat-of-user-profile.yml
@@ -0,0 +1,5 @@
+---
+title: Externalize strings of chat page in user profile
+merge_request: 28632
+author:
+type: other
diff --git a/doc/university/glossary/README.md b/doc/university/glossary/README.md
index 647ad4b2e24..f15b0107de5 100644
--- a/doc/university/glossary/README.md
+++ b/doc/university/glossary/README.md
@@ -381,7 +381,7 @@ Takes changes from one branch, and [applies them](https://git-scm.com/docs/git-m
[Arises](https://about.gitlab.com/2016/09/06/resolving-merge-conflicts-from-the-gitlab-ui/) when a merge can't be performed cleanly between two versions of the same file.
-#### Merge Request
+#### Merge Request (MR)
[Takes changes](../../gitlab-basics/add-merge-request.md) from one branch, and applies them into another branch.
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index afb1f7efadd..9e7ff8d1847 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -1126,6 +1126,9 @@ msgstr ""
msgid "Are you sure you want to reset the health check token?"
msgstr ""
+msgid "Are you sure you want to revoke this nickname?"
+msgstr ""
+
msgid "Are you sure you want to stop this environment?"
msgstr ""
@@ -5650,6 +5653,9 @@ msgstr ""
msgid "Last updated"
msgstr ""
+msgid "Last used"
+msgstr ""
+
msgid "LastPushEvent|You pushed to"
msgstr ""
@@ -6386,6 +6392,9 @@ msgstr ""
msgid "Next"
msgstr ""
+msgid "Nickname"
+msgstr ""
+
msgid "No"
msgstr ""
@@ -8735,6 +8744,9 @@ msgstr ""
msgid "Serverless|There is currently no function data available from Knative. This could be for a variety of reasons including:"
msgstr ""
+msgid "Service"
+msgstr ""
+
msgid "Service Templates"
msgstr ""
@@ -9520,6 +9532,9 @@ msgstr ""
msgid "Team"
msgstr ""
+msgid "Team domain"
+msgstr ""
+
msgid "Template"
msgstr ""
@@ -11334,6 +11349,9 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
+msgid "You can see your chat accounts."
+msgstr ""
+
msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
@@ -11370,6 +11388,9 @@ msgstr ""
msgid "You do not have permission to leave this %{namespaceType}."
msgstr ""
+msgid "You don't have any active chat names."
+msgstr ""
+
msgid "You don't have any applications"
msgstr ""
diff --git a/qa/README.md b/qa/README.md
index 002ad4c65f5..f75205133e6 100644
--- a/qa/README.md
+++ b/qa/README.md
@@ -49,10 +49,10 @@ will need to [modify your GDK setup](https://gitlab.com/gitlab-org/gitlab-qa/blo
### Writing tests
-- [Writing tests from scratch tutorial](docs/WRITING_TESTS_FROM_SCRATCH.md)
- - [Best practices](docs/BEST_PRACTICES.md)
+- [Writing tests from scratch tutorial](docs/writing_tests_from_scratch.md)
+ - [Best practices](docs/best_practices.md)
- [Using page objects](qa/page/README.md)
- - [Guidelines](docs/GUIDELINES.md)
+ - [Guidelines](docs/guidelines.md)
### Running specific tests
diff --git a/qa/docs/GUIDELINES.md b/qa/docs/GUIDELINES.md
deleted file mode 100644
index 9db52cd07e6..00000000000
--- a/qa/docs/GUIDELINES.md
+++ /dev/null
@@ -1,46 +0,0 @@
-# Style guide for writing GUI tests
-
-This document describes the conventions used at GitLab for writing GUI tests using the GitLab QA project.
-
-## `click_` versus `go_to_`
-
-### When to use `click_`?
-
-When clicking in a single link to navigate, use `click_`.
-
-E.g.:
-
-```ruby
-def click_ci_cd_pipelines
- within_sidebar do
- click_element :link_pipelines
- end
-end
-```
-
-From a testing perspective, if we want to check that clicking a link, or a button (a single interaction) is working as intended, we would want the test to read as:
-
-- Click a certain element
-- Verify the action took place
-
-### When to use `go_to_`?
-
-When interacting with multiple elements to go to a page, use `go_to_`.
-
-E.g.:
-
-```ruby
-def go_to_operations_environments
- hover_operations do
- within_submenu do
- click_element(:operations_environments_link)
- end
- end
-end
-```
-
-`go_to_` fits the definition of interacting with multiple elements very well given it's more of a meta-navigation action that includes multiple interactions.
-
-Notice that in the above example, before clicking the `:operations_environments_link`, another element is hovered over.
-
-> We can create these methods as helpers to abstract multi-step navigation.
diff --git a/qa/docs/BEST_PRACTICES.md b/qa/docs/best_practices.md
index 3a2640607e4..d6e5350b0c8 100644
--- a/qa/docs/BEST_PRACTICES.md
+++ b/qa/docs/best_practices.md
@@ -35,4 +35,4 @@ Finally, interacting with the application only by its GUI generates a higher rat
- Building state through the GUI is time consuming and it's not sustainable as the test suite grows.
- When depending only on the GUI to create the application's state and tests fail due to front-end issues, we can't rely on the test failures rate, and we generates a higher rate of test flakiness.
-Now that we are aware of all of it, [let's go create some tests](./WRITING_TESTS_FROM_SCRATCH.md).
+Now that we are aware of all of it, [let's go create some tests](writing_tests_from_scratch.md).
diff --git a/qa/docs/guidelines.md b/qa/docs/guidelines.md
new file mode 100644
index 00000000000..cd4b939fd71
--- /dev/null
+++ b/qa/docs/guidelines.md
@@ -0,0 +1,97 @@
+# Style guide for writing E2E tests
+
+This document describes the conventions used at GitLab for writing E2E tests using the GitLab QA project.
+
+## `click_` versus `go_to_`
+
+### When to use `click_`?
+
+When clicking in a single link to navigate, use `click_`.
+
+E.g.:
+
+```ruby
+def click_ci_cd_pipelines
+ within_sidebar do
+ click_element :link_pipelines
+ end
+end
+```
+
+From a testing perspective, if we want to check that clicking a link, or a button (a single interaction) is working as intended, we would want the test to read as:
+
+- Click a certain element
+- Verify the action took place
+
+### When to use `go_to_`?
+
+When interacting with multiple elements to go to a page, use `go_to_`.
+
+E.g.:
+
+```ruby
+def go_to_operations_environments
+ hover_operations do
+ within_submenu do
+ click_element(:operations_environments_link)
+ end
+ end
+end
+```
+
+`go_to_` fits the definition of interacting with multiple elements very well given it's more of a meta-navigation action that includes multiple interactions.
+
+Notice that in the above example, before clicking the `:operations_environments_link`, another element is hovered over.
+
+> We can create these methods as helpers to abstract multi-step navigation.
+
+### Element Naming Convention
+
+When adding new elements to a page, it's important that we have a uniform element naming convention.
+
+We follow a simple formula roughly based on hungarian notation.
+
+*Formula*: `element :<descriptor>_<type>`
+
+- `descriptor`: The natural-language description of what the element is. On the login page, this could be `username`, or `password`.
+- `type`: A physical control on the page that can be seen by a user.
+ - `_button`
+ - `_link`
+ - `_tab`
+ - `_dropdown`
+ - `_field`
+ - `_checkbox`
+ - `_radio`
+ - `_content`
+
+*Note: This list is a work in progress. This list will eventually be the end-all enumeration of all available types.
+ I.e., any element that does not end with something in this list is bad form.*
+
+#### Examples
+
+**Good**
+```ruby
+view '...' do
+ element :edit_button
+ element :notes_tab
+ element :squash_checkbox
+ element :username_field
+ element :issue_title_content
+end
+```
+
+**Bad**
+```ruby
+view '...' do
+ # `_confirmation` should be `_field`. what sort of confirmation? a checkbox confirmation? no real way to disambiguate.
+ # an appropriate replacement would be `element :password_confirmation_field`
+ element :password_confirmation
+
+ # `clone_options` is too vague. If it's a dropdown menu, it should be `clone_dropdown`.
+ # If it's a checkbox, it should be `clone_checkbox`
+ element :clone_options
+
+ # how is this url being displayed? is it a textbox? a simple span?
+ element :ssh_clone_url
+end
+```
diff --git a/qa/docs/WRITING_TESTS_FROM_SCRATCH.md b/qa/docs/writing_tests_from_scratch.md
index 309fcc4064c..65e7a78a8b5 100644
--- a/qa/docs/WRITING_TESTS_FROM_SCRATCH.md
+++ b/qa/docs/writing_tests_from_scratch.md
@@ -8,7 +8,7 @@ In this tutorial, you will find different examples, and the steps involved, in t
It's important to understand that end-to-end tests of isolated features, such as the ones described in the above note, doesn't mean that everything needs to happen through the GUI.
-If you don't exactly understand what we mean by **not everything needs to happen through the GUI,** please make sure you've read the [best practices](./BEST_PRACTICES.md) before moving on.
+If you don't exactly understand what we mean by **not everything needs to happen through the GUI,** please make sure you've read the [best practices](best_practices.md) before moving on.
## This document covers the following items:
@@ -367,7 +367,7 @@ With that in mind, resources can be a project, an epic, an issue, a label, a com
As you saw in the tests' pre-conditions and the optimization sections, we're already creating some of these resources, and we are doing that by calling the `fabricate_via_api!` method.
-> We could be using the `fabricate!` method instead, which would use the `fabricate_via_api!` method if it exists, and fallback to GUI fabrication otherwise, but we recommend being explicit to make it clear what the test does. Also, we recommend fabricating resources via API since this makes tests faster and more reliable, unless the test is focusing on the GUI itself, or there's no GUI coverage for that specific part in any other test.
+> We could be using the `fabricate!` method instead, which would use the `fabricate_via_api!` method if it exists, and fallback to GUI fabrication otherwise, but we recommend being explicit to make it clear what the test does. Also, we always recommend fabricating resources via API since this makes tests faster and more reliable.
For our test suite example, the [project resource](https://gitlab.com/gitlab-org/gitlab-ee/blob/d3584e80b4236acdf393d815d604801573af72cc/qa/qa/resource/project.rb#L55) already had a `fabricate_via_api!` method available, while other resources don't have it, so we will have to create them, like for the issue and label resources. Also, we will have to make a small change in the project resource to expose its `id` attribute so that we can refer to it when fabricating the issue.