Merge branch 'blackst0ne-remove-spinach' into 'master'
Remove Spinach Closes #23036 See merge request gitlab-org/gitlab-ce!18869
This commit is contained in:
commit
a78b1b27b8
290
.gitlab-ci.yml
290
.gitlab-ci.yml
|
|
@ -31,7 +31,6 @@ variables:
|
|||
GIT_SUBMODULE_STRATEGY: "none"
|
||||
GET_SOURCES_ATTEMPTS: "3"
|
||||
KNAPSACK_RSPEC_SUITE_REPORT_PATH: knapsack/${CI_PROJECT_NAME}/rspec_report-master.json
|
||||
KNAPSACK_SPINACH_SUITE_REPORT_PATH: knapsack/${CI_PROJECT_NAME}/spinach_report-master.json
|
||||
FLAKY_RSPEC_SUITE_REPORT_PATH: rspec_flaky/report-suite.json
|
||||
|
||||
before_script:
|
||||
|
|
@ -179,46 +178,6 @@ stages:
|
|||
<<: *rspec-metadata-mysql
|
||||
<<: *rails5
|
||||
|
||||
.spinach-metadata: &spinach-metadata
|
||||
<<: *dedicated-runner
|
||||
<<: *except-docs-and-qa
|
||||
<<: *pull-cache
|
||||
<<: *rails5-variables
|
||||
stage: test
|
||||
script:
|
||||
- JOB_NAME=( $CI_JOB_NAME )
|
||||
- export CI_NODE_INDEX=${JOB_NAME[-2]}
|
||||
- export CI_NODE_TOTAL=${JOB_NAME[-1]}
|
||||
- export KNAPSACK_REPORT_PATH=knapsack/${CI_PROJECT_NAME}/${JOB_NAME[0]}_node_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_report.json
|
||||
- export KNAPSACK_GENERATE_REPORT=true
|
||||
- export CACHE_CLASSES=true
|
||||
- cp ${KNAPSACK_SPINACH_SUITE_REPORT_PATH} ${KNAPSACK_REPORT_PATH}
|
||||
- scripts/gitaly-test-spawn
|
||||
- knapsack spinach "-r rerun" -b || retry '[[ -e tmp/spinach-rerun.txt ]] && bundle exec spinach -b -r rerun $(cat tmp/spinach-rerun.txt)'
|
||||
artifacts:
|
||||
expire_in: 31d
|
||||
when: always
|
||||
paths:
|
||||
- coverage/
|
||||
- knapsack/
|
||||
- tmp/capybara/
|
||||
|
||||
.spinach-metadata-pg: &spinach-metadata-pg
|
||||
<<: *spinach-metadata
|
||||
<<: *use-pg
|
||||
|
||||
.spinach-metadata-pg-rails5: &spinach-metadata-pg-rails5
|
||||
<<: *spinach-metadata-pg
|
||||
<<: *rails5
|
||||
|
||||
.spinach-metadata-mysql: &spinach-metadata-mysql
|
||||
<<: *spinach-metadata
|
||||
<<: *use-mysql
|
||||
|
||||
.spinach-metadata-mysql-rails5: &spinach-metadata-mysql-rails5
|
||||
<<: *spinach-metadata-mysql
|
||||
<<: *rails5
|
||||
|
||||
.only-canonical-masters: &only-canonical-masters
|
||||
only:
|
||||
- master@gitlab-org/gitlab-ce
|
||||
|
|
@ -350,9 +309,7 @@ retrieve-tests-metadata:
|
|||
script:
|
||||
- mkdir -p knapsack/${CI_PROJECT_NAME}/
|
||||
- wget -O $KNAPSACK_RSPEC_SUITE_REPORT_PATH http://${TESTS_METADATA_S3_BUCKET}.s3.amazonaws.com/$KNAPSACK_RSPEC_SUITE_REPORT_PATH || rm $KNAPSACK_RSPEC_SUITE_REPORT_PATH
|
||||
- wget -O $KNAPSACK_SPINACH_SUITE_REPORT_PATH http://${TESTS_METADATA_S3_BUCKET}.s3.amazonaws.com/$KNAPSACK_SPINACH_SUITE_REPORT_PATH || rm $KNAPSACK_SPINACH_SUITE_REPORT_PATH
|
||||
- '[[ -f $KNAPSACK_RSPEC_SUITE_REPORT_PATH ]] || echo "{}" > ${KNAPSACK_RSPEC_SUITE_REPORT_PATH}'
|
||||
- '[[ -f $KNAPSACK_SPINACH_SUITE_REPORT_PATH ]] || echo "{}" > ${KNAPSACK_SPINACH_SUITE_REPORT_PATH}'
|
||||
- mkdir -p rspec_flaky/
|
||||
- wget -O $FLAKY_RSPEC_SUITE_REPORT_PATH http://${TESTS_METADATA_S3_BUCKET}.s3.amazonaws.com/$FLAKY_RSPEC_SUITE_REPORT_PATH || rm $FLAKY_RSPEC_SUITE_REPORT_PATH
|
||||
- '[[ -f $FLAKY_RSPEC_SUITE_REPORT_PATH ]] || echo "{}" > ${FLAKY_RSPEC_SUITE_REPORT_PATH}'
|
||||
|
|
@ -370,10 +327,9 @@ update-tests-metadata:
|
|||
script:
|
||||
- retry gem install fog-aws mime-types activesupport
|
||||
- scripts/merge-reports ${KNAPSACK_RSPEC_SUITE_REPORT_PATH} knapsack/${CI_PROJECT_NAME}/rspec-pg_node_*.json
|
||||
- scripts/merge-reports ${KNAPSACK_SPINACH_SUITE_REPORT_PATH} knapsack/${CI_PROJECT_NAME}/spinach-pg_node_*.json
|
||||
- scripts/merge-reports ${FLAKY_RSPEC_SUITE_REPORT_PATH} rspec_flaky/all_*_*.json
|
||||
- FLAKY_RSPEC_GENERATE_REPORT=1 scripts/prune-old-flaky-specs ${FLAKY_RSPEC_SUITE_REPORT_PATH}
|
||||
- '[[ -z ${TESTS_METADATA_S3_BUCKET} ]] || scripts/sync-reports put $TESTS_METADATA_S3_BUCKET $KNAPSACK_RSPEC_SUITE_REPORT_PATH $KNAPSACK_SPINACH_SUITE_REPORT_PATH'
|
||||
- '[[ -z ${TESTS_METADATA_S3_BUCKET} ]] || scripts/sync-reports put $TESTS_METADATA_S3_BUCKET $KNAPSACK_RSPEC_SUITE_REPORT_PATH'
|
||||
- '[[ -z ${TESTS_METADATA_S3_BUCKET} ]] || scripts/sync-reports put $TESTS_METADATA_S3_BUCKET $FLAKY_RSPEC_SUITE_REPORT_PATH'
|
||||
- rm -f knapsack/${CI_PROJECT_NAME}/*_node_*.json
|
||||
- rm -f rspec_flaky/all_*.json rspec_flaky/new_*.json
|
||||
|
|
@ -441,133 +397,129 @@ setup-test-env:
|
|||
- config/secrets.yml
|
||||
- vendor/gitaly-ruby
|
||||
|
||||
rspec-pg 0 28: *rspec-metadata-pg
|
||||
rspec-pg 1 28: *rspec-metadata-pg
|
||||
rspec-pg 2 28: *rspec-metadata-pg
|
||||
rspec-pg 3 28: *rspec-metadata-pg
|
||||
rspec-pg 4 28: *rspec-metadata-pg
|
||||
rspec-pg 5 28: *rspec-metadata-pg
|
||||
rspec-pg 6 28: *rspec-metadata-pg
|
||||
rspec-pg 7 28: *rspec-metadata-pg
|
||||
rspec-pg 8 28: *rspec-metadata-pg
|
||||
rspec-pg 9 28: *rspec-metadata-pg
|
||||
rspec-pg 10 28: *rspec-metadata-pg
|
||||
rspec-pg 11 28: *rspec-metadata-pg
|
||||
rspec-pg 12 28: *rspec-metadata-pg
|
||||
rspec-pg 13 28: *rspec-metadata-pg
|
||||
rspec-pg 14 28: *rspec-metadata-pg
|
||||
rspec-pg 15 28: *rspec-metadata-pg
|
||||
rspec-pg 16 28: *rspec-metadata-pg
|
||||
rspec-pg 17 28: *rspec-metadata-pg
|
||||
rspec-pg 18 28: *rspec-metadata-pg
|
||||
rspec-pg 19 28: *rspec-metadata-pg
|
||||
rspec-pg 20 28: *rspec-metadata-pg
|
||||
rspec-pg 21 28: *rspec-metadata-pg
|
||||
rspec-pg 22 28: *rspec-metadata-pg
|
||||
rspec-pg 23 28: *rspec-metadata-pg
|
||||
rspec-pg 24 28: *rspec-metadata-pg
|
||||
rspec-pg 25 28: *rspec-metadata-pg
|
||||
rspec-pg 26 28: *rspec-metadata-pg
|
||||
rspec-pg 27 28: *rspec-metadata-pg
|
||||
rspec-pg 0 30: *rspec-metadata-pg
|
||||
rspec-pg 1 30: *rspec-metadata-pg
|
||||
rspec-pg 2 30: *rspec-metadata-pg
|
||||
rspec-pg 3 30: *rspec-metadata-pg
|
||||
rspec-pg 4 30: *rspec-metadata-pg
|
||||
rspec-pg 5 30: *rspec-metadata-pg
|
||||
rspec-pg 6 30: *rspec-metadata-pg
|
||||
rspec-pg 7 30: *rspec-metadata-pg
|
||||
rspec-pg 8 30: *rspec-metadata-pg
|
||||
rspec-pg 9 30: *rspec-metadata-pg
|
||||
rspec-pg 10 30: *rspec-metadata-pg
|
||||
rspec-pg 11 30: *rspec-metadata-pg
|
||||
rspec-pg 12 30: *rspec-metadata-pg
|
||||
rspec-pg 13 30: *rspec-metadata-pg
|
||||
rspec-pg 14 30: *rspec-metadata-pg
|
||||
rspec-pg 15 30: *rspec-metadata-pg
|
||||
rspec-pg 16 30: *rspec-metadata-pg
|
||||
rspec-pg 17 30: *rspec-metadata-pg
|
||||
rspec-pg 18 30: *rspec-metadata-pg
|
||||
rspec-pg 19 30: *rspec-metadata-pg
|
||||
rspec-pg 20 30: *rspec-metadata-pg
|
||||
rspec-pg 21 30: *rspec-metadata-pg
|
||||
rspec-pg 22 30: *rspec-metadata-pg
|
||||
rspec-pg 23 30: *rspec-metadata-pg
|
||||
rspec-pg 24 30: *rspec-metadata-pg
|
||||
rspec-pg 25 30: *rspec-metadata-pg
|
||||
rspec-pg 26 30: *rspec-metadata-pg
|
||||
rspec-pg 27 30: *rspec-metadata-pg
|
||||
rspec-pg 28 30: *rspec-metadata-pg
|
||||
rspec-pg 29 30: *rspec-metadata-pg
|
||||
|
||||
rspec-mysql 0 28: *rspec-metadata-mysql
|
||||
rspec-mysql 1 28: *rspec-metadata-mysql
|
||||
rspec-mysql 2 28: *rspec-metadata-mysql
|
||||
rspec-mysql 3 28: *rspec-metadata-mysql
|
||||
rspec-mysql 4 28: *rspec-metadata-mysql
|
||||
rspec-mysql 5 28: *rspec-metadata-mysql
|
||||
rspec-mysql 6 28: *rspec-metadata-mysql
|
||||
rspec-mysql 7 28: *rspec-metadata-mysql
|
||||
rspec-mysql 8 28: *rspec-metadata-mysql
|
||||
rspec-mysql 9 28: *rspec-metadata-mysql
|
||||
rspec-mysql 10 28: *rspec-metadata-mysql
|
||||
rspec-mysql 11 28: *rspec-metadata-mysql
|
||||
rspec-mysql 12 28: *rspec-metadata-mysql
|
||||
rspec-mysql 13 28: *rspec-metadata-mysql
|
||||
rspec-mysql 14 28: *rspec-metadata-mysql
|
||||
rspec-mysql 15 28: *rspec-metadata-mysql
|
||||
rspec-mysql 16 28: *rspec-metadata-mysql
|
||||
rspec-mysql 17 28: *rspec-metadata-mysql
|
||||
rspec-mysql 18 28: *rspec-metadata-mysql
|
||||
rspec-mysql 19 28: *rspec-metadata-mysql
|
||||
rspec-mysql 20 28: *rspec-metadata-mysql
|
||||
rspec-mysql 21 28: *rspec-metadata-mysql
|
||||
rspec-mysql 22 28: *rspec-metadata-mysql
|
||||
rspec-mysql 23 28: *rspec-metadata-mysql
|
||||
rspec-mysql 24 28: *rspec-metadata-mysql
|
||||
rspec-mysql 25 28: *rspec-metadata-mysql
|
||||
rspec-mysql 26 28: *rspec-metadata-mysql
|
||||
rspec-mysql 27 28: *rspec-metadata-mysql
|
||||
rspec-mysql 0 30: *rspec-metadata-mysql
|
||||
rspec-mysql 1 30: *rspec-metadata-mysql
|
||||
rspec-mysql 2 30: *rspec-metadata-mysql
|
||||
rspec-mysql 3 30: *rspec-metadata-mysql
|
||||
rspec-mysql 4 30: *rspec-metadata-mysql
|
||||
rspec-mysql 5 30: *rspec-metadata-mysql
|
||||
rspec-mysql 6 30: *rspec-metadata-mysql
|
||||
rspec-mysql 7 30: *rspec-metadata-mysql
|
||||
rspec-mysql 8 30: *rspec-metadata-mysql
|
||||
rspec-mysql 9 30: *rspec-metadata-mysql
|
||||
rspec-mysql 10 30: *rspec-metadata-mysql
|
||||
rspec-mysql 11 30: *rspec-metadata-mysql
|
||||
rspec-mysql 12 30: *rspec-metadata-mysql
|
||||
rspec-mysql 13 30: *rspec-metadata-mysql
|
||||
rspec-mysql 14 30: *rspec-metadata-mysql
|
||||
rspec-mysql 15 30: *rspec-metadata-mysql
|
||||
rspec-mysql 16 30: *rspec-metadata-mysql
|
||||
rspec-mysql 17 30: *rspec-metadata-mysql
|
||||
rspec-mysql 18 30: *rspec-metadata-mysql
|
||||
rspec-mysql 19 30: *rspec-metadata-mysql
|
||||
rspec-mysql 20 30: *rspec-metadata-mysql
|
||||
rspec-mysql 21 30: *rspec-metadata-mysql
|
||||
rspec-mysql 22 30: *rspec-metadata-mysql
|
||||
rspec-mysql 23 30: *rspec-metadata-mysql
|
||||
rspec-mysql 24 30: *rspec-metadata-mysql
|
||||
rspec-mysql 25 30: *rspec-metadata-mysql
|
||||
rspec-mysql 26 30: *rspec-metadata-mysql
|
||||
rspec-mysql 27 30: *rspec-metadata-mysql
|
||||
rspec-mysql 28 30: *rspec-metadata-mysql
|
||||
rspec-mysql 29 30: *rspec-metadata-mysql
|
||||
|
||||
spinach-pg 0 2: *spinach-metadata-pg
|
||||
spinach-pg 1 2: *spinach-metadata-pg
|
||||
rspec-pg-rails5 0 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 1 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 2 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 3 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 4 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 5 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 6 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 7 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 8 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 9 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 10 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 11 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 12 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 13 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 14 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 15 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 16 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 17 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 18 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 19 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 20 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 21 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 22 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 23 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 24 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 25 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 26 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 27 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 28 30: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 29 30: *rspec-metadata-pg-rails5
|
||||
|
||||
spinach-mysql 0 2: *spinach-metadata-mysql
|
||||
spinach-mysql 1 2: *spinach-metadata-mysql
|
||||
|
||||
rspec-pg-rails5 0 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 1 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 2 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 3 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 4 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 5 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 6 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 7 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 8 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 9 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 10 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 11 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 12 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 13 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 14 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 15 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 16 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 17 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 18 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 19 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 20 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 21 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 22 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 23 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 24 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 25 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 26 28: *rspec-metadata-pg-rails5
|
||||
rspec-pg-rails5 27 28: *rspec-metadata-pg-rails5
|
||||
|
||||
rspec-mysql-rails5 0 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 1 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 2 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 3 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 4 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 5 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 6 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 7 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 8 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 9 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 10 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 11 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 12 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 13 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 14 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 15 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 16 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 17 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 18 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 19 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 20 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 21 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 22 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 23 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 24 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 25 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 26 28: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 27 28: *rspec-metadata-mysql-rails5
|
||||
|
||||
spinach-pg-rails5 0 2: *spinach-metadata-pg-rails5
|
||||
spinach-pg-rails5 1 2: *spinach-metadata-pg-rails5
|
||||
|
||||
spinach-mysql-rails5 0 2: *spinach-metadata-mysql-rails5
|
||||
spinach-mysql-rails5 1 2: *spinach-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 0 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 1 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 2 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 3 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 4 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 5 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 6 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 7 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 8 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 9 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 10 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 11 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 12 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 13 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 14 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 15 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 16 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 17 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 18 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 19 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 20 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 21 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 22 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 23 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 24 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 25 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 26 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 27 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 28 30: *rspec-metadata-mysql-rails5
|
||||
rspec-mysql-rails5 29 30: *rspec-metadata-mysql-rails5
|
||||
|
||||
static-analysis:
|
||||
<<: *dedicated-no-docs-no-db-pull-cache-job
|
||||
|
|
|
|||
3
Gemfile
3
Gemfile
|
|
@ -325,8 +325,6 @@ group :development, :test do
|
|||
gem 'factory_bot_rails', '~> 4.8.2'
|
||||
gem 'rspec-rails', '~> 3.6.0'
|
||||
gem 'rspec-retry', '~> 0.4.5'
|
||||
gem 'spinach-rails', '~> 0.2.1'
|
||||
gem 'spinach-rerun-reporter', '~> 0.0.2'
|
||||
gem 'rspec_profiling', '~> 0.0.5'
|
||||
gem 'rspec-set', '~> 0.1.3'
|
||||
gem 'rspec-parameterized', require: false
|
||||
|
|
@ -343,7 +341,6 @@ group :development, :test do
|
|||
|
||||
gem 'spring', '~> 2.0.0'
|
||||
gem 'spring-commands-rspec', '~> 1.0.4'
|
||||
gem 'spring-commands-spinach', '~> 1.1.0'
|
||||
|
||||
gem 'gitlab-styles', '~> 2.3', require: false
|
||||
# Pin these dependencies, otherwise a new rule could break the CI pipelines
|
||||
|
|
|
|||
17
Gemfile.lock
17
Gemfile.lock
|
|
@ -131,7 +131,6 @@ GEM
|
|||
coderay (1.1.1)
|
||||
coercible (1.0.0)
|
||||
descendants_tracker (~> 0.0.1)
|
||||
colorize (0.7.7)
|
||||
commonmarker (0.17.8)
|
||||
ruby-enum (~> 0.5)
|
||||
concord (0.1.5)
|
||||
|
|
@ -288,7 +287,6 @@ GEM
|
|||
gettext_i18n_rails (>= 0.7.1)
|
||||
po_to_json (>= 1.0.0)
|
||||
rails (>= 3.2.0)
|
||||
gherkin-ruby (0.3.2)
|
||||
gitaly-proto (0.99.0)
|
||||
google-protobuf (~> 3.1)
|
||||
grpc (~> 1.10)
|
||||
|
|
@ -869,22 +867,10 @@ GEM
|
|||
simplecov-html (0.10.0)
|
||||
slack-notifier (1.5.1)
|
||||
slop (3.6.0)
|
||||
spinach (0.8.10)
|
||||
colorize
|
||||
gherkin-ruby (>= 0.3.2)
|
||||
json
|
||||
spinach-rails (0.2.1)
|
||||
capybara (>= 2.0.0)
|
||||
railties (>= 3)
|
||||
spinach (>= 0.4)
|
||||
spinach-rerun-reporter (0.0.2)
|
||||
spinach (~> 0.8)
|
||||
spring (2.0.1)
|
||||
activesupport (>= 4.2)
|
||||
spring-commands-rspec (1.0.4)
|
||||
spring (>= 0.9.1)
|
||||
spring-commands-spinach (1.1.0)
|
||||
spring (>= 0.9.1)
|
||||
sprockets (3.7.1)
|
||||
concurrent-ruby (~> 1.0)
|
||||
rack (> 1, < 3)
|
||||
|
|
@ -1183,11 +1169,8 @@ DEPENDENCIES
|
|||
simple_po_parser (~> 1.1.2)
|
||||
simplecov (~> 0.14.0)
|
||||
slack-notifier (~> 1.5.1)
|
||||
spinach-rails (~> 0.2.1)
|
||||
spinach-rerun-reporter (~> 0.0.2)
|
||||
spring (~> 2.0.0)
|
||||
spring-commands-rspec (~> 1.0.4)
|
||||
spring-commands-spinach (~> 1.1.0)
|
||||
sprockets (~> 3.7.0)
|
||||
sshkey (~> 1.9.0)
|
||||
stackprof (~> 0.2.10)
|
||||
|
|
|
|||
|
|
@ -132,7 +132,6 @@ GEM
|
|||
coderay (1.1.2)
|
||||
coercible (1.0.0)
|
||||
descendants_tracker (~> 0.0.1)
|
||||
colorize (0.8.1)
|
||||
commonmarker (0.17.9)
|
||||
ruby-enum (~> 0.5)
|
||||
concord (0.1.5)
|
||||
|
|
@ -289,7 +288,6 @@ GEM
|
|||
gettext_i18n_rails (>= 0.7.1)
|
||||
po_to_json (>= 1.0.0)
|
||||
rails (>= 3.2.0)
|
||||
gherkin-ruby (0.3.2)
|
||||
gitaly-proto (0.99.0)
|
||||
google-protobuf (~> 3.1)
|
||||
grpc (~> 1.10)
|
||||
|
|
@ -871,22 +869,10 @@ GEM
|
|||
simplecov-html (~> 0.10.0)
|
||||
simplecov-html (0.10.2)
|
||||
slack-notifier (1.5.1)
|
||||
spinach (0.8.10)
|
||||
colorize
|
||||
gherkin-ruby (>= 0.3.2)
|
||||
json
|
||||
spinach-rails (0.2.1)
|
||||
capybara (>= 2.0.0)
|
||||
railties (>= 3)
|
||||
spinach (>= 0.4)
|
||||
spinach-rerun-reporter (0.0.2)
|
||||
spinach (~> 0.8)
|
||||
spring (2.0.2)
|
||||
activesupport (>= 4.2)
|
||||
spring-commands-rspec (1.0.4)
|
||||
spring (>= 0.9.1)
|
||||
spring-commands-spinach (1.1.0)
|
||||
spring (>= 0.9.1)
|
||||
sprockets (3.7.1)
|
||||
concurrent-ruby (~> 1.0)
|
||||
rack (> 1, < 3)
|
||||
|
|
@ -1187,11 +1173,8 @@ DEPENDENCIES
|
|||
simple_po_parser (~> 1.1.2)
|
||||
simplecov (~> 0.14.0)
|
||||
slack-notifier (~> 1.5.1)
|
||||
spinach-rails (~> 0.2.1)
|
||||
spinach-rerun-reporter (~> 0.0.2)
|
||||
spring (~> 2.0.0)
|
||||
spring-commands-rspec (~> 1.0.4)
|
||||
spring-commands-spinach (~> 1.1.0)
|
||||
sprockets (~> 3.7.0)
|
||||
sshkey (~> 1.9.0)
|
||||
stackprof (~> 0.2.10)
|
||||
|
|
|
|||
|
|
@ -8,19 +8,6 @@ class Projects::NotesController < Projects::ApplicationController
|
|||
before_action :authorize_create_note!, only: [:create]
|
||||
before_action :authorize_resolve_note!, only: [:resolve, :unresolve]
|
||||
|
||||
#
|
||||
# This is a fix to make spinach feature tests passing:
|
||||
# Controller actions are returned from AbstractController::Base and methods of parent classes are
|
||||
# excluded in order to return only specific controller related methods.
|
||||
# That is ok for the app (no :create method in ancestors)
|
||||
# but fails for tests because there is a :create method on FactoryBot (one of the ancestors)
|
||||
#
|
||||
# see https://github.com/rails/rails/blob/v4.2.7/actionpack/lib/abstract_controller/base.rb#L78
|
||||
#
|
||||
def create
|
||||
super
|
||||
end
|
||||
|
||||
def delete_attachment
|
||||
note.remove_attachment!
|
||||
note.update_attribute(:attachment, nil)
|
||||
|
|
|
|||
13
bin/spinach
13
bin/spinach
|
|
@ -1,13 +0,0 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
# Remove this block when removing rails5? code.
|
||||
gemfile = %w[1 true].include?(ENV["RAILS5"]) ? "Gemfile.rails5" : "Gemfile"
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../#{gemfile}", __dir__)
|
||||
|
||||
begin
|
||||
load File.expand_path('../spring', __FILE__)
|
||||
rescue LoadError => e
|
||||
raise unless e.message.include?('spring')
|
||||
end
|
||||
require 'bundler/setup'
|
||||
load Gem.bin_path('spinach', 'spinach')
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Remove Spinach
|
||||
merge_request: 18869
|
||||
author: '@blackst0ne'
|
||||
type: other
|
||||
|
|
@ -82,7 +82,7 @@ Example of response
|
|||
"artifacts_file": null,
|
||||
"finished_at": "2015-12-24T17:54:24.921Z",
|
||||
"id": 6,
|
||||
"name": "spinach:other",
|
||||
"name": "rspec:other",
|
||||
"pipeline": {
|
||||
"id": 6,
|
||||
"ref": "master",
|
||||
|
|
@ -196,7 +196,7 @@ Example of response
|
|||
"artifacts_file": null,
|
||||
"finished_at": "2015-12-24T17:54:24.921Z",
|
||||
"id": 6,
|
||||
"name": "spinach:other",
|
||||
"name": "rspec:other",
|
||||
"pipeline": {
|
||||
"id": 6,
|
||||
"ref": "master",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ Available `RAILS_ENV`
|
|||
|
||||
- `production` (generally not for your main GDK db, but you may need this for e.g. omnibus)
|
||||
- `development` (this is your main GDK db)
|
||||
- `test` (used for tests like rspec and spinach)
|
||||
- `test` (used for tests like rspec)
|
||||
|
||||
|
||||
## Nuke everything and start over
|
||||
|
|
|
|||
|
|
@ -65,12 +65,11 @@ To make sure that indices still fit. You could find great details in:
|
|||
## Run tests
|
||||
|
||||
In order to run the test you can use the following commands:
|
||||
- `rake spinach` to run the spinach suite
|
||||
- `rake spec` to run the rspec suite
|
||||
- `rake karma` to run the karma test suite
|
||||
- `rake gitlab:test` to run all the tests
|
||||
|
||||
Note: Both `rake spinach` and `rake spec` takes significant time to pass.
|
||||
Note: `rake spec` takes significant time to pass.
|
||||
Instead of running full test suite locally you can save a lot of time by running
|
||||
a single test or directory related to your changes. After you submit merge request
|
||||
CI will run full test suite for you. Green CI status in the merge request means
|
||||
|
|
@ -82,12 +81,10 @@ files it can find, also the ones in `/tmp`
|
|||
To run a single test file you can use:
|
||||
|
||||
- `bin/rspec spec/controllers/commit_controller_spec.rb` for a rspec test
|
||||
- `bin/spinach features/project/issues/milestones.feature` for a spinach test
|
||||
|
||||
To run several tests inside one directory:
|
||||
|
||||
- `bin/rspec spec/requests/api/` for the rspec tests if you want to test API only
|
||||
- `bin/spinach features/profile/` for the spinach tests if you want to test only profile pages
|
||||
|
||||
### Speed-up tests, rake tasks, and migrations
|
||||
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@ Here are some things to keep in mind regarding test performance:
|
|||
- `FactoryBot.build(...)` and `.build_stubbed` are faster than `.create`.
|
||||
- Don't `create` an object when `build`, `build_stubbed`, `attributes_for`,
|
||||
`spy`, or `double` will do. Database persistence is slow!
|
||||
- Don't mark a feature as requiring JavaScript (through `@javascript` in
|
||||
Spinach or `:js` in RSpec) unless it's _actually_ required for the test
|
||||
- Don't mark a feature as requiring JavaScript (through `:js` in RSpec) unless it's _actually_ required for the test
|
||||
to be valid. Headless browser testing is slow!
|
||||
|
||||
[parallelization]: ci.md#test-suite-parallelization-on-the-ci
|
||||
|
|
|
|||
|
|
@ -24,8 +24,7 @@ Our current CI parallelization setup is as follows:
|
|||
uploaded to S3.
|
||||
|
||||
After that, the next pipeline will use the up-to-date
|
||||
`knapsack/${CI_PROJECT_NAME}/rspec_report-master.json` file. The same strategy
|
||||
is used for Spinach tests as well.
|
||||
`knapsack/${CI_PROJECT_NAME}/rspec_report-master.json` file.
|
||||
|
||||
### Monitoring
|
||||
|
||||
|
|
|
|||
|
|
@ -280,26 +280,6 @@ describe "Admin::AbuseReports", :js do
|
|||
end
|
||||
```
|
||||
|
||||
### Spinach errors due to missing JavaScript
|
||||
|
||||
NOTE: **Note:** Since we are discouraging the use of Spinach when writing new
|
||||
feature tests, you shouldn't ever need to use this. This information is kept
|
||||
available for legacy purposes only.
|
||||
|
||||
In Spinach, the JavaScript driver is enabled differently. In the `*.feature`
|
||||
file for the failing spec, add the `@javascript` flag above the Scenario:
|
||||
|
||||
```
|
||||
@javascript
|
||||
Scenario: Developer can approve merge request
|
||||
Given I am a "Shop" developer
|
||||
And I visit project "Shop" merge requests page
|
||||
And merge request 'Bug NS-04' must be approved
|
||||
And I click link "Bug NS-04"
|
||||
When I click link "Approve"
|
||||
Then I should see approved merge request "Bug NS-04"
|
||||
```
|
||||
|
||||
[jasmine-focus]: https://jasmine.github.io/2.5/focused_specs.html
|
||||
[jasmine-jquery]: https://github.com/velesin/jasmine-jquery
|
||||
[karma]: http://karma-runner.github.io/
|
||||
|
|
|
|||
|
|
@ -72,21 +72,6 @@ Everything you should know about how to run end-to-end tests using
|
|||
|
||||
---
|
||||
|
||||
## Spinach (feature) tests
|
||||
|
||||
GitLab [moved from Cucumber to Spinach](https://github.com/gitlabhq/gitlabhq/pull/1426)
|
||||
for its feature/integration tests in September 2012.
|
||||
|
||||
As of March 2016, we are [trying to avoid adding new Spinach
|
||||
tests](https://gitlab.com/gitlab-org/gitlab-ce/issues/14121) going forward,
|
||||
opting for [RSpec feature](#features-integration) specs.
|
||||
|
||||
Adding new Spinach scenarios is acceptable _only if_ the new scenario requires
|
||||
no more than one new `step` definition. If more than that is required, the
|
||||
test should be re-implemented using RSpec instead.
|
||||
|
||||
---
|
||||
|
||||
[Return to Development documentation](../README.md)
|
||||
|
||||
[^1]: /ci/yaml/README.html#dependencies
|
||||
|
|
|
|||
|
|
@ -81,7 +81,6 @@ possible).
|
|||
| Tests path | Testing engine | Notes |
|
||||
| ---------- | -------------- | ----- |
|
||||
| `spec/features/` | [Capybara] + [RSpec] | If your spec has the `:js` metadata, the browser driver will be [Poltergeist], otherwise it's using [RackTest]. |
|
||||
| `features/` | Spinach | Spinach tests are deprecated, [you shouldn't add new Spinach tests](#spinach-feature-tests). |
|
||||
|
||||
### Consider **not** writing a system test!
|
||||
|
||||
|
|
|
|||
|
|
@ -1,68 +0,0 @@
|
|||
class Spinach::Features::GroupMembers < Spinach::FeatureSteps
|
||||
include WaitForRequests
|
||||
include SharedAuthentication
|
||||
include SharedPaths
|
||||
include SharedGroup
|
||||
include SharedUser
|
||||
|
||||
step 'I should see user "John Doe" in team list' do
|
||||
expect(group_members_list).to have_content("John Doe")
|
||||
end
|
||||
|
||||
step 'I should not see user "Mary Jane" in team list' do
|
||||
expect(group_members_list).not_to have_content("Mary Jane")
|
||||
end
|
||||
|
||||
step 'I click on the "Remove User From Group" button for "John Doe"' do
|
||||
find(:css, '.project-members-page li', text: "John Doe").find(:css, 'a.btn-remove').click
|
||||
# poltergeist always confirms popups.
|
||||
end
|
||||
|
||||
step 'I click on the "Remove User From Group" button for "Mary Jane"' do
|
||||
find(:css, 'li', text: "Mary Jane").find(:css, 'a.btn-remove').click
|
||||
# poltergeist always confirms popups.
|
||||
end
|
||||
|
||||
step 'I should not see the "Remove User From Group" button for "John Doe"' do
|
||||
expect(find(:css, '.project-members-page li', text: "John Doe")).not_to have_selector(:css, 'a.btn-remove')
|
||||
# poltergeist always confirms popups.
|
||||
end
|
||||
|
||||
step 'I should not see the "Remove User From Group" button for "Mary Jane"' do
|
||||
expect(find(:css, 'li', text: "Mary Jane")).not_to have_selector(:css, 'a.btn-remove')
|
||||
# poltergeist always confirms popups.
|
||||
end
|
||||
|
||||
step 'I change the "Mary Jane" role to "Developer"' do
|
||||
member = mary_jane_member
|
||||
|
||||
page.within "#group_member_#{member.id}" do
|
||||
click_button member.human_access
|
||||
|
||||
page.within '.dropdown-menu' do
|
||||
click_link 'Developer'
|
||||
end
|
||||
|
||||
wait_for_requests
|
||||
end
|
||||
end
|
||||
|
||||
step 'I should see "Mary Jane" as "Developer"' do
|
||||
member = mary_jane_member
|
||||
|
||||
page.within "#group_member_#{member.id}" do
|
||||
expect(page).to have_content "Developer"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def mary_jane_member
|
||||
user = User.find_by(name: "Mary Jane")
|
||||
owned_group.members.find_by(user_id: user.id)
|
||||
end
|
||||
|
||||
def group_members_list
|
||||
find(".panel .content-list")
|
||||
end
|
||||
end
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
class Spinach::Features::ProfileNotifications < Spinach::FeatureSteps
|
||||
include SharedAuthentication
|
||||
include SharedProject
|
||||
|
||||
step 'I visit profile notifications page' do
|
||||
visit profile_notifications_path
|
||||
end
|
||||
|
||||
step 'I should see global notifications settings' do
|
||||
expect(page).to have_content "Notifications"
|
||||
end
|
||||
|
||||
step 'I select Mention setting from dropdown' do
|
||||
first(:link, "On mention").click
|
||||
end
|
||||
|
||||
step 'I should see Notification saved message' do
|
||||
expect(page).to have_content 'On mention'
|
||||
end
|
||||
end
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
class Spinach::Features::ProjectCommitsBranches < Spinach::FeatureSteps
|
||||
include SharedAuthentication
|
||||
include SharedProject
|
||||
include SharedPaths
|
||||
|
||||
step 'I click link "All"' do
|
||||
click_link "All"
|
||||
end
|
||||
|
||||
step 'I click link "Protected"' do
|
||||
click_link "Protected"
|
||||
end
|
||||
|
||||
step 'I click new branch link' do
|
||||
click_link "New branch"
|
||||
end
|
||||
|
||||
step 'I submit new branch form with invalid name' do
|
||||
fill_in 'branch_name', with: '1.0 stable'
|
||||
page.find("body").click # defocus the branch_name input
|
||||
select_branch('master')
|
||||
click_button 'Create branch'
|
||||
end
|
||||
|
||||
def select_branch(branch_name)
|
||||
find('.git-revision-dropdown-toggle').click
|
||||
|
||||
page.within '#new-branch-form .dropdown-menu' do
|
||||
click_link branch_name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
class Spinach::Features::ProjectCommitsComments < Spinach::FeatureSteps
|
||||
include SharedAuthentication
|
||||
include SharedNote
|
||||
include SharedPaths
|
||||
include SharedProject
|
||||
end
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
class Spinach::Features::ProjectCommitsDiffComments < Spinach::FeatureSteps
|
||||
include SharedAuthentication
|
||||
include SharedDiffNote
|
||||
include SharedPaths
|
||||
include SharedProject
|
||||
end
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
class Spinach::Features::ProjectCreate < Spinach::FeatureSteps
|
||||
include SharedAuthentication
|
||||
include SharedPaths
|
||||
include SharedUser
|
||||
|
||||
step 'fill project form with valid data' do
|
||||
fill_in 'project_path', with: 'Empty'
|
||||
page.within '#content-body' do
|
||||
click_button "Create project"
|
||||
end
|
||||
end
|
||||
|
||||
step 'I should see project page' do
|
||||
expect(page).to have_content "Empty"
|
||||
expect(current_path).to eq project_path(Project.last)
|
||||
end
|
||||
|
||||
step 'I should see empty project instructions' do
|
||||
expect(page).to have_content "git init"
|
||||
expect(page).to have_content "git remote"
|
||||
expect(page).to have_content Project.last.url_to_repo
|
||||
end
|
||||
end
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
class Spinach::Features::ProjectIssuesFilterLabels < Spinach::FeatureSteps
|
||||
include SharedAuthentication
|
||||
include SharedProject
|
||||
include SharedPaths
|
||||
include Select2Helper
|
||||
|
||||
step 'I should see "Bugfix1" in issues list' do
|
||||
page.within ".issues-list" do
|
||||
expect(page).to have_content "Bugfix1"
|
||||
end
|
||||
end
|
||||
|
||||
step 'I should see "Bugfix2" in issues list' do
|
||||
page.within ".issues-list" do
|
||||
expect(page).to have_content "Bugfix2"
|
||||
end
|
||||
end
|
||||
|
||||
step 'I should not see "Bugfix2" in issues list' do
|
||||
page.within ".issues-list" do
|
||||
expect(page).not_to have_content "Bugfix2"
|
||||
end
|
||||
end
|
||||
|
||||
step 'I should not see "Feature1" in issues list' do
|
||||
page.within ".issues-list" do
|
||||
expect(page).not_to have_content "Feature1"
|
||||
end
|
||||
end
|
||||
|
||||
step 'I click "dropdown close button"' do
|
||||
page.first('.labels-filter .dropdown-title .dropdown-menu-close-icon').click
|
||||
sleep 2
|
||||
end
|
||||
|
||||
step 'I click link "feature"' do
|
||||
page.within ".labels-filter" do
|
||||
click_link "feature"
|
||||
end
|
||||
end
|
||||
|
||||
step 'project "Shop" has issue "Bugfix1" with labels: "bug", "feature"' do
|
||||
project = Project.find_by(name: "Shop")
|
||||
issue = create(:issue, title: "Bugfix1", project: project)
|
||||
issue.labels << project.labels.find_by(title: 'bug')
|
||||
issue.labels << project.labels.find_by(title: 'feature')
|
||||
end
|
||||
|
||||
step 'project "Shop" has issue "Bugfix2" with labels: "bug", "enhancement"' do
|
||||
project = Project.find_by(name: "Shop")
|
||||
issue = create(:issue, title: "Bugfix2", project: project)
|
||||
issue.labels << project.labels.find_by(title: 'bug')
|
||||
issue.labels << project.labels.find_by(title: 'enhancement')
|
||||
end
|
||||
|
||||
step 'project "Shop" has issue "Feature1" with labels: "feature"' do
|
||||
project = Project.find_by(name: "Shop")
|
||||
issue = create(:issue, title: "Feature1", project: project)
|
||||
issue.labels << project.labels.find_by(title: 'feature')
|
||||
end
|
||||
end
|
||||
|
|
@ -1,175 +0,0 @@
|
|||
class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
|
||||
include SharedAuthentication
|
||||
include SharedIssuable
|
||||
include SharedProject
|
||||
include SharedNote
|
||||
include SharedPaths
|
||||
include SharedMarkdown
|
||||
include SharedUser
|
||||
|
||||
step 'I should not see "Release 0.3" in issues' do
|
||||
expect(page).not_to have_content "Release 0.3"
|
||||
end
|
||||
|
||||
step 'I click link "Closed"' do
|
||||
find('.issues-state-filters [data-state="closed"] span', text: 'Closed').click
|
||||
end
|
||||
|
||||
step 'I should see "Release 0.3" in issues' do
|
||||
expect(page).to have_content "Release 0.3"
|
||||
end
|
||||
|
||||
step 'I should not see "Release 0.4" in issues' do
|
||||
expect(page).not_to have_content "Release 0.4"
|
||||
end
|
||||
|
||||
step 'I click link "All"' do
|
||||
find('.issues-state-filters [data-state="all"] span', text: 'All').click
|
||||
# Waits for load
|
||||
expect(find('.issues-state-filters > .active')).to have_content 'All'
|
||||
end
|
||||
|
||||
step 'I should see issue "Tweet control"' do
|
||||
expect(page).to have_content "Tweet control"
|
||||
end
|
||||
|
||||
step 'I click "author" dropdown' do
|
||||
page.find('.js-author-search').click
|
||||
sleep 1
|
||||
end
|
||||
|
||||
step 'I see current user as the first user' do
|
||||
expect(page).to have_selector('.dropdown-content', visible: true)
|
||||
users = page.all('.dropdown-menu-author .dropdown-content li a')
|
||||
expect(users[0].text).to eq 'Any Author'
|
||||
expect(users[1].text).to eq "#{current_user.name} #{current_user.to_reference}"
|
||||
end
|
||||
|
||||
step 'I click link "500 error on profile"' do
|
||||
click_link "500 error on profile"
|
||||
end
|
||||
|
||||
step 'I should see label \'bug\' with issue' do
|
||||
page.within '.issuable-show-labels' do
|
||||
expect(page).to have_content 'bug'
|
||||
end
|
||||
end
|
||||
|
||||
step 'I fill in issue search with "Re"' do
|
||||
filter_issue "Re"
|
||||
end
|
||||
|
||||
step 'I fill in issue search with "Bu"' do
|
||||
filter_issue "Bu"
|
||||
end
|
||||
|
||||
step 'I fill in issue search with ".3"' do
|
||||
filter_issue ".3"
|
||||
end
|
||||
|
||||
step 'I fill in issue search with "Something"' do
|
||||
filter_issue "Something"
|
||||
end
|
||||
|
||||
step 'I fill in issue search with ""' do
|
||||
filter_issue ""
|
||||
end
|
||||
|
||||
step 'project "Shop" has milestone "v2.2"' do
|
||||
milestone = create(:milestone, title: "v2.2", project: project)
|
||||
|
||||
3.times { create(:issue, project: project, milestone: milestone) }
|
||||
end
|
||||
|
||||
step 'project "Shop" has milestone "v3.0"' do
|
||||
milestone = create(:milestone, title: "v3.0", project: project)
|
||||
|
||||
3.times { create(:issue, project: project, milestone: milestone) }
|
||||
end
|
||||
|
||||
When 'I select milestone "v3.0"' do
|
||||
select "v3.0", from: "milestone_id"
|
||||
end
|
||||
|
||||
step 'I should see selected milestone with title "v3.0"' do
|
||||
issues_milestone_selector = "#issue_milestone_id_chzn > a"
|
||||
expect(find(issues_milestone_selector)).to have_content("v3.0")
|
||||
end
|
||||
|
||||
When 'I select first assignee from "Shop" project' do
|
||||
first_assignee = project.users.first
|
||||
select first_assignee.name, from: "assignee_id"
|
||||
end
|
||||
|
||||
step 'I should see first assignee from "Shop" as selected assignee' do
|
||||
issues_assignee_selector = "#issue_assignee_id_chzn > a"
|
||||
|
||||
assignee_name = project.users.first.name
|
||||
expect(find(issues_assignee_selector)).to have_content(assignee_name)
|
||||
end
|
||||
|
||||
step 'The list should be sorted by "Least popular"' do
|
||||
page.within '.issues-list' do
|
||||
page.within 'li.issue:nth-child(1)' do
|
||||
expect(page).to have_content 'Tweet control'
|
||||
expect(page).to have_content '1 2'
|
||||
end
|
||||
|
||||
page.within 'li.issue:nth-child(2)' do
|
||||
expect(page).to have_content 'Release 0.4'
|
||||
expect(page).to have_content '2 1'
|
||||
end
|
||||
|
||||
page.within 'li.issue:nth-child(3)' do
|
||||
expect(page).to have_content 'Bugfix'
|
||||
expect(page).not_to have_content '0 0'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
When 'I visit empty project page' do
|
||||
project = Project.find_by(name: 'Empty Project')
|
||||
visit project_path(project)
|
||||
end
|
||||
|
||||
When "I visit project \"Community\" issues page" do
|
||||
project = Project.find_by(name: 'Community')
|
||||
visit project_issues_path(project)
|
||||
end
|
||||
|
||||
step 'project \'Shop\' has issue \'Bugfix1\' with description: \'Description for issue1\'' do
|
||||
create(:issue, title: 'Bugfix1', description: 'Description for issue1', project: project)
|
||||
end
|
||||
|
||||
step 'project \'Shop\' has issue \'Feature1\' with description: \'Feature submitted for issue1\'' do
|
||||
create(:issue, title: 'Feature1', description: 'Feature submitted for issue1', project: project)
|
||||
end
|
||||
|
||||
step 'I fill in issue search with \'Description for issue1\'' do
|
||||
filter_issue 'Description for issue'
|
||||
end
|
||||
|
||||
step 'I fill in issue search with \'issue1\'' do
|
||||
filter_issue 'issue1'
|
||||
end
|
||||
|
||||
step 'I fill in issue search with \'Rock and roll\'' do
|
||||
filter_issue 'Rock and roll'
|
||||
end
|
||||
|
||||
step 'I should see \'Bugfix1\' in issues' do
|
||||
expect(page).to have_content 'Bugfix1'
|
||||
end
|
||||
|
||||
step 'I should see \'Feature1\' in issues' do
|
||||
expect(page).to have_content 'Feature1'
|
||||
end
|
||||
|
||||
step 'I should not see \'Bugfix1\' in issues' do
|
||||
expect(page).not_to have_content 'Bugfix1'
|
||||
end
|
||||
|
||||
def filter_issue(text)
|
||||
fill_in 'issuable_search', with: text
|
||||
end
|
||||
end
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps
|
||||
include SharedAuthentication
|
||||
include SharedProject
|
||||
include SharedPaths
|
||||
include SharedMarkdown
|
||||
|
||||
step 'project "Shop" has milestone "v2.2"' do
|
||||
project = Project.find_by(name: "Shop")
|
||||
milestone = create(:milestone,
|
||||
title: "v2.2",
|
||||
project: project,
|
||||
description: "# Description header"
|
||||
)
|
||||
3.times { create(:issue, project: project, milestone: milestone) }
|
||||
end
|
||||
|
||||
When 'I click link "All Issues"' do
|
||||
click_link 'All Issues'
|
||||
end
|
||||
end
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
class Spinach::Features::ProjectIssuesReferences < Spinach::FeatureSteps
|
||||
include SharedAuthentication
|
||||
include SharedIssuable
|
||||
include SharedNote
|
||||
include SharedProject
|
||||
include SharedUser
|
||||
end
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
class Spinach::Features::ProjectMergeRequestsReferences < Spinach::FeatureSteps
|
||||
include SharedAuthentication
|
||||
include SharedIssuable
|
||||
include SharedNote
|
||||
include SharedProject
|
||||
include SharedUser
|
||||
end
|
||||
|
|
@ -1,435 +0,0 @@
|
|||
# coding: utf-8
|
||||
class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
|
||||
include SharedAuthentication
|
||||
include SharedProject
|
||||
include SharedPaths
|
||||
include RepoHelpers
|
||||
include WaitForRequests
|
||||
|
||||
step "I don't have write access" do
|
||||
@project = create(:project, :repository, name: "Other Project", path: "other-project")
|
||||
@project.add_reporter(@user)
|
||||
visit project_tree_path(@project, root_ref)
|
||||
end
|
||||
|
||||
step 'I should see files from repository' do
|
||||
expect(page).to have_content "VERSION"
|
||||
expect(page).to have_content ".gitignore"
|
||||
expect(page).to have_content "LICENSE"
|
||||
end
|
||||
|
||||
step 'I should see files from repository for "6d39438"' do
|
||||
expect(current_path).to eq project_tree_path(@project, "6d39438")
|
||||
expect(page).to have_content ".gitignore"
|
||||
expect(page).to have_content "LICENSE"
|
||||
end
|
||||
|
||||
step 'I see the ".gitignore"' do
|
||||
expect(page).to have_content '.gitignore'
|
||||
end
|
||||
|
||||
step 'I don\'t see the ".gitignore"' do
|
||||
expect(page).not_to have_content '.gitignore'
|
||||
end
|
||||
|
||||
step 'I click on ".gitignore" file in repo' do
|
||||
click_link ".gitignore"
|
||||
end
|
||||
|
||||
step 'I should see its content' do
|
||||
wait_for_requests
|
||||
expect(page).to have_content old_gitignore_content
|
||||
end
|
||||
|
||||
step 'I should see its new content' do
|
||||
wait_for_requests
|
||||
expect(page).to have_content new_gitignore_content
|
||||
end
|
||||
|
||||
step 'I click link "Raw"' do
|
||||
click_link 'Open raw'
|
||||
end
|
||||
|
||||
step 'I should see raw file content' do
|
||||
expect(source).to eq '' # Body is filled in by gitlab-workhorse
|
||||
end
|
||||
|
||||
step 'I click button "Edit"' do
|
||||
find('.js-edit-blob').click
|
||||
end
|
||||
|
||||
step 'I cannot see the edit button' do
|
||||
expect(page).not_to have_link 'edit'
|
||||
end
|
||||
|
||||
step 'I click button "Fork"' do
|
||||
click_link 'Fork'
|
||||
end
|
||||
|
||||
step 'I edit code' do
|
||||
expect(page).to have_selector('.file-editor')
|
||||
set_new_content
|
||||
end
|
||||
|
||||
step 'I fill the new file name' do
|
||||
fill_in :file_name, with: new_file_name
|
||||
end
|
||||
|
||||
step 'I fill the new branch name' do
|
||||
fill_in :branch_name, with: 'new_branch_name', visible: true
|
||||
end
|
||||
|
||||
step 'I fill the new file name with a new directory' do
|
||||
fill_in :file_name, with: new_file_name_with_directory
|
||||
end
|
||||
|
||||
step 'I fill the commit message' do
|
||||
fill_in :commit_message, with: 'New commit message', visible: true
|
||||
end
|
||||
|
||||
step 'I click link "Diff"' do
|
||||
click_link 'Preview changes'
|
||||
end
|
||||
|
||||
step 'I click on "Commit changes"' do
|
||||
click_button 'Commit changes'
|
||||
end
|
||||
|
||||
step 'I click on "Changes" tab' do
|
||||
click_link 'Changes'
|
||||
end
|
||||
|
||||
step 'I click on "Create directory"' do
|
||||
click_button 'Create directory'
|
||||
end
|
||||
|
||||
step 'I click on "Delete"' do
|
||||
click_on 'Delete'
|
||||
end
|
||||
|
||||
step 'I click on "Delete file"' do
|
||||
click_button 'Delete file'
|
||||
end
|
||||
|
||||
step 'I click on "Replace"' do
|
||||
click_on "Replace"
|
||||
end
|
||||
|
||||
step 'I click on "Replace file"' do
|
||||
click_button 'Replace file'
|
||||
end
|
||||
|
||||
step 'I see diff' do
|
||||
expect(page).to have_css '.line_holder.new'
|
||||
end
|
||||
|
||||
step 'I click on "New file" link in repo' do
|
||||
find('.add-to-tree').click
|
||||
click_link 'New file'
|
||||
expect(page).to have_selector('.file-editor')
|
||||
end
|
||||
|
||||
step 'I click on "Upload file" link in repo' do
|
||||
find('.add-to-tree').click
|
||||
click_link 'Upload file'
|
||||
end
|
||||
|
||||
step 'I click on "New directory" link in repo' do
|
||||
find('.add-to-tree').click
|
||||
click_link 'New directory'
|
||||
end
|
||||
|
||||
step 'I fill the new directory name' do
|
||||
fill_in :dir_name, with: new_dir_name
|
||||
end
|
||||
|
||||
step 'I fill an existing directory name' do
|
||||
fill_in :dir_name, with: 'files'
|
||||
end
|
||||
|
||||
step 'I can see new file page' do
|
||||
expect(page).to have_content "New File"
|
||||
expect(page).to have_content "Commit message"
|
||||
end
|
||||
|
||||
step 'I click on "Upload file"' do
|
||||
click_button 'Upload file'
|
||||
end
|
||||
|
||||
step 'I can see the new commit message' do
|
||||
expect(page).to have_content "New commit message"
|
||||
end
|
||||
|
||||
step 'I upload a new text file' do
|
||||
drop_in_dropzone test_text_file
|
||||
end
|
||||
|
||||
step 'I fill the upload file commit message' do
|
||||
page.within('#modal-upload-blob') do
|
||||
fill_in :commit_message, with: 'New commit message'
|
||||
end
|
||||
end
|
||||
|
||||
step 'I replace it with a text file' do
|
||||
drop_in_dropzone test_text_file
|
||||
end
|
||||
|
||||
step 'I fill the replace file commit message' do
|
||||
page.within('#modal-upload-blob') do
|
||||
fill_in :commit_message, with: 'Replacement file commit message'
|
||||
end
|
||||
end
|
||||
|
||||
step 'I can see the replacement commit message' do
|
||||
expect(page).to have_content "Replacement file commit message"
|
||||
end
|
||||
|
||||
step 'I can see the new text file' do
|
||||
expect(page).to have_content "Lorem ipsum dolor sit amet"
|
||||
expect(page).to have_content "Sed ut perspiciatis unde omnis"
|
||||
end
|
||||
|
||||
step 'I click on files directory' do
|
||||
click_link 'files'
|
||||
end
|
||||
|
||||
step 'I click on History link' do
|
||||
click_link 'History'
|
||||
end
|
||||
|
||||
step 'I see Browse dir link' do
|
||||
expect(page).to have_link 'Browse Directory'
|
||||
expect(page).not_to have_link 'Browse Code'
|
||||
end
|
||||
|
||||
step 'I click on readme file' do
|
||||
page.within '.tree-table' do
|
||||
click_link 'README.md'
|
||||
end
|
||||
end
|
||||
|
||||
step 'I see Browse file link' do
|
||||
expect(page).to have_link 'Browse File'
|
||||
expect(page).not_to have_link 'Browse Files'
|
||||
end
|
||||
|
||||
step 'I see Browse code link' do
|
||||
expect(page).to have_link 'Browse Files'
|
||||
expect(page).not_to have_link 'Browse Directory'
|
||||
end
|
||||
|
||||
step 'I click on Permalink' do
|
||||
click_link 'Permalink'
|
||||
end
|
||||
|
||||
step 'I am redirected to the files URL' do
|
||||
expect(current_path).to eq project_tree_path(@project, 'master')
|
||||
end
|
||||
|
||||
step 'I am redirected to the ".gitignore"' do
|
||||
expect(current_path).to eq(project_blob_path(@project, 'master/.gitignore'))
|
||||
end
|
||||
|
||||
step 'I am redirected to the permalink URL' do
|
||||
expect(current_path).to(
|
||||
eq(project_blob_path(@project,
|
||||
@project.repository.commit.sha +
|
||||
'/.gitignore'))
|
||||
)
|
||||
end
|
||||
|
||||
step 'I am redirected to the new file' do
|
||||
expect(current_path).to eq(
|
||||
project_blob_path(@project, 'master/' + new_file_name))
|
||||
end
|
||||
|
||||
step 'I am redirected to the new file with directory' do
|
||||
expect(current_path).to eq(
|
||||
project_blob_path(@project, 'master/' + new_file_name_with_directory))
|
||||
end
|
||||
|
||||
step 'I am redirected to the new merge request page' do
|
||||
expect(current_path).to eq(project_new_merge_request_path(@project))
|
||||
end
|
||||
|
||||
step "I am redirected to the fork's new merge request page" do
|
||||
fork = @user.fork_of(@project)
|
||||
expect(current_path).to eq(project_new_merge_request_path(fork))
|
||||
end
|
||||
|
||||
step 'I am redirected to the root directory' do
|
||||
expect(current_path).to eq(
|
||||
project_tree_path(@project, 'master'))
|
||||
end
|
||||
|
||||
step "I don't see the permalink link" do
|
||||
expect(page).not_to have_link('permalink')
|
||||
end
|
||||
|
||||
step 'I see "Unable to create directory"' do
|
||||
expect(page).to have_content('A directory with this name already exists')
|
||||
end
|
||||
|
||||
step 'I see "Path can contain only..."' do
|
||||
expect(page).to have_content('Path can contain only')
|
||||
end
|
||||
|
||||
step 'I see a commit error message' do
|
||||
expect(page).to have_content('Your changes could not be committed')
|
||||
end
|
||||
|
||||
step "I switch ref to 'test'" do
|
||||
first('.js-project-refs-dropdown').click
|
||||
|
||||
page.within '.project-refs-form' do
|
||||
click_link "'test'"
|
||||
end
|
||||
end
|
||||
|
||||
step "I switch ref to fix" do
|
||||
first('.js-project-refs-dropdown').click
|
||||
|
||||
page.within '.project-refs-form' do
|
||||
click_link 'fix'
|
||||
end
|
||||
end
|
||||
|
||||
step "I see the ref 'test' has been selected" do
|
||||
expect(page).to have_selector '.dropdown-toggle-text', text: "'test'"
|
||||
end
|
||||
|
||||
step "I visit the 'test' tree" do
|
||||
visit project_tree_path(@project, "'test'")
|
||||
end
|
||||
|
||||
step "I visit the fix tree" do
|
||||
visit project_tree_path(@project, "fix/.testdir")
|
||||
end
|
||||
|
||||
step 'I see the commit data' do
|
||||
expect(page).to have_css('.tree-commit-link', visible: true)
|
||||
expect(page).not_to have_content('Loading commit data...')
|
||||
end
|
||||
|
||||
step 'I see the commit data for a directory with a leading dot' do
|
||||
expect(page).to have_css('.tree-commit-link', visible: true)
|
||||
expect(page).not_to have_content('Loading commit data...')
|
||||
end
|
||||
|
||||
step 'I click on "files/lfs/lfs_object.iso" file in repo' do
|
||||
allow_any_instance_of(Project).to receive(:lfs_enabled?).and_return(true)
|
||||
visit project_tree_path(@project, "lfs")
|
||||
click_link 'files'
|
||||
click_link "lfs"
|
||||
click_link "lfs_object.iso"
|
||||
end
|
||||
|
||||
step 'I should see download link and object size' do
|
||||
expect(page).to have_content 'Download (1.5 MB)'
|
||||
end
|
||||
|
||||
step 'I should not see lfs pointer details' do
|
||||
expect(page).not_to have_content 'version https://git-lfs.github.com/spec/v1'
|
||||
expect(page).not_to have_content 'oid sha256:91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897'
|
||||
expect(page).not_to have_content 'size 1575078'
|
||||
end
|
||||
|
||||
step 'I should see buttons for allowed commands' do
|
||||
page.within '.content' do
|
||||
expect(page).to have_link 'Download'
|
||||
expect(page).to have_content 'History'
|
||||
expect(page).to have_content 'Permalink'
|
||||
expect(page).not_to have_content 'Edit'
|
||||
expect(page).not_to have_content 'Blame'
|
||||
expect(page).to have_content 'Delete'
|
||||
expect(page).to have_content 'Replace'
|
||||
end
|
||||
end
|
||||
|
||||
step 'I should see a Fork/Cancel combo' do
|
||||
expect(page).to have_link 'Fork'
|
||||
expect(page).to have_button 'Cancel'
|
||||
end
|
||||
|
||||
step 'I should see a notice about a new fork having been created' do
|
||||
expect(page).to have_content "You're not allowed to make changes to this project directly. A fork of this project has been created that you can make changes in, so you can submit a merge request."
|
||||
end
|
||||
|
||||
# SVG files
|
||||
step 'I upload a new SVG file' do
|
||||
drop_in_dropzone test_svg_file
|
||||
end
|
||||
|
||||
step 'I visit the SVG file' do
|
||||
visit project_blob_path(@project, 'new_branch_name/logo_sample.svg')
|
||||
end
|
||||
|
||||
step 'I can see the new rendered SVG image' do
|
||||
expect(page).to have_css('.file-content img')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_new_content
|
||||
find('#editor')
|
||||
execute_script("ace.edit('editor').setValue('#{new_gitignore_content}')")
|
||||
end
|
||||
|
||||
# Content of the gitignore file on the seed repository.
|
||||
def old_gitignore_content
|
||||
'*.rbc'
|
||||
end
|
||||
|
||||
# Constant value that differs from the content
|
||||
# of the gitignore of the seed repository.
|
||||
def new_gitignore_content
|
||||
old_gitignore_content + 'a'
|
||||
end
|
||||
|
||||
# Constant value that is a valid filename and
|
||||
# not a filename present at root of the seed repository.
|
||||
def new_file_name
|
||||
'not_a_file.md'
|
||||
end
|
||||
|
||||
# Constant value that is a valid filename with directory and
|
||||
# not a filename present at root of the seed repository.
|
||||
def new_file_name_with_directory
|
||||
'foo/bar/baz.txt'
|
||||
end
|
||||
|
||||
# Constant value that is a valid directory and
|
||||
# not a directory present at root of the seed repository.
|
||||
def new_dir_name
|
||||
'new_dir/subdir'
|
||||
end
|
||||
|
||||
def drop_in_dropzone(file_path)
|
||||
# Generate a fake input selector
|
||||
page.execute_script <<-JS
|
||||
var fakeFileInput = window.$('<input/>').attr(
|
||||
{id: 'fakeFileInput', type: 'file'}
|
||||
).appendTo('body');
|
||||
JS
|
||||
# Attach the file to the fake input selector with Capybara
|
||||
attach_file("fakeFileInput", file_path)
|
||||
# Add the file to a fileList array and trigger the fake drop event
|
||||
page.execute_script <<-JS
|
||||
var fileList = [$('#fakeFileInput')[0].files[0]];
|
||||
var e = jQuery.Event('drop', { dataTransfer : { files : fileList } });
|
||||
$('.dropzone')[0].dropzone.listeners[0].events.drop(e);
|
||||
JS
|
||||
end
|
||||
|
||||
def test_text_file
|
||||
File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt')
|
||||
end
|
||||
|
||||
def test_image_file
|
||||
File.join(Rails.root, 'spec', 'fixtures', 'banana_sample.gif')
|
||||
end
|
||||
|
||||
def test_svg_file
|
||||
File.join(Rails.root, 'spec', 'fixtures', 'logo_sample.svg')
|
||||
end
|
||||
end
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
module SharedActiveTab
|
||||
include Spinach::DSL
|
||||
include WaitForRequests
|
||||
|
||||
after do
|
||||
wait_for_requests if javascript_test?
|
||||
end
|
||||
|
||||
def ensure_active_main_tab(content)
|
||||
expect(find('.sidebar-top-level-items > li.active')).to have_content(content)
|
||||
end
|
||||
|
||||
def ensure_active_sub_tab(content)
|
||||
expect(find('.sidebar-sub-level-items > li.active:not(.fly-out-top-item)')).to have_content(content)
|
||||
end
|
||||
|
||||
def ensure_active_sub_nav(content)
|
||||
expect(find('.layout-nav .controls li.active')).to have_content(content)
|
||||
end
|
||||
|
||||
step 'no other main tabs should be active' do
|
||||
expect(page).to have_selector('.sidebar-top-level-items > li.active', count: 1)
|
||||
end
|
||||
|
||||
step 'no other sub tabs should be active' do
|
||||
expect(page).to have_selector('.sidebar-sub-level-items > li.active:not(.fly-out-top-item)', count: 1)
|
||||
end
|
||||
|
||||
step 'no other sub navs should be active' do
|
||||
expect(page).to have_selector('.layout-nav .controls li.active', count: 1)
|
||||
end
|
||||
end
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
module SharedAdmin
|
||||
include Spinach::DSL
|
||||
|
||||
step 'there are projects in system' do
|
||||
2.times { create(:project, :repository) }
|
||||
end
|
||||
|
||||
step 'system has users' do
|
||||
2.times { create(:user) }
|
||||
end
|
||||
end
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
require Rails.root.join('features', 'support', 'login_helpers')
|
||||
|
||||
module SharedAuthentication
|
||||
include Spinach::DSL
|
||||
include LoginHelpers
|
||||
|
||||
step 'I sign in as a user' do
|
||||
sign_out(@user) if @user
|
||||
|
||||
@user = create(:user)
|
||||
sign_in(@user)
|
||||
end
|
||||
|
||||
step 'I sign in via the UI' do
|
||||
gitlab_sign_in(create(:user))
|
||||
end
|
||||
|
||||
step 'I should be redirected to sign in page' do
|
||||
expect(current_path).to eq new_user_session_path
|
||||
end
|
||||
|
||||
step "I logout directly" do
|
||||
gitlab_sign_out
|
||||
end
|
||||
|
||||
def current_user
|
||||
@user || User.reorder(nil).first
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def gitlab_sign_in(user)
|
||||
visit new_user_session_path
|
||||
|
||||
fill_in "user_login", with: user.email
|
||||
fill_in "user_password", with: "12345678"
|
||||
check 'user_remember_me'
|
||||
click_button "Sign in"
|
||||
|
||||
@user = user
|
||||
end
|
||||
|
||||
def gitlab_sign_out
|
||||
return unless @user
|
||||
|
||||
if Capybara.current_driver == Capybara.javascript_driver
|
||||
find('.header-user-dropdown-toggle').click
|
||||
click_link 'Sign out'
|
||||
expect(page).to have_button('Sign in')
|
||||
else
|
||||
sign_out(@user)
|
||||
end
|
||||
|
||||
@user = nil
|
||||
end
|
||||
end
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
module SharedDiffNote
|
||||
include Spinach::DSL
|
||||
include RepoHelpers
|
||||
include WaitForRequests
|
||||
|
||||
after do
|
||||
wait_for_requests if javascript_test?
|
||||
end
|
||||
|
||||
step 'I delete a diff comment' do
|
||||
find('.note').hover
|
||||
find(".js-note-delete").click
|
||||
end
|
||||
|
||||
step 'I haven\'t written any diff comment text' do
|
||||
page.within(diff_file_selector) do
|
||||
fill_in "note[note]", with: ""
|
||||
end
|
||||
end
|
||||
|
||||
step 'The diff comment preview tab should say there is nothing to do' do
|
||||
page.within(diff_file_selector) do
|
||||
find('.js-md-preview-button').click
|
||||
expect(find('.js-md-preview')).to have_content('Nothing to preview.')
|
||||
end
|
||||
end
|
||||
|
||||
step 'I see side-by-side diff button' do
|
||||
expect(page).to have_content "Side-by-side"
|
||||
end
|
||||
|
||||
def diff_file_selector
|
||||
'.diff-file:nth-of-type(1)'
|
||||
end
|
||||
|
||||
def click_diff_line(code)
|
||||
find(".line_holder[id='#{code}'] button").click
|
||||
end
|
||||
|
||||
def click_parallel_diff_line(code, line_type)
|
||||
find(".line_holder.parallel td[id='#{code}']").find(:xpath, 'preceding-sibling::*[1][self::td]').hover
|
||||
find(".line_holder.parallel button[data-line-code='#{code}']").click
|
||||
end
|
||||
end
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
module SharedGroup
|
||||
include Spinach::DSL
|
||||
|
||||
step 'current user is developer of group "Owned"' do
|
||||
is_member_of(current_user.name, "Owned", Gitlab::Access::DEVELOPER)
|
||||
end
|
||||
|
||||
step '"John Doe" is guest of group "Guest"' do
|
||||
is_member_of("John Doe", "Guest", Gitlab::Access::GUEST)
|
||||
end
|
||||
|
||||
step '"Mary Jane" is owner of group "Owned"' do
|
||||
is_member_of("Mary Jane", "Owned", Gitlab::Access::OWNER)
|
||||
end
|
||||
|
||||
step '"Mary Jane" is guest of group "Owned"' do
|
||||
is_member_of("Mary Jane", "Owned", Gitlab::Access::GUEST)
|
||||
end
|
||||
|
||||
step '"Mary Jane" is guest of group "Guest"' do
|
||||
is_member_of("Mary Jane", "Guest", Gitlab::Access::GUEST)
|
||||
end
|
||||
|
||||
step 'I should see group "TestGroup"' do
|
||||
expect(page).to have_content "TestGroup"
|
||||
end
|
||||
|
||||
step 'I should not see group "TestGroup"' do
|
||||
expect(page).not_to have_content "TestGroup"
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def is_member_of(username, groupname, role)
|
||||
user = User.find_by(name: username) || create(:user, name: username)
|
||||
group = Group.find_by(name: groupname) || create(:group, name: groupname)
|
||||
group.add_user(user, role)
|
||||
project ||= create(:project, :repository, namespace: group)
|
||||
create(:closed_issue_event, project: project)
|
||||
project.add_master(user)
|
||||
end
|
||||
|
||||
def owned_group
|
||||
@owned_group ||= Group.find_by(name: "Owned")
|
||||
end
|
||||
end
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
module SharedIssuable
|
||||
include Spinach::DSL
|
||||
|
||||
def edit_issuable
|
||||
find('.js-issuable-edit', visible: true).click
|
||||
end
|
||||
|
||||
step 'I leave a comment referencing issue "Community issue"' do
|
||||
leave_reference_comment(
|
||||
issuable: Issue.find_by(title: 'Community issue'),
|
||||
from_project_name: 'Enterprise'
|
||||
)
|
||||
end
|
||||
|
||||
step 'I click link "Edit" for the merge request' do
|
||||
edit_issuable
|
||||
end
|
||||
|
||||
step 'I sort the list by "Least popular"' do
|
||||
find('button.dropdown-toggle').click
|
||||
|
||||
page.within('.content ul.dropdown-menu.dropdown-menu-align-right li') do
|
||||
click_link 'Least popular'
|
||||
end
|
||||
end
|
||||
|
||||
step 'I click link "Next" in the sidebar' do
|
||||
page.within '.issuable-sidebar' do
|
||||
click_link 'Next'
|
||||
end
|
||||
end
|
||||
|
||||
def create_issuable_for_project(project_name:, title:, type: :issue)
|
||||
project = Project.find_by(name: project_name)
|
||||
|
||||
attrs = {
|
||||
title: title,
|
||||
author: project.users.first,
|
||||
description: '# Description header'
|
||||
}
|
||||
|
||||
case type
|
||||
when :issue
|
||||
attrs[:project] = project
|
||||
when :merge_request
|
||||
attrs.merge!(
|
||||
source_project: project,
|
||||
target_project: project,
|
||||
source_branch: 'fix',
|
||||
target_branch: 'master'
|
||||
)
|
||||
end
|
||||
|
||||
create(type, attrs)
|
||||
end
|
||||
|
||||
def leave_reference_comment(issuable:, from_project_name:)
|
||||
project = Project.find_by(name: from_project_name)
|
||||
|
||||
page.within('.js-main-target-form') do
|
||||
fill_in 'note[note]', with: "##{issuable.to_reference(project)}"
|
||||
click_button 'Comment'
|
||||
end
|
||||
end
|
||||
|
||||
def visible_note(issuable:, from_project_name:, user_name:)
|
||||
project = Project.find_by(name: from_project_name)
|
||||
|
||||
expect(page).to have_content(user_name)
|
||||
expect(page).to have_content("mentioned in #{issuable.class.to_s.titleize.downcase} #{issuable.to_reference(project)}")
|
||||
end
|
||||
|
||||
def expect_sidebar_content(content)
|
||||
page.within '.issuable-sidebar' do
|
||||
expect(page).to have_content content
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
module SharedMarkdown
|
||||
include Spinach::DSL
|
||||
|
||||
step 'I should not see the Markdown preview' do
|
||||
expect(find('.gfm-form .js-md-preview')).not_to be_visible
|
||||
end
|
||||
|
||||
step 'I haven\'t written any description text' do
|
||||
find('.gfm-form').fill_in 'Description', with: ''
|
||||
end
|
||||
end
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
module SharedNote
|
||||
include Spinach::DSL
|
||||
include WaitForRequests
|
||||
|
||||
after do
|
||||
wait_for_requests if javascript_test?
|
||||
end
|
||||
|
||||
step 'I haven\'t written any comment text' do
|
||||
page.within(".js-main-target-form") do
|
||||
fill_in "note[note]", with: ""
|
||||
end
|
||||
end
|
||||
|
||||
step 'The comment preview tab should say there is nothing to do' do
|
||||
page.within(".js-main-target-form") do
|
||||
find('.js-md-preview-button').click
|
||||
expect(find('.js-md-preview')).to have_content('Nothing to preview.')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,413 +0,0 @@
|
|||
module SharedPaths
|
||||
include Spinach::DSL
|
||||
include RepoHelpers
|
||||
include DashboardHelper
|
||||
include WaitForRequests
|
||||
|
||||
step 'I visit new project page' do
|
||||
visit new_project_path
|
||||
end
|
||||
|
||||
step 'I visit login page' do
|
||||
visit new_user_session_path
|
||||
end
|
||||
|
||||
# ----------------------------------------
|
||||
# User
|
||||
# ----------------------------------------
|
||||
|
||||
step 'I visit user "John Doe" page' do
|
||||
visit user_path("john_doe")
|
||||
end
|
||||
|
||||
# ----------------------------------------
|
||||
# Group
|
||||
# ----------------------------------------
|
||||
|
||||
step 'I visit group "Owned" page' do
|
||||
visit group_path(Group.find_by(name: "Owned"))
|
||||
end
|
||||
|
||||
step 'I visit group "Owned" activity page' do
|
||||
visit activity_group_path(Group.find_by(name: "Owned"))
|
||||
end
|
||||
|
||||
step 'I visit group "Owned" issues page' do
|
||||
visit issues_group_path(Group.find_by(name: "Owned"))
|
||||
end
|
||||
|
||||
step 'I visit group "Owned" merge requests page' do
|
||||
visit merge_requests_group_path(Group.find_by(name: "Owned"))
|
||||
end
|
||||
|
||||
step 'I visit group "Owned" milestones page' do
|
||||
visit group_milestones_path(Group.find_by(name: "Owned"))
|
||||
end
|
||||
|
||||
step 'I visit group "Owned" members page' do
|
||||
visit group_group_members_path(Group.find_by(name: "Owned"))
|
||||
end
|
||||
|
||||
step 'I visit group "Owned" projects page' do
|
||||
visit projects_group_path(Group.find_by(name: "Owned"))
|
||||
end
|
||||
|
||||
step 'I visit group "Guest" page' do
|
||||
visit group_path(Group.find_by(name: "Guest"))
|
||||
end
|
||||
|
||||
step 'I visit group "Guest" issues page' do
|
||||
visit issues_group_path(Group.find_by(name: "Guest"))
|
||||
end
|
||||
|
||||
step 'I visit group "Guest" merge requests page' do
|
||||
visit merge_requests_group_path(Group.find_by(name: "Guest"))
|
||||
end
|
||||
|
||||
step 'I visit group "Guest" members page' do
|
||||
visit group_group_members_path(Group.find_by(name: "Guest"))
|
||||
end
|
||||
|
||||
step 'I visit group "Guest" settings page' do
|
||||
visit edit_group_path(Group.find_by(name: "Guest"))
|
||||
end
|
||||
|
||||
# ----------------------------------------
|
||||
# Dashboard
|
||||
# ----------------------------------------
|
||||
|
||||
step 'I visit dashboard page' do
|
||||
visit dashboard_projects_path
|
||||
end
|
||||
|
||||
step 'I visit dashboard activity page' do
|
||||
visit activity_dashboard_path
|
||||
end
|
||||
|
||||
step 'I visit dashboard projects page' do
|
||||
visit projects_dashboard_path
|
||||
end
|
||||
|
||||
step 'I visit dashboard issues page' do
|
||||
visit assigned_issues_dashboard_path
|
||||
end
|
||||
|
||||
step 'I visit dashboard search page' do
|
||||
visit search_path
|
||||
end
|
||||
|
||||
step 'I visit dashboard help page' do
|
||||
visit help_path
|
||||
end
|
||||
|
||||
step 'I visit dashboard groups page' do
|
||||
visit dashboard_groups_path
|
||||
end
|
||||
|
||||
step 'I should be redirected to the dashboard groups page' do
|
||||
expect(current_path).to eq dashboard_groups_path
|
||||
end
|
||||
|
||||
step 'I visit dashboard starred projects page' do
|
||||
visit starred_dashboard_projects_path
|
||||
end
|
||||
|
||||
# ----------------------------------------
|
||||
# Profile
|
||||
# ----------------------------------------
|
||||
|
||||
step 'I visit profile page' do
|
||||
visit profile_path
|
||||
end
|
||||
|
||||
step 'I visit profile applications page' do
|
||||
visit applications_profile_path
|
||||
end
|
||||
|
||||
step 'I visit profile password page' do
|
||||
visit edit_profile_password_path
|
||||
end
|
||||
|
||||
step 'I visit profile account page' do
|
||||
visit profile_account_path
|
||||
end
|
||||
|
||||
step 'I visit profile SSH keys page' do
|
||||
visit profile_keys_path
|
||||
end
|
||||
|
||||
step 'I visit profile preferences page' do
|
||||
visit profile_preferences_path
|
||||
end
|
||||
|
||||
step 'I visit Authentication log page' do
|
||||
visit audit_log_profile_path
|
||||
end
|
||||
|
||||
# ----------------------------------------
|
||||
# Admin
|
||||
# ----------------------------------------
|
||||
|
||||
step 'I visit admin page' do
|
||||
visit admin_root_path
|
||||
end
|
||||
|
||||
step 'I visit abuse reports page' do
|
||||
visit admin_abuse_reports_path
|
||||
end
|
||||
|
||||
step 'I visit admin projects page' do
|
||||
visit admin_projects_path
|
||||
end
|
||||
|
||||
step 'I visit admin users page' do
|
||||
visit admin_users_path
|
||||
end
|
||||
|
||||
step 'I visit admin logs page' do
|
||||
visit admin_logs_path
|
||||
end
|
||||
|
||||
step 'I visit admin messages page' do
|
||||
visit admin_broadcast_messages_path
|
||||
end
|
||||
|
||||
step 'I visit admin hooks page' do
|
||||
visit admin_hooks_path
|
||||
end
|
||||
|
||||
step 'I visit admin Resque page' do
|
||||
visit admin_background_jobs_path
|
||||
end
|
||||
|
||||
step 'I visit admin teams page' do
|
||||
visit admin_teams_path
|
||||
end
|
||||
|
||||
step 'I visit spam logs page' do
|
||||
visit admin_spam_logs_path
|
||||
end
|
||||
|
||||
# ----------------------------------------
|
||||
# Generic Project
|
||||
# ----------------------------------------
|
||||
|
||||
step "I visit my project's settings page" do
|
||||
visit edit_project_path(@project)
|
||||
end
|
||||
|
||||
step 'I visit a binary file in the repo' do
|
||||
visit project_blob_path(@project,
|
||||
File.join(root_ref, 'files/images/logo-black.png'))
|
||||
end
|
||||
|
||||
step "I visit my project's commits page" do
|
||||
visit project_commits_path(@project, root_ref, { limit: 5 })
|
||||
end
|
||||
|
||||
step "I visit my project's commits page for a specific path" do
|
||||
visit project_commits_path(@project, root_ref + "/files/ruby/regex.rb", { limit: 5 })
|
||||
end
|
||||
|
||||
step 'I visit my project\'s commits stats page' do
|
||||
visit stats_project_repository_path(@project)
|
||||
end
|
||||
|
||||
step "I visit my project's graph page" do
|
||||
# Stub Graph max_size to speed up test (10 commits vs. 650)
|
||||
Network::Graph.stub(max_count: 10)
|
||||
|
||||
visit project_network_path(@project, root_ref)
|
||||
end
|
||||
|
||||
step "I visit my project's issues page" do
|
||||
visit project_issues_path(@project)
|
||||
end
|
||||
|
||||
step "I visit my project's merge requests page" do
|
||||
visit project_merge_requests_path(@project)
|
||||
end
|
||||
|
||||
step "I visit my project's members page" do
|
||||
visit project_project_members_path(@project)
|
||||
end
|
||||
|
||||
step "I visit my project's wiki page" do
|
||||
visit project_wiki_path(@project, :home)
|
||||
end
|
||||
|
||||
step 'I visit project hooks page' do
|
||||
visit project_settings_integrations_path(@project)
|
||||
end
|
||||
|
||||
step 'I visit project find file page' do
|
||||
visit project_find_file_path(@project, root_ref)
|
||||
end
|
||||
|
||||
# ----------------------------------------
|
||||
# "Shop" Project
|
||||
# ----------------------------------------
|
||||
|
||||
step 'I visit project "Shop" page' do
|
||||
visit project_path(project)
|
||||
end
|
||||
|
||||
step 'I visit edit project "Shop" page' do
|
||||
visit edit_project_path(project)
|
||||
end
|
||||
|
||||
step 'I visit compare refs page' do
|
||||
visit project_compare_index_path(@project)
|
||||
end
|
||||
|
||||
step 'I visit project commits page' do
|
||||
visit project_commits_path(@project, root_ref, { limit: 5 })
|
||||
end
|
||||
|
||||
step 'I visit project commits page for stable branch' do
|
||||
visit project_commits_path(@project, 'stable', { limit: 5 })
|
||||
end
|
||||
|
||||
step 'I visit blob file from repo' do
|
||||
visit project_blob_path(@project, File.join(sample_commit.id, sample_blob.path))
|
||||
end
|
||||
|
||||
step 'I visit ".gitignore" file in repo' do
|
||||
visit project_blob_path(@project, File.join(root_ref, '.gitignore'))
|
||||
end
|
||||
|
||||
step 'I am on the new file page' do
|
||||
expect(current_path).to eq(project_create_blob_path(@project, root_ref))
|
||||
end
|
||||
|
||||
step 'I am on the ".gitignore" edit file page' do
|
||||
expect(current_path).to eq(
|
||||
project_edit_blob_path(@project, File.join(root_ref, '.gitignore')))
|
||||
end
|
||||
|
||||
step 'I visit project source page for "6d39438"' do
|
||||
visit project_tree_path(@project, "6d39438")
|
||||
end
|
||||
|
||||
step 'I visit project source page for' \
|
||||
' "6d394385cf567f80a8fd85055db1ab4c5295806f"' do
|
||||
visit project_tree_path(@project,
|
||||
'6d394385cf567f80a8fd85055db1ab4c5295806f')
|
||||
end
|
||||
|
||||
step 'I visit project tags page' do
|
||||
visit project_tags_path(@project)
|
||||
end
|
||||
|
||||
step 'I visit issue page "Release 0.4"' do
|
||||
issue = Issue.find_by(title: "Release 0.4")
|
||||
visit project_issue_path(issue.project, issue)
|
||||
end
|
||||
|
||||
step 'I visit project "Forum" labels page' do
|
||||
project = Project.find_by(name: 'Forum')
|
||||
visit project_labels_path(project)
|
||||
end
|
||||
|
||||
step 'I visit project "Shop" new label page' do
|
||||
project = Project.find_by(name: 'Shop')
|
||||
visit new_project_label_path(project)
|
||||
end
|
||||
|
||||
step 'I visit project "Forum" new label page' do
|
||||
project = Project.find_by(name: 'Forum')
|
||||
visit new_project_label_path(project)
|
||||
end
|
||||
|
||||
step 'I visit merge request page "Bug NS-04"' do
|
||||
visit merge_request_path("Bug NS-04")
|
||||
wait_for_requests
|
||||
end
|
||||
|
||||
step 'I visit merge request page "Bug NS-07"' do
|
||||
visit merge_request_path("Bug NS-07")
|
||||
wait_for_requests
|
||||
end
|
||||
|
||||
step 'I visit merge request page "Bug NS-08"' do
|
||||
visit merge_request_path("Bug NS-08")
|
||||
wait_for_requests
|
||||
end
|
||||
|
||||
step 'I visit merge request page "Bug CO-01"' do
|
||||
mr = MergeRequest.find_by(title: "Bug CO-01")
|
||||
visit project_merge_request_path(mr.target_project, mr)
|
||||
wait_for_requests
|
||||
end
|
||||
|
||||
step 'I visit forked project "Shop" merge requests page' do
|
||||
visit project_merge_requests_path(project)
|
||||
end
|
||||
|
||||
step 'I visit project "Shop" team page' do
|
||||
visit project_project_members_path(project)
|
||||
end
|
||||
|
||||
step 'I visit project wiki page' do
|
||||
visit project_wiki_path(@project, :home)
|
||||
end
|
||||
|
||||
# ----------------------------------------
|
||||
# Visibility Projects
|
||||
# ----------------------------------------
|
||||
|
||||
step 'I visit project "Community" source page' do
|
||||
project = Project.find_by(name: 'Community')
|
||||
visit project_tree_path(project, root_ref)
|
||||
end
|
||||
|
||||
step 'I visit project "Internal" page' do
|
||||
project = Project.find_by(name: "Internal")
|
||||
visit project_path(project)
|
||||
end
|
||||
|
||||
step 'I visit project "Enterprise" page' do
|
||||
project = Project.find_by(name: "Enterprise")
|
||||
visit project_path(project)
|
||||
end
|
||||
|
||||
# ----------------------------------------
|
||||
# Empty Projects
|
||||
# ----------------------------------------
|
||||
|
||||
step "I should not see command line instructions" do
|
||||
expect(page).not_to have_css('.empty_wrapper')
|
||||
end
|
||||
|
||||
# ----------------------------------------
|
||||
# Public Projects
|
||||
# ----------------------------------------
|
||||
step 'I visit the public groups area' do
|
||||
visit explore_groups_path
|
||||
end
|
||||
|
||||
# ----------------------------------------
|
||||
# Snippets
|
||||
# ----------------------------------------
|
||||
|
||||
step 'I visit project "Shop" snippets page' do
|
||||
visit project_snippets_path(project)
|
||||
end
|
||||
|
||||
step 'I visit snippets page' do
|
||||
visit explore_snippets_path
|
||||
end
|
||||
|
||||
def root_ref
|
||||
@project.repository.root_ref
|
||||
end
|
||||
|
||||
def project
|
||||
Project.find_by!(name: 'Shop')
|
||||
end
|
||||
|
||||
def merge_request_path(title)
|
||||
mr = MergeRequest.find_by(title: title)
|
||||
project_merge_request_path(mr.target_project, mr)
|
||||
end
|
||||
end
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
module SharedProject
|
||||
include Spinach::DSL
|
||||
|
||||
# Create a project without caring about what it's called
|
||||
step "I own a project" do
|
||||
@project = create(:project, :repository, namespace: @user.namespace)
|
||||
@project.add_master(@user)
|
||||
end
|
||||
|
||||
step "I own a project in some group namespace" do
|
||||
@group = create(:group, name: 'some group')
|
||||
@project = create(:project, namespace: @group)
|
||||
@project.add_master(@user)
|
||||
end
|
||||
|
||||
def current_project
|
||||
@project ||= Project.first
|
||||
end
|
||||
|
||||
# ----------------------------------------
|
||||
# Visibility of archived project
|
||||
# ----------------------------------------
|
||||
|
||||
step 'I should not see project "Archive"' do
|
||||
project = Project.find_by(name: "Archive")
|
||||
expect(page).not_to have_content project.full_name
|
||||
end
|
||||
|
||||
step 'I should see project "Archive"' do
|
||||
project = Project.find_by(name: "Archive")
|
||||
expect(page).to have_content project.full_name
|
||||
end
|
||||
|
||||
# ----------------------------------------
|
||||
# Visibility level
|
||||
# ----------------------------------------
|
||||
|
||||
step 'I should see project "Enterprise"' do
|
||||
expect(page).to have_content "Enterprise"
|
||||
end
|
||||
|
||||
step 'I should not see project "Enterprise"' do
|
||||
expect(page).not_to have_content "Enterprise"
|
||||
end
|
||||
|
||||
step 'internal project "Internal"' do
|
||||
create(:project, :internal, :repository, name: 'Internal')
|
||||
end
|
||||
|
||||
step 'I should see project "Internal"' do
|
||||
page.within '.js-projects-list-holder' do
|
||||
expect(page).to have_content "Internal"
|
||||
end
|
||||
end
|
||||
|
||||
step 'I should not see project "Internal"' do
|
||||
page.within '.js-projects-list-holder' do
|
||||
expect(page).not_to have_content "Internal"
|
||||
end
|
||||
end
|
||||
|
||||
step 'I should see project "Community"' do
|
||||
expect(page).to have_content "Community"
|
||||
end
|
||||
|
||||
step 'I should not see project "Community"' do
|
||||
expect(page).not_to have_content "Community"
|
||||
end
|
||||
|
||||
step '"John Doe" owns private project "Enterprise"' do
|
||||
user_owns_project(
|
||||
user_name: 'John Doe',
|
||||
project_name: 'Enterprise'
|
||||
)
|
||||
end
|
||||
|
||||
step '"John Doe" owns internal project "Internal"' do
|
||||
user_owns_project(
|
||||
user_name: 'John Doe',
|
||||
project_name: 'Internal',
|
||||
visibility: :internal
|
||||
)
|
||||
end
|
||||
|
||||
step 'public empty project "Empty Public Project"' do
|
||||
create :project_empty_repo, :public, name: "Empty Public Project"
|
||||
end
|
||||
|
||||
step 'project "Shop" has labels: "bug", "feature", "enhancement"' do
|
||||
project = Project.find_by(name: "Shop")
|
||||
create(:label, project: project, title: 'bug')
|
||||
create(:label, project: project, title: 'feature')
|
||||
create(:label, project: project, title: 'enhancement')
|
||||
end
|
||||
|
||||
def user_owns_project(user_name:, project_name:, visibility: :private)
|
||||
user = user_exists(user_name, username: user_name.gsub(/\s/, '').underscore)
|
||||
project = Project.find_by(name: project_name)
|
||||
project ||= create(:project, visibility, name: project_name, namespace: user.namespace)
|
||||
project.add_master(user)
|
||||
end
|
||||
end
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
require_relative 'active_tab'
|
||||
|
||||
module SharedProjectTab
|
||||
include Spinach::DSL
|
||||
include SharedActiveTab
|
||||
|
||||
step 'the active main tab should be Project' do
|
||||
ensure_active_main_tab('Overview')
|
||||
end
|
||||
|
||||
step 'the active main tab should be Repository' do
|
||||
ensure_active_main_tab('Repository')
|
||||
end
|
||||
|
||||
step 'the active main tab should be Issues' do
|
||||
ensure_active_main_tab('Issues')
|
||||
end
|
||||
|
||||
step 'the active sub tab should be Members' do
|
||||
ensure_active_sub_tab('Members')
|
||||
end
|
||||
|
||||
step 'the active main tab should be Merge Requests' do
|
||||
ensure_active_main_tab('Merge Requests')
|
||||
end
|
||||
|
||||
step 'the active main tab should be Snippets' do
|
||||
ensure_active_main_tab('Snippets')
|
||||
end
|
||||
|
||||
step 'the active main tab should be Wiki' do
|
||||
ensure_active_main_tab('Wiki')
|
||||
end
|
||||
|
||||
step 'the active main tab should be Members' do
|
||||
ensure_active_main_tab('Members')
|
||||
end
|
||||
|
||||
step 'the active main tab should be Settings' do
|
||||
ensure_active_main_tab('Settings')
|
||||
end
|
||||
|
||||
step 'the active sub tab should be Graph' do
|
||||
ensure_active_sub_tab('Graph')
|
||||
end
|
||||
|
||||
step 'the active sub tab should be Files' do
|
||||
ensure_active_sub_tab('Files')
|
||||
end
|
||||
|
||||
step 'the active sub tab should be Commits' do
|
||||
ensure_active_sub_tab('Commits')
|
||||
end
|
||||
|
||||
step 'the active sub tab should be Home' do
|
||||
ensure_active_sub_tab('Details')
|
||||
end
|
||||
|
||||
step 'the active sub tab should be Activity' do
|
||||
ensure_active_sub_tab('Activity')
|
||||
end
|
||||
|
||||
step 'the active sub tab should be Charts' do
|
||||
ensure_active_sub_tab('Charts')
|
||||
end
|
||||
end
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
module SharedShortcuts
|
||||
include Spinach::DSL
|
||||
|
||||
step 'I press "g" and "p"' do
|
||||
find('body').native.send_key('g')
|
||||
find('body').native.send_key('p')
|
||||
end
|
||||
|
||||
step 'I press "g" and "i"' do
|
||||
find('body').native.send_key('g')
|
||||
find('body').native.send_key('i')
|
||||
end
|
||||
|
||||
step 'I press "g" and "m"' do
|
||||
find('body').native.send_key('g')
|
||||
find('body').native.send_key('m')
|
||||
end
|
||||
end
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
module SharedSidebarActiveTab
|
||||
include Spinach::DSL
|
||||
|
||||
step 'no other main tabs should be active' do
|
||||
expect(page).to have_selector('.nav-sidebar li.active', count: 1)
|
||||
end
|
||||
|
||||
def ensure_active_main_tab(content)
|
||||
expect(find('.nav-sidebar li.active')).to have_content(content)
|
||||
end
|
||||
|
||||
step 'the active main tab should be Home' do
|
||||
ensure_active_main_tab('Projects')
|
||||
end
|
||||
|
||||
step 'the active main tab should be Groups' do
|
||||
ensure_active_main_tab('Groups')
|
||||
end
|
||||
|
||||
step 'the active main tab should be Projects' do
|
||||
ensure_active_main_tab('Projects')
|
||||
end
|
||||
|
||||
step 'the active main tab should be Issues' do
|
||||
ensure_active_main_tab('Issues')
|
||||
end
|
||||
|
||||
step 'the active main tab should be Merge Requests' do
|
||||
ensure_active_main_tab('Merge Requests')
|
||||
end
|
||||
end
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
module SharedUser
|
||||
include Spinach::DSL
|
||||
|
||||
step 'User "John Doe" exists' do
|
||||
user_exists("John Doe", { username: "john_doe" })
|
||||
end
|
||||
|
||||
step 'User "Mary Jane" exists' do
|
||||
user_exists("Mary Jane", { username: "mary_jane" })
|
||||
end
|
||||
|
||||
step 'gitlab user "Mike"' do
|
||||
create(:user, name: "Mike")
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def user_exists(name, options = {})
|
||||
User.find_by(name: name) || create(:user, { name: name, admin: false }.merge(options))
|
||||
end
|
||||
|
||||
step 'I have no ssh keys' do
|
||||
@user.keys.delete_all
|
||||
end
|
||||
|
||||
step 'I click on "Personal projects" tab' do
|
||||
page.within '.nav-links' do
|
||||
click_link 'Personal projects'
|
||||
end
|
||||
|
||||
expect(page).to have_css('.tab-content #projects.active')
|
||||
end
|
||||
|
||||
step 'I click on "Contributed projects" tab' do
|
||||
page.within '.nav-links' do
|
||||
click_link 'Contributed projects'
|
||||
end
|
||||
|
||||
expect(page).to have_css('.tab-content #contributed.active')
|
||||
end
|
||||
end
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
require 'capybara-screenshot/spinach'
|
||||
|
||||
# Give CI some extra time
|
||||
timeout = (ENV['CI'] || ENV['CI_SERVER']) ? 60 : 30
|
||||
|
||||
Capybara.register_driver :chrome do |app|
|
||||
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
|
||||
# This enables access to logs with `page.driver.manage.get_log(:browser)`
|
||||
loggingPrefs: {
|
||||
browser: "ALL",
|
||||
client: "ALL",
|
||||
driver: "ALL",
|
||||
server: "ALL"
|
||||
}
|
||||
)
|
||||
|
||||
options = Selenium::WebDriver::Chrome::Options.new
|
||||
options.add_argument("window-size=1240,1400")
|
||||
|
||||
# Chrome won't work properly in a Docker container in sandbox mode
|
||||
options.add_argument("no-sandbox")
|
||||
|
||||
# Run headless by default unless CHROME_HEADLESS specified
|
||||
options.add_argument("headless") unless ENV['CHROME_HEADLESS'] =~ /^(false|no|0)$/i
|
||||
|
||||
# Disable /dev/shm use in CI. See https://gitlab.com/gitlab-org/gitlab-ee/issues/4252
|
||||
options.add_argument("disable-dev-shm-usage") if ENV['CI'] || ENV['CI_SERVER']
|
||||
|
||||
Capybara::Selenium::Driver.new(
|
||||
app,
|
||||
browser: :chrome,
|
||||
desired_capabilities: capabilities,
|
||||
options: options
|
||||
)
|
||||
end
|
||||
|
||||
Capybara.javascript_driver = :chrome
|
||||
Capybara.default_max_wait_time = timeout
|
||||
Capybara.ignore_hidden_elements = false
|
||||
|
||||
# Keep only the screenshots generated from the last failing test suite
|
||||
Capybara::Screenshot.prune_strategy = :keep_last_run
|
||||
# From https://github.com/mattheworiordan/capybara-screenshot/issues/84#issuecomment-41219326
|
||||
Capybara::Screenshot.register_driver(:chrome) do |driver, path|
|
||||
driver.browser.save_screenshot(path)
|
||||
end
|
||||
|
||||
Spinach.hooks.before_run do
|
||||
TestEnv.eager_load_driver_server
|
||||
end
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
require 'database_cleaner'
|
||||
|
||||
DatabaseCleaner[:active_record].strategy = :deletion
|
||||
|
||||
Spinach.hooks.before_scenario do
|
||||
DatabaseCleaner.start
|
||||
end
|
||||
|
||||
Spinach.hooks.after_scenario do
|
||||
DatabaseCleaner.clean
|
||||
end
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
require './spec/simplecov_env'
|
||||
SimpleCovEnv.start!
|
||||
|
||||
ENV['RAILS_ENV'] = 'test'
|
||||
require './config/environment'
|
||||
require 'rspec/expectations'
|
||||
|
||||
if ENV['CI']
|
||||
require 'knapsack'
|
||||
Knapsack::Adapters::SpinachAdapter.bind
|
||||
end
|
||||
|
||||
WebMock.enable!
|
||||
|
||||
%w(select2_helper test_env repo_helpers wait_for_requests project_forks_helper).each do |f|
|
||||
require Rails.root.join('spec', 'support', 'helpers', f)
|
||||
end
|
||||
|
||||
%w(sidekiq webmock).each do |f|
|
||||
require Rails.root.join('spec', 'support', f)
|
||||
end
|
||||
|
||||
Dir["#{Rails.root}/features/steps/shared/*.rb"].each { |file| require file }
|
||||
|
||||
Spinach.hooks.before_run do
|
||||
include RSpec::Mocks::ExampleMethods
|
||||
include ActiveJob::TestHelper
|
||||
include FactoryBot::Syntax::Methods
|
||||
include GitlabRoutingHelper
|
||||
|
||||
RSpec::Mocks.setup
|
||||
TestEnv.init(mailer: false)
|
||||
|
||||
# skip pre-receive hook check so we can use
|
||||
# web editor and merge
|
||||
TestEnv.disable_pre_receive
|
||||
end
|
||||
|
||||
Spinach.hooks.after_scenario do |scenario_data, step_definitions|
|
||||
if scenario_data.tags.include?('javascript')
|
||||
include WaitForRequests
|
||||
block_and_wait_for_requests_complete
|
||||
end
|
||||
end
|
||||
|
||||
module StdoutReporterWithScenarioLocation
|
||||
# Override the standard reporter to show filename and line number next to each
|
||||
# scenario for easy, focused re-runs
|
||||
def before_scenario_run(scenario, step_definitions = nil)
|
||||
@max_step_name_length = scenario.steps.map(&:name).map(&:length).max if scenario.steps.any? # rubocop:disable Gitlab/ModuleWithInstanceVariables
|
||||
name = scenario.name
|
||||
|
||||
# This number has no significance, it's just to line things up
|
||||
max_length = @max_step_name_length + 19 # rubocop:disable Gitlab/ModuleWithInstanceVariables
|
||||
out.puts "\n #{'Scenario:'.green} #{name.light_green.ljust(max_length)}" \
|
||||
" # #{scenario.feature.filename}:#{scenario.line}"
|
||||
end
|
||||
end
|
||||
|
||||
Spinach::Reporter::Stdout.prepend(StdoutReporterWithScenarioLocation)
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
Spinach.hooks.before_scenario do
|
||||
allow(Gitlab::GitalyClient).to receive(:feature_enabled?).and_return(true)
|
||||
end
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
module LoginHelpers
|
||||
# After inclusion, IntegrationHelpers calls these two methods that aren't
|
||||
# supported by Spinach, so we perform the end results ourselves
|
||||
class << self
|
||||
def setup(*args)
|
||||
Spinach.hooks.before_scenario do
|
||||
Warden.test_mode!
|
||||
end
|
||||
end
|
||||
|
||||
def teardown(*args)
|
||||
Spinach.hooks.after_scenario do
|
||||
Warden.test_reset!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
include Devise::Test::IntegrationHelpers
|
||||
end
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
# The spinach-rerun-reporter doesn't define the on_undefined_step
|
||||
# See it here: https://github.com/javierav/spinach-rerun-reporter/blob/master/lib/spinach/reporter/rerun.rb
|
||||
require 'spinach-rerun-reporter'
|
||||
|
||||
module Spinach
|
||||
class Reporter
|
||||
class Rerun
|
||||
def on_undefined_step(step_data, failure, step_definitions = nil)
|
||||
super step_data, failure, step_definitions
|
||||
|
||||
# save feature file and scenario line
|
||||
@rerun << "#{current_feature.filename}:#{current_scenario.line}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -4,7 +4,6 @@ namespace :gitlab do
|
|||
cmds = [
|
||||
%w(rake brakeman),
|
||||
%w(rake rubocop),
|
||||
%w(rake spinach),
|
||||
%w(rake spec),
|
||||
%w(rake karma)
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,60 +0,0 @@
|
|||
Rake::Task["spinach"].clear if Rake::Task.task_defined?('spinach')
|
||||
|
||||
namespace :spinach do
|
||||
namespace :project do
|
||||
desc "GitLab | Spinach | Run project commits, issues and merge requests spinach features"
|
||||
task :half do
|
||||
run_spinach_tests('@project_commits,@project_issues,@project_merge_requests')
|
||||
end
|
||||
|
||||
desc "GitLab | Spinach | Run remaining project spinach features"
|
||||
task :rest do
|
||||
run_spinach_tests('~@admin,~@dashboard,~@profile,~@public,~@snippets,~@project_commits,~@project_issues,~@project_merge_requests')
|
||||
end
|
||||
end
|
||||
|
||||
desc "GitLab | Spinach | Run project spinach features"
|
||||
task :project do
|
||||
run_spinach_tests('~@admin,~@dashboard,~@profile,~@public,~@snippets')
|
||||
end
|
||||
|
||||
desc "GitLab | Spinach | Run other spinach features"
|
||||
task :other do
|
||||
run_spinach_tests('@admin,@dashboard,@profile,@public,@snippets')
|
||||
end
|
||||
|
||||
desc "GitLab | Spinach | Run other spinach features"
|
||||
task :builds do
|
||||
run_spinach_tests('@builds')
|
||||
end
|
||||
end
|
||||
|
||||
desc "GitLab | Run spinach"
|
||||
task :spinach do
|
||||
run_spinach_tests(nil)
|
||||
end
|
||||
|
||||
def run_system_command(cmd)
|
||||
system({ 'RAILS_ENV' => 'test', 'force' => 'yes' }, *cmd)
|
||||
end
|
||||
|
||||
def run_spinach_command(args)
|
||||
run_system_command(%w(spinach -r rerun) + args)
|
||||
end
|
||||
|
||||
def run_spinach_tests(tags)
|
||||
success = run_spinach_command(%W(--tags #{tags}))
|
||||
3.times do |_|
|
||||
break if success
|
||||
break unless File.exist?('tmp/spinach-rerun.txt')
|
||||
|
||||
tests = File.foreach('tmp/spinach-rerun.txt').map(&:chomp)
|
||||
puts ''
|
||||
puts "Spinach tests for #{tags}: Retrying tests... #{tests}".color(:red)
|
||||
puts ''
|
||||
sleep(3)
|
||||
success = run_spinach_command(tests)
|
||||
end
|
||||
|
||||
raise("spinach tests for #{tags} failed!") unless success
|
||||
end
|
||||
Loading…
Reference in New Issue