Skip to content
Snippets Groups Projects
Commit ca3aa6e0 authored by Dan Davison's avatar Dan Davison
Browse files

Merge branch 'e2e-ci-purchase-flow' into 'master'

Add e2e tests for purchasing CI minutes

See merge request !70734
parents 42d44783 82eb4da2
No related branches found
No related tags found
1 merge request!70734Add e2e tests for purchasing CI minutes
Pipeline #379642506 passed with warnings
Pipeline: CNG-mirror

#379646193

    ......@@ -18,6 +18,7 @@ module Subscriptions
    module Group
    module Settings
    autoload :Billing, 'gitlab/page/group/settings/billing'
    autoload :UsageQuotas, 'gitlab/page/group/settings/usage_quotas'
    end
    end
    end
    ......
    # frozen_string_literal: true
    module Gitlab
    module Page
    module Group
    module Settings
    module UsageQuota
    # @note Defined as +link :pipeline_tab+
    # Clicks +pipeline_tab+
    def pipeline_tab
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @example
    # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
    # expect(usage_quota.pipeline_tab_element).to exist
    # end
    # @return [Watir::Link] The raw +Link+ element
    def pipeline_tab_element
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @example
    # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
    # expect(usage_quota).to be_pipeline_tab
    # end
    # @return [Boolean] true if the +pipeline_tab+ element is present on the page
    def pipeline_tab?
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @note Defined as +link :storage_tab+
    # Clicks +storage_tab+
    def storage_tab
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @example
    # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
    # expect(usage_quota.storage_tab_element).to exist
    # end
    # @return [Watir::Link] The raw +Link+ element
    def storage_tab_element
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @example
    # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
    # expect(usage_quota).to be_storage_tab
    # end
    # @return [Boolean] true if the +storage_tab+ element is present on the page
    def storage_tab?
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @note Defined as +link :buy_ci_minutes+
    # Clicks +buy_ci_minutes+
    def buy_ci_minutes
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @example
    # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
    # expect(usage_quota.buy_ci_minutes_element).to exist
    # end
    # @return [Watir::Link] The raw +Link+ element
    def buy_ci_minutes_element
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @example
    # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
    # expect(usage_quota).to be_buy_ci_minutes
    # end
    # @return [Boolean] true if the +buy_ci_minutes+ element is present on the page
    def buy_ci_minutes?
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @note Defined as +link :buy_storage+
    # Clicks +buy_storage+
    def buy_storage
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @example
    # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
    # expect(usage_quota.buy_storage_element).to exist
    # end
    # @return [Watir::Link] The raw +Link+ element
    def buy_storage_element
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @example
    # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
    # expect(usage_quota).to be_buy_storage
    # end
    # @return [Boolean] true if the +buy_storage+ element is present on the page
    def buy_storage?
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @note Defined as +strong :additional_minutes+
    # @return [String] The text content or value of +additional_minutes+
    def additional_minutes
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @example
    # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
    # expect(usage_quota.additional_minutes_element).to exist
    # end
    # @return [Watir::Strong] The raw +Strong+ element
    def additional_minutes_element
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @example
    # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
    # expect(usage_quota).to be_additional_minutes
    # end
    # @return [Boolean] true if the +additional_minutes+ element is present on the page
    def additional_minutes?
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @note Defined as +div :additional_minutes_usage+
    # @return [String] The text content or value of +additional_minutes_usage+
    def additional_minutes_usage
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @example
    # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
    # expect(usage_quota.additional_minutes_usage_element).to exist
    # end
    # @return [Watir::Div] The raw +Div+ element
    def additional_minutes_usage_element
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @example
    # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
    # expect(usage_quota).to be_additional_minutes_usage
    # end
    # @return [Boolean] true if the +additional_minutes_usage+ element is present on the page
    def additional_minutes_usage?
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @note Defined as +strong :plan_minutes+
    # @return [String] The text content or value of +plan_minutes+
    def plan_minutes
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @example
    # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
    # expect(usage_quota.plan_minutes_element).to exist
    # end
    # @return [Watir::Strong] The raw +Strong+ element
    def plan_minutes_element
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @example
    # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
    # expect(usage_quota).to be_plan_minutes
    # end
    # @return [Boolean] true if the +plan_minutes+ element is present on the page
    def plan_minutes?
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @note Defined as +div :plan_minutes_usage+
    # @return [String] The text content or value of +plan_minutes_usage+
    def plan_minutes_usage
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @example
    # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
    # expect(usage_quota.plan_minutes_usage_element).to exist
    # end
    # @return [Watir::Div] The raw +Div+ element
    def plan_minutes_usage_element
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @example
    # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
    # expect(usage_quota).to be_plan_minutes_usage
    # end
    # @return [Boolean] true if the +plan_minutes_usage+ element is present on the page
    def plan_minutes_usage?
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @note Defined as +div :purchase_successful_alert+
    # @return [String] The text content or value of +purchase_successful_alert+
    def purchase_successful_alert
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @example
    # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
    # expect(usage_quota.purchase_successful_alert_element).to exist
    # end
    # @return [Watir::Div] The raw +Div+ element
    def purchase_successful_alert_element
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    # @example
    # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
    # expect(usage_quota).to be_purchase_successful_alert
    # end
    # @return [Boolean] true if the +purchase_successful_alert+ element is present on the page
    def purchase_successful_alert?
    # This is a stub, used for indexing. The method is dynamically generated.
    end
    end
    end
    end
    end
    end
    # frozen_string_literal: true
    module Gitlab
    module Page
    module Group
    module Settings
    class UsageQuotas < Chemlab::Page
    link :pipeline_tab, id: 'pipelines-quota'
    link :storage_tab, id: 'storage-quota'
    link :buy_ci_minutes, text: 'Buy additional minutes'
    link :buy_storage, text: /Purchase more storage/
    strong :additional_minutes, text: 'Additional minutes'
    div(:additional_minutes_usage) { additional_minutes_element.following_sibling.span }
    div :purchase_successful_alert, text: /You have successfully purchased CI minutes/
    def plan_minutes_limits
    plan_minutes_usage[%r{([^/ ]+)$}]
    end
    def additional_limits
    additional_minutes_usage[%r{([^/ ]+)$}]
    end
    # TODO: Refactor/Remove this method once https://gitlab.com/gitlab-org/quality/chemlab/-/merge_requests/28 is merged
    def additional_minutes_exist?
    has_element?(:strong, :additional_minutes, text: 'Additional minutes')
    end
    end
    end
    end
    end
    end
    ......@@ -6,10 +6,11 @@ module Subscriptions
    class New < Chemlab::Page
    path '/subscriptions/new'
    # Subscription Details
    # Purchase Details
    select :plan_name
    select :group_name
    text_field :number_of_users
    text_field :quantity
    button :continue_to_billing, text: /Continue to billing/
    # Billing address
    ......@@ -35,6 +36,10 @@ class New < Chemlab::Page
    # Confirmation
    button :confirm_purchase, text: /Confirm purchase/
    # Order Summary
    div :selected_plan, 'data-testid': 'selected-plan'
    div :order_total, 'data-testid': 'total-amount'
    end
    end
    end
    ......
    ......@@ -108,6 +108,14 @@ def go_to_billing
    end
    end
    def go_to_usage_quotas
    hover_group_settings do
    within_submenu do
    click_element(:sidebar_menu_item_link, menu_item: 'Usage Quotas')
    end
    end
    end
    private
    def hover_security_and_compliance
    ......
    # frozen_string_literal: true
    module QA
    RSpec.describe 'Fulfillment', :requires_admin, only: { subdomain: :staging } do
    context 'Purchase CI minutes' do
    # the quantity of products to purchase
    let(:purchase_quantity) { 5 }
    let(:hash) { SecureRandom.hex(4) }
    let(:user) do
    Resource::User.fabricate_via_api! do |user|
    user.email = "test-user-#{hash}@gitlab.com"
    user.api_client = Runtime::API::Client.as_admin
    user.hard_delete_on_api_removal = true
    end
    end
    let(:group) do
    Resource::Sandbox.fabricate_via_api! do |sandbox|
    sandbox.path = "gitlab-qa-group-#{hash}"
    sandbox.api_client = Runtime::API::Client.as_admin
    end
    end
    before do
    Runtime::Feature.enable(:top_level_group_creation_enabled)
    group.add_member(user, Resource::Members::AccessLevel::OWNER)
    # A group project is required for additional CI Minutes to show up
    Resource::Project.fabricate_via_api! do |project|
    project.name = 'ci-minutes'
    project.group = group
    project.initialize_with_readme = true
    project.api_client = Runtime::API::Client.as_admin
    end
    Flow::Login.sign_in(as: user)
    group.visit!
    end
    after do
    user.remove_via_api!
    Runtime::Feature.disable(:top_level_group_creation_enabled)
    end
    it 'adds additional minutes to group namespace', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/2660' do
    Page::Group::Menu.perform(&:go_to_usage_quotas)
    Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quota|
    usage_quota.pipeline_tab
    usage_quota.buy_ci_minutes
    end
    Gitlab::Page::Subscriptions::New.perform do |ci_minutes|
    ci_minutes.quantity = purchase_quantity
    ci_minutes.continue_to_billing
    ci_minutes.country = user_billing_info[:country]
    ci_minutes.street_address_1 = user_billing_info[:address_1]
    ci_minutes.street_address_2 = user_billing_info[:address_2]
    ci_minutes.city = user_billing_info[:city]
    ci_minutes.state = user_billing_info[:state]
    ci_minutes.zip_code = user_billing_info[:zip]
    ci_minutes.continue_to_payment
    ci_minutes.name_on_card = credit_card_info[:name]
    ci_minutes.card_number = credit_card_info[:number]
    ci_minutes.expiration_month = credit_card_info[:month]
    ci_minutes.expiration_year = credit_card_info[:year]
    ci_minutes.cvv = credit_card_info[:cvv]
    ci_minutes.review_your_order
    ci_minutes.confirm_purchase
    end
    Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quota|
    expected_minutes = ci_product[:minutes] * purchase_quantity
    expect(usage_quota.purchase_successful_alert?).to be true
    expect { usage_quota.additional_minutes_exist? }.to eventually_be_truthy.within(max_duration: 120, max_attempts: 60, reload_page: page)
    expect(usage_quota.additional_limits).to eq(expected_minutes.to_s)
    end
    end
    private
    # Hash presentation of CI minutes addon
    # @return [Hash] CI Minutes addon
    def ci_product
    {
    name: 'CI Minutes', # the name as it appears to purchase in GitLab
    price: 10, # unit price in USD
    minutes: 1000 # additional CI minutes per pack
    }.freeze
    end
    def credit_card_info
    {
    name: 'QA Test',
    number: '4111111111111111',
    month: '01',
    year: '2025',
    cvv: '232'
    }.freeze
    end
    def user_billing_info
    {
    country: 'United States of America',
    address_1: 'Address 1',
    address_2: 'Address 2',
    city: 'San Francisco',
    state: 'California',
    zip: '94102'
    }.freeze
    end
    end
    end
    end
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Finish editing this message first!
    Please register or to comment