Commit 3249c49c authored by Ramya Authappan's avatar Ramya Authappan

Merge branch 'qa-shl-e2e-test-for-project-access-tokens' into 'master'

Add end-to-end tests for project access tokens

See merge request gitlab-org/gitlab!56839
parents 75b91ad7 3583b0c2
......@@ -80,6 +80,7 @@ module QA
autoload :CiVariable, 'qa/resource/ci_variable'
autoload :Runner, 'qa/resource/runner'
autoload :PersonalAccessToken, 'qa/resource/personal_access_token'
autoload :ProjectAccessToken, 'qa/resource/project_access_token'
autoload :User, 'qa/resource/user'
autoload :ProjectMilestone, 'qa/resource/project_milestone'
autoload :GroupMilestone, 'qa/resource/group_milestone'
......@@ -318,6 +319,7 @@ module QA
autoload :MirroringRepositories, 'qa/page/project/settings/mirroring_repositories'
autoload :ProtectedTags, 'qa/page/project/settings/protected_tags'
autoload :VisibilityFeaturesPermissions, 'qa/page/project/settings/visibility_features_permissions'
autoload :AccessTokens, 'qa/page/project/settings/access_tokens'
module Services
autoload :Jira, 'qa/page/project/settings/services/jira'
......@@ -500,6 +502,7 @@ module QA
autoload :Wiki, 'qa/page/component/wiki'
autoload :WikiSidebar, 'qa/page/component/wiki_sidebar'
autoload :WikiPageForm, 'qa/page/component/wiki_page_form'
autoload :AccessTokens, 'qa/page/component/access_tokens'
autoload :CommitModal, 'qa/page/component/commit_modal'
module Issuable
......
# frozen_string_literal: true
module QA
module Page
module Component
module AccessTokens
extend QA::Page::PageConcern
def self.included(base)
super
base.view 'app/assets/javascripts/access_tokens/components/expires_at_field.vue' do
element :expiry_date_field
end
base.view 'app/views/shared/access_tokens/_form.html.haml' do
element :access_token_name_field
element :create_token_button
end
base.view 'app/views/shared/tokens/_scopes_form.html.haml' do
element :api_radio, 'qa-#{scope}-radio' # rubocop:disable QA/ElementWithPattern, Lint/InterpolationCheck
end
base.view 'app/views/shared/access_tokens/_created_container.html.haml' do
element :created_access_token
end
base.view 'app/views/shared/access_tokens/_table.html.haml' do
element :revoke_button
end
end
def fill_token_name(name)
fill_element(:access_token_name_field, name)
end
def check_api
check_element(:api_radio)
end
def click_create_token_button
click_element(:create_token_button)
end
def created_access_token
find_element(:created_access_token, wait: 30).value
end
def fill_expiry_date(date)
date = date.to_s if date.is_a?(Date)
Date.strptime(date, '%Y-%m-%d') rescue ArgumentError raise "Expiry date must be in YYYY-MM-DD format"
fill_element(:expiry_date_field, date)
end
def has_token_row_for_name?(token_name)
page.has_css?('tr', text: token_name, wait: 1.0)
end
def first_token_row_for_name(token_name)
page.find('tr', text: token_name, match: :first, wait: 1.0)
end
def revoke_first_token_with_name(token_name)
within first_token_row_for_name(token_name) do
accept_confirm do
click_element(:revoke_button)
end
end
end
end
end
end
end
......@@ -6,64 +6,7 @@ module QA
module Page
module Profile
class PersonalAccessTokens < Page::Base
view 'app/assets/javascripts/access_tokens/components/expires_at_field.vue' do
element :expiry_date_field
end
view 'app/views/shared/access_tokens/_form.html.haml' do
element :access_token_name_field
element :create_token_button
end
view 'app/views/shared/tokens/_scopes_form.html.haml' do
element :api_radio, 'qa-#{scope}-radio' # rubocop:disable QA/ElementWithPattern, Lint/InterpolationCheck
end
view 'app/views/shared/access_tokens/_created_container.html.haml' do
element :created_access_token
end
view 'app/views/shared/access_tokens/_table.html.haml' do
element :revoke_button
end
def fill_token_name(name)
fill_element(:access_token_name_field, name)
end
def check_api
check_element(:api_radio)
end
def click_create_token_button
click_element(:create_token_button)
end
def created_access_token
find_element(:created_access_token, wait: 30).value
end
def fill_expiry_date(date)
date = date.to_s if date.is_a?(Date)
Date.strptime(date, '%Y-%m-%d') rescue ArgumentError raise "Expiry date must be in YYYY-MM-DD format"
fill_element(:expiry_date_field, date)
end
def has_token_row_for_name?(token_name)
page.has_css?('tr', text: token_name, wait: 1.0)
end
def first_token_row_for_name(token_name)
page.find('tr', text: token_name, match: :first, wait: 1.0)
end
def revoke_first_token_with_name(token_name)
within first_token_row_for_name(token_name) do
accept_confirm do
click_element(:revoke_button)
end
end
end
include Page::Component::AccessTokens
end
end
end
......
# frozen_string_literal: true
require 'date'
module QA
module Page
module Project
module Settings
class AccessTokens < Page::Base
include Page::Component::AccessTokens
end
end
end
end
end
......@@ -18,6 +18,7 @@ module QA
element :general_settings_link
element :integrations_settings_link
element :operations_settings_link
element :access_tokens_settings_link
end
end
end
......@@ -68,6 +69,14 @@ module QA
end
end
def go_to_access_token_settings
hover_settings do
within_submenu do
click_element :access_tokens_settings_link
end
end
end
private
def hover_settings
......
# frozen_string_literal: true
require 'date'
module QA
module Resource
class ProjectAccessToken < Base
attr_writer :name
attribute :id
attribute :project do
Project.fabricate!
end
attribute :token do
Page::Project::Settings::AccessTokens.perform(&:created_access_token)
end
def fabricate_via_api!
super
end
def api_get_path
"/projects/#{project.api_resource[:id]}/access_tokens"
end
def api_post_path
api_get_path
end
def name
@name || 'api-project-access-token'
end
def api_post_body
{
name: name,
scopes: ["api"]
}
end
def api_delete_path
"projects/#{project.api_resource[:id]}/access_tokens/#{id}"
end
def resource_web_url(resource)
super
rescue ResourceURLMissingError
# this particular resource does not expose a web_url property
end
def revoke_via_ui!
Page::Project::Settings::AccessTokens.perform do |tokens_page|
tokens_page.revoke_first_token_with_name(name)
end
end
def fabricate!
Flow::Login.sign_in_unless_signed_in
project.visit!
Page::Project::Menu.perform(&:go_to_access_token_settings)
Page::Project::Settings::AccessTokens.perform do |token_page|
token_page.fill_token_name(name || 'api-project-access-token')
token_page.check_api
# Expire in 2 days just in case the token is created just before midnight
token_page.fill_expiry_date(Time.now.utc.to_date + 2)
token_page.click_create_token_button
end
end
end
end
end
# frozen_string_literal: true
module QA
RSpec.describe 'Manage' do
describe 'Project access token' do
before(:all) do
@project_access_token = QA::Resource::ProjectAccessToken.fabricate_via_api!
@user_api_client = Runtime::API::Client.new(:gitlab, personal_access_token: @project_access_token.token)
end
context 'for the same project' do
it 'can be used to create a file via the project API', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1734' do
expect do
Resource::File.fabricate_via_api! do |file|
file.api_client = @user_api_client
file.project = @project_access_token.project
file.branch = 'new_branch'
file.commit_message = 'Add new file'
file.name = "text-#{SecureRandom.hex(8)}.txt"
file.content = 'New file'
end
end.not_to raise_error
end
it 'can be used to commit via the API', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1735' do
expect do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.api_client = @user_api_client
commit.project = @project_access_token.project
commit.branch = 'new_branch'
commit.start_branch = @project_access_token.project.default_branch
commit.commit_message = 'Add new file'
commit.add_files([
{ file_path: "text-#{SecureRandom.hex(8)}.txt", content: 'new file' }
])
end
end.not_to raise_error
end
end
context 'for a different project' do
before(:all) do
@different_project = Resource::Project.fabricate!
end
it 'cannot be used to create a file via the project API', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1736' do
expect do
Resource::File.fabricate_via_api! do |file|
file.api_client = @user_api_client
file.project = @different_project
file.branch = 'new_branch'
file.commit_message = 'Add new file'
file.name = "text-#{SecureRandom.hex(8)}.txt"
file.content = 'New file'
end
end.to raise_error(Resource::ApiFabricator::ResourceFabricationFailedError, /403 Forbidden/)
end
it 'cannot be used to commit via the API', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1737' do
expect do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.api_client = @user_api_client
commit.project = @different_project
commit.branch = 'new_branch'
commit.start_branch = @different_project.default_branch
commit.commit_message = 'Add new file'
commit.add_files([
{ file_path: "text-#{SecureRandom.hex(8)}.txt", content: 'new file' }
])
end
end.to raise_error(Resource::ApiFabricator::ResourceFabricationFailedError, /403 Forbidden - You are not allowed to push into this branch/)
end
after(:all) do
@different_project.remove_via_api!
end
end
after(:all) do
@project_access_token.remove_via_api!
@project_access_token.project.remove_via_api!
end
end
end
end
# frozen_string_literal: true
module QA
RSpec.describe 'Manage' do
describe 'Project access tokens' do
let(:project_access_token) {QA::Resource::ProjectAccessToken.fabricate_via_browser_ui!}
it 'can be created and revoked via the UI' do
expect(project_access_token.token).not_to be_nil
project_access_token.revoke_via_ui!
expect(page).to have_text("Revoked project access token #{project_access_token.name}!")
end
after do
project_access_token.project.remove_via_api!
end
end
end
end
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