├── .gitignore ├── FIXTURES.md ├── Gemfile ├── Gemfile.lock ├── README.markdown ├── Rakefile ├── build.sh ├── features ├── ant_plugin.feature ├── audit_trail_plugin.feature ├── batch_task_plugin.feature ├── build_history.feature ├── build_timeout_plugin.feature ├── checkstyle_plugin.feature ├── cobertura_plugin.feature ├── configure_slaves.feature ├── copy_job.feature ├── dashboard-view_plugin.feature ├── deploy_plugin.feature ├── description_setter_plugin.feature ├── disk_usage_plugin.feature ├── docker_test.feature ├── email_ext_plugin.feature ├── envinject_plugin.feature ├── findbugs_plugin.feature ├── freestyle_build.feature ├── git_plugin.feature ├── gradle_plugin.feature ├── groovy_plugin.feature ├── htmlpublisher_plugin.feature ├── javadoc_plugin.feature ├── jira_plugin.feature ├── job_config_history_plugin.feature ├── job_parameter_summary_plugin.feature ├── junit_publisher.feature ├── mailer_plugin.feature ├── matrix.feature ├── matrix_reloaded_plugin.feature ├── maven_plugin.feature ├── multiple_scms_plugin.feature ├── nested_view_plugin.feature ├── nodelabelparameter_plugin.feature ├── plot_plugin.feature ├── pmd_plugin.feature ├── postbuildscript_plugin.feature ├── priority_sorter_plugin.feature ├── project_description_setter_plugin.feature ├── scp_plugin.feature ├── script.feature ├── scriptler_plugin.feature ├── step_definitions │ ├── build_history_steps.rb │ ├── docker_steps.rb │ ├── general_steps.rb │ ├── jenkins_configuration_steps.rb │ ├── job_configuration_steps.rb │ ├── job_steps.rb │ ├── junit_publisher_steps.rb │ ├── logging_steps.rb │ ├── matrix_steps.rb │ ├── nodelabelparameter_steps.rb │ ├── plugin_steps.rb │ ├── plugins │ │ ├── ant_steps.rb │ │ ├── audit_trail_steps.rb │ │ ├── batch_task_steps.rb │ │ ├── build_timeout_steps.rb │ │ ├── checkstyle_steps.rb │ │ ├── cobertura_steps.rb │ │ ├── dashboard-view_steps.rb │ │ ├── deploy_steps.rb │ │ ├── description_setter_steps.rb │ │ ├── disk_usage_steps.rb │ │ ├── email_ext_steps.rb │ │ ├── envinject_plugin.rb │ │ ├── findbugs_steps.rb │ │ ├── git_steps.rb │ │ ├── gitrepo_steps.rb │ │ ├── gradle_steps.rb │ │ ├── groovy_steps.rb │ │ ├── htmlpublisher_steps.rb │ │ ├── javadoc_steps.rb │ │ ├── jira_steps.rb │ │ ├── job_config_history_steps.rb │ │ ├── job_parameter_summary_steps.rb │ │ ├── mailer_steps.rb │ │ ├── matrix_reloaded_steps.rb │ │ ├── maven_steps.rb │ │ ├── multiple_scms_steps.rb │ │ ├── nested_view_steps.rb │ │ ├── plot_steps.rb │ │ ├── pmd_steps.rb │ │ ├── postbuildscript_steps.rb │ │ ├── priority_sorter_plugin_steps.rb │ │ ├── project_description_setter_steps.rb │ │ ├── scp_steps.rb │ │ ├── scriptler_steps.rb │ │ ├── subversion_steps.rb │ │ ├── timestamper_steps.rb │ │ ├── violations_step.rb │ │ ├── warnings_steps.rb │ │ ├── ws_cleanup_steps.rb │ │ ├── xunit_steps.rb │ │ └── xvnc_steps.rb │ ├── script_steps.rb │ ├── slave_steps.rb │ └── view_steps.rb ├── subversion_plugin.feature ├── support │ ├── env.rb │ └── hooks.rb ├── timestamper_plugin.feature ├── violations_plugin.feature ├── warnings_plugin.feature ├── ws_cleanup_plugin.feature ├── xunit_plugin.feature └── xvnc_plugin.feature ├── fixtures ├── jira │ ├── Dockerfile │ ├── jira.rb │ ├── test.rb │ └── test2.rb ├── sshd │ ├── Dockerfile │ ├── sshd.rb │ ├── unsafe │ └── unsafe.pub ├── tomcat7 │ ├── Dockerfile │ └── tomcat7.rb └── winstone_docker │ ├── Dockerfile │ └── winstone_docker.rb ├── grab-latest-rc.sh ├── jenkins-selenium-tests.gemspec ├── lib └── jenkins │ ├── build.rb │ ├── build_step.rb │ ├── capybara.rb │ ├── controller │ ├── centos_controller.rb │ ├── controller_factory.rb │ ├── jboss_controller.rb │ ├── jenkins_controller.rb │ ├── local_controller.rb │ ├── log_watcher.rb │ ├── opensuse_controller.rb │ ├── sysv_init_controller.rb │ ├── tomcat_controller.rb │ ├── ubuntu_controller.rb │ ├── vagrant_controller.rb │ ├── winstone_controller.rb │ └── winstone_docker_controller.rb │ ├── cucumber.rb │ ├── docker.rb │ ├── env.rb │ ├── fixtures.rb │ ├── jenkins.rb │ ├── jenkins_config.rb │ ├── job.rb │ ├── logger.rb │ ├── matrix.rb │ ├── pagearea.rb │ ├── pageobject.rb │ ├── parameter.rb │ ├── pluginmanager.rb │ ├── plugins │ ├── ant.rb │ ├── batch_task.rb │ ├── build_timeout.rb │ ├── checkstyle.rb │ ├── cobertura.rb │ ├── deploy.rb │ ├── disk_usage.rb │ ├── email_ext.rb │ ├── envinject.rb │ ├── git.rb │ ├── gradle.rb │ ├── groovy.rb │ ├── htmlpublisher.rb │ ├── javadoc.rb │ ├── jira.rb │ ├── mailer.rb │ ├── maven.rb │ ├── multiple_scms.rb │ ├── nodelabelparameter.rb │ ├── plot.rb │ ├── postbuildscript.rb │ ├── priority_sorter.rb │ ├── scp.rb │ ├── scriptler.rb │ ├── subversion.rb │ └── xunit.rb │ ├── post_build_step.rb │ ├── rspec.rb │ ├── scenario_skipper.rb │ ├── scm.rb │ ├── slave.rb │ ├── step.rb │ ├── thread_dump.rb │ ├── tool_installer.rb │ ├── util │ └── codemirror.rb │ ├── vagrant.rb │ ├── version.rb │ ├── view.rb │ └── workspace.rb ├── resources ├── checkstyle_plugin │ └── checkstyle-result.xml ├── cobertura_plugin │ └── coverage.xml ├── findbugs_plugin │ └── findbugsXml.xml ├── htmlpublisher_plugin │ ├── home.html │ └── style.css ├── junit │ ├── failure │ │ ├── TEST-com.simple.project.AppTest.xml │ │ └── com.simple.project.AppTest.txt │ ├── parameterized │ │ ├── junit.xml │ │ └── testng.xml │ └── success │ │ ├── TEST-com.simple.project.AppTest.xml │ │ └── com.simple.project.AppTest.txt ├── maven │ └── repositories │ │ └── multimodule │ │ ├── module_a │ │ └── pom.xml │ │ ├── module_b │ │ └── pom.xml │ │ └── pom.xml ├── plot_plugin │ └── plot.csv ├── pmd_plugin │ ├── pmd-warnings.xml │ └── pmd.xml ├── scriptler_plugin │ ├── hello_parameterized.groovy │ └── hello_world.groovy └── violations_plugin │ ├── fxcop │ └── fxcop.xml │ └── pom.xml ├── run ├── spec ├── ant_plugin.rb └── spec_helper.rb ├── vagrant ├── centos │ └── Vagrantfile ├── opensuse │ └── Vagrantfile ├── readme.txt └── ubuntu │ └── Vagrantfile └── veewee ├── definitions ├── jenkins-test-centos-6.0 │ ├── base.sh │ ├── chef.sh │ ├── cleanup.sh │ ├── definition.rb │ ├── ks.cfg │ ├── puppet.sh │ ├── ruby.sh │ ├── vagrant.sh │ ├── virtualbox.sh │ └── zerodisk.sh └── jenkins-test-opensuse-11.4 │ ├── autoinst_en.xml │ ├── definition.rb │ └── postinstall.sh └── readme.txt /.gitignore: -------------------------------------------------------------------------------- 1 | jenkins*.war 2 | *.swp 3 | *.swn 4 | last_test.log 5 | *~ 6 | .vagrant 7 | iso 8 | *.box 9 | workspace/ 10 | path-element.hpi 11 | slave.jar 12 | temp_dir_* 13 | chromedriver.log 14 | .buildpath 15 | .project 16 | -------------------------------------------------------------------------------- /FIXTURES.md: -------------------------------------------------------------------------------- 1 | # Docker Test Fixtures 2 | 3 | End-to-end testing requires a lot of non-trivial test fixtures that you want Jenkins to interact with, 4 | such as SSH daemon, JIRA server, LDAP server, etc. 5 | 6 | To allow us to define such fixtures in a portable and reusable manner, this test harness comes with 7 | a mechanism and convention to define/use fixtures inside [Docker](http://docker.io/). They are 8 | defined in `./fixtures/*` 9 | 10 | 11 | ## Running/skipping Docker tests 12 | Tests that require docker fixtures are marked with `@docker` annotation. If docker is not installed 13 | when you run tests, these tests are automatically skipped. 14 | 15 | 16 | ## Writing a cucumber test that relies on Docker fixtures 17 | `docker_steps.rb` defines steps that get the fixtures running, such as this: 18 | 19 | Given a docker fixture "tomcat7" 20 | 21 | The instantiated fixture object is assigned to `@docker["tomcat7"]` so that your step definitions can access them. 22 | See `deploy_steps.rb` for an example of interacting with running containers. 23 | 24 | 25 | ## Defining a fixture 26 | Each fixture is defined in a directory named after its ID. A fixture minimally consists 27 | of `Dockerfile` that defines how to build the image, and it also must accompany `ID.rb` file 28 | that defines a fixture wrapper class that encapsulates interactions to the container. 29 | 30 | The fixture wrapper class extends from `Fixture` class, and it needs to call `register` class method 31 | to make the wrapper class discoverable to the runtime. 32 | 33 | `Jenkins::Fixtures::Fixture.search_path` is a string array that lists directories that contain fixtures. 34 | This allows you to define your local fixtures elsewhere, for example if you have your own in-house acceptance testing. -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # ruby directive does not seem to support relational operators to constrain version number 4 | if RUBY_VERSION < "2.0" 5 | ruby "2.0" 6 | end 7 | 8 | gemspec 9 | 10 | group :development do 11 | gem "debugger" 12 | gem "ruby-debug-ide" 13 | end 14 | 15 | # vim: set ft=conf 16 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler' 2 | require 'rake' 3 | require 'rake/testtask' 4 | require 'cucumber' 5 | require 'cucumber/rake/task' 6 | 7 | task :default => :cucumber 8 | 9 | namespace :cucumber do 10 | desc "Run the 'finished' scenarios (without @wip)" 11 | Cucumber::Rake::Task.new(:ready) do |t| 12 | t.cucumber_opts = "--tags ~@wip --format pretty" 13 | end 14 | 15 | desc "Run the scenarios which don't require network access" 16 | Cucumber::Rake::Task.new(:nonetwork) do |t| 17 | t.cucumber_opts = "--tags ~@wip --format pretty" 18 | end 19 | 20 | desc "Run the scenarios tagged with @wip" 21 | Cucumber::Rake::Task.new(:wip) do |t| 22 | t.cucumber_opts = "--tags @wip --format pretty" 23 | end 24 | 25 | desc "Run step definition check" 26 | Cucumber::Rake::Task.new(:dryrun) do |t| 27 | t.cucumber_opts = "--format pretty --strict --dry-run" 28 | end 29 | end 30 | 31 | desc "Defaults to running cucumber:ready" 32 | task :cucumber => "cucumber:ready" 33 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Build step to run tests 3 | 4 | curl -s -o use-ruby https://repository-cloudbees.forge.cloudbees.com/distributions/ci-addons/ruby/use-ruby 5 | RUBY_VERSION=2.0.0-p247 source ./use-ruby 6 | 7 | gem install --conservative bundle 8 | bundle update 9 | 10 | curl -s -o jenkins.war $WAR_URL 11 | 12 | STARTUP_TIMEOUT=240 JENKINS_WAR=jenkins.war bundle exec rake 13 | -------------------------------------------------------------------------------- /features/ant_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Adds Apache Ant support 2 | In order to be able to build Ant projects 3 | As a Jenkins user 4 | I want to install and configure Ant and build Ant based project 5 | 6 | Scenario: Configure a job with Ant build steps 7 | Given I have installed the "ant" plugin 8 | And a job 9 | When I configure the job 10 | And I add an Ant build step 11 | """ 12 | 13 | 14 | 15 | 16 | 17 | """ 18 | When I build the job 19 | Then the build should succeed 20 | 21 | Scenario: Add Auto-Installed Ant 22 | Given I have installed the "ant" plugin 23 | And I have Ant "1.8.4" auto-installation named "ant_1.8.4" configured 24 | And a job 25 | When I add an Ant build step for "ant_1.8.4" 26 | """ 27 | 28 | 29 | 30 | 31 | 32 | """ 33 | And I build the job 34 | Then the build should succeed 35 | And console output should contain 36 | """ 37 | Unpacking http://archive.apache.org/dist/ant/binaries/apache-ant-1.8.4-bin.zip 38 | """ 39 | 40 | Scenario: Add locally installed Ant 41 | Given I have installed the "ant" plugin 42 | And fake Ant installation at "/tmp/fake-ant" 43 | And a job 44 | And I have Ant "local_ant_1.8.4" installed in "/tmp/fake-ant" configured 45 | When I add an Ant build step for "local_ant_1.8.4" 46 | """ 47 | 48 | 49 | 50 | 51 | 52 | """ 53 | And I build the job 54 | Then console output should contain "fake ant at /tmp/fake-ant/bin/ant" 55 | And the build should succeed 56 | -------------------------------------------------------------------------------- /features/audit_trail_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Audit trail plugin 2 | 3 | Scenario: Trail should be empty after installation 4 | Given I have set up the Audit Trail plugin 5 | Then the audit trail should be empty 6 | 7 | Scenario: Trail should contain logged events 8 | Given I have set up the Audit Trail plugin 9 | When I create a job named "job" 10 | And I create dumb slave named "slave" 11 | Then the audit trail should contain event "/createItem" 12 | And the audit trail should contain event "/computer/createItem" 13 | -------------------------------------------------------------------------------- /features/batch_task_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Batch tasks 2 | Scenario: Run batch task manually 3 | Given I have installed the "batch-task" plugin 4 | And a job 5 | When I configure the job 6 | And I add batch task "manual" 7 | And I add batch task "useless" 8 | And I save the job 9 | And I build the job 10 | And I run "manual" batch task manually 11 | Then the batch task "manual" should run 12 | Then the batch task "useless" should not run 13 | 14 | Scenario: Trigger batch task 15 | Given I have installed the "batch-task" plugin 16 | And a job 17 | When I configure the job 18 | And I add batch task "runit" 19 | And I add batch task "dontrunit" 20 | And I configure batch trigger for "runit" 21 | And I save the job 22 | And I build the job 23 | Then the build should succeed 24 | And the batch task "runit" should run 25 | And the batch task "dontrunit" should not run 26 | 27 | Scenario: Trigger batch task on other job 28 | Given I have installed the "batch-task" plugin 29 | When I create a job named "target" 30 | And I configure the job 31 | And I add batch task "runit" 32 | And I add batch task "dontrunit" 33 | And I save the job 34 | And I build the job 35 | 36 | And I create a job named "trigger" 37 | And I configure the job 38 | And I configure "target" batch trigger for "runit" 39 | And I save the job 40 | And I build the job 41 | 42 | Then the build should succeed 43 | And "target" batch task "runit" should run 44 | And "target" batch task "dontrunit" should not run 45 | 46 | Scenario: Do not trigger for failed build 47 | Given I have installed the "batch-task" plugin 48 | And a job 49 | And I configure the job 50 | And I add batch task "dontrunit" 51 | And I add always fail build step 52 | And I configure batch trigger for "dontrunit" 53 | And I save the job 54 | And I build the job 55 | Then the batch task "dontrunit" should not run 56 | -------------------------------------------------------------------------------- /features/build_history.feature: -------------------------------------------------------------------------------- 1 | Feature: Display build history 2 | As a Jenkins user or administrator 3 | I should be able to view the build history both globally or per-job 4 | So that I can identify build trends, times, etc. 5 | 6 | Scenario: Viewing global build history 7 | Given a simple job 8 | When I build the job 9 | Then the global build history should show the build 10 | -------------------------------------------------------------------------------- /features/build_timeout_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Fail builds that take too long 2 | In order to prevent executors from being blocked for too long 3 | As a Jenkins user 4 | I want to set timeouts with the build-timeout plugin to abort or 5 | fail builds that exceed specified timeout values 6 | 7 | # TODO: The build-timeout plugin doesn't allow timeouts less than 3 minutes 8 | # in duration. 9 | #JENKINS-19592 10 | @wip 11 | Scenario: Fail a blocked build with absolute timeouts 12 | Given I have installed the "build-timeout" plugin 13 | And a job 14 | When I configure the job 15 | And I add a shell build step "sleep 200" 16 | And I set the build timeout to 3 minutes 17 | And I set abort build description 18 | And I save the job 19 | And I build the job 20 | Then the build should fail 21 | 22 | #JENKINS-19592 23 | @wip 24 | Scenario: Fail a blocked build if likely stuck 25 | Given I have installed the "build-timeout" plugin 26 | And a job 27 | When I configure the job 28 | And I enable concurrent builds 29 | And I add a shell build step "sleep 1" 30 | And I save the job 31 | And I build 3 jobs 32 | And I wait for build to complete 33 | And I configure the job 34 | And I set the build timeout to likely stuck 35 | And I change a shell build step to "sleep 20" 36 | And I save the job 37 | And I build the job 38 | Then the build should fail 39 | -------------------------------------------------------------------------------- /features/checkstyle_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Allow publishing of Checkstyle report 2 | In order to be able to check code style of my project 3 | As a Jenkins user 4 | I want to be able to publish Checkstyle report 5 | 6 | Scenario: Record Checkstyle report 7 | Given I have installed the "checkstyle" plugin 8 | And a job 9 | When I configure the job 10 | And I copy resource "checkstyle_plugin/checkstyle-result.xml" into workspace 11 | And I add "Publish Checkstyle analysis results" post-build action 12 | And I set up "checkstyle-result.xml" as the Checkstyle results 13 | And I save the job 14 | And I build the job 15 | Then the build should have "Checkstyle Warnings" action 16 | And the job should have "Checkstyle Warnings" action 17 | 18 | Scenario: View Checkstyle report 19 | Given I have installed the "checkstyle" plugin 20 | And a job 21 | When I configure the job 22 | And I copy resource "checkstyle_plugin/checkstyle-result.xml" into workspace 23 | And I add "Publish Checkstyle analysis results" post-build action 24 | And I set up "checkstyle-result.xml" as the Checkstyle results 25 | And I save the job 26 | And I build the job 27 | Then the build should succeed 28 | When I visit Checkstyle report 29 | Then I should see there are 776 warnings 30 | And I should see there are 776 new warnings 31 | And I should see there are 0 fixed warnings 32 | And I should see there are 776 high priority warnings 33 | And I should see there are 0 normal priority warnings 34 | And I should see there are 0 low priority warnings 35 | -------------------------------------------------------------------------------- /features/cobertura_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Allow publishing of Cobertura analysis 2 | In order to be able track test coverage of my project 3 | As a Jenkins user 4 | I want to be able to publish Cobertura analysis report 5 | 6 | Scenario: Record Cobertura coverage report 7 | Given I have installed the "cobertura" plugin 8 | And a job 9 | When I configure the job 10 | And I copy resource "cobertura_plugin/coverage.xml" into workspace 11 | And I add "Publish Cobertura Coverage Report" post-build action 12 | And I set up "coverage.xml" as the Cobertura report 13 | And I save the job 14 | And I build the job 15 | Then the build should have "Coverage Report" action 16 | And the job should have "Coverage Report" action 17 | 18 | Scenario: View Cobertura coverage report 19 | Given I have installed the "cobertura" plugin 20 | And a job 21 | When I configure the job 22 | And I copy resource "cobertura_plugin/coverage.xml" into workspace 23 | And I add "Publish Cobertura Coverage Report" post-build action 24 | And I set up "coverage.xml" as the Cobertura report 25 | And I save the job 26 | And I build the job 27 | Then the build should succeed 28 | When I visit Cobertura report 29 | Then I should see the coverage of packages is 100% 30 | Then I should see the coverage of files is 50% 31 | Then I should see the coverage of classes is 31% 32 | Then I should see the coverage of methods is 23% 33 | Then I should see the coverage of lines is 16% 34 | Then I should see the coverage of conditionals is 10% 35 | 36 | -------------------------------------------------------------------------------- /features/configure_slaves.feature: -------------------------------------------------------------------------------- 1 | Feature: configure slaves 2 | In order to effectively use more machines 3 | As a user 4 | I want to be able to configure slaves and jobs to distribute load 5 | 6 | Scenario: Tie a job to a specified label 7 | Given a job 8 | And a dumb slave 9 | When I add the label "test" to the slave 10 | And I configure the job 11 | And I tie the job to the "test" label 12 | And I build the job 13 | Then the job should be tied to the "test" label 14 | And the build should run on the slave 15 | 16 | Scenario: Tie a job to a specific slave 17 | Given a job 18 | And a dumb slave 19 | When I configure the job 20 | And I tie the job to the slave 21 | And I build the job 22 | Then the job should be tied to the slave 23 | And the build should run on the slave 24 | 25 | Scenario: Create a slave with multiple executors 26 | Given a dumb slave 27 | When I set the executors to "3" 28 | Then I should see "3" executors configured 29 | -------------------------------------------------------------------------------- /features/copy_job.feature: -------------------------------------------------------------------------------- 1 | Feature: Copy a job 2 | Copy a job and check if exists and has the same configuration as the original job 3 | 4 | Scenario: Copy a simple job 5 | When I create a job named "simple-job" 6 | And I copy the job named "simple-job-copy" from job named "simple-job" 7 | Then the page should say "simple-job-copy" 8 | And the job configuration should be equal to "simple-job" configuration 9 | -------------------------------------------------------------------------------- /features/dashboard-view_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Add spport for dashboards 2 | In order to be able to create custom dashboards 3 | As a Jenkins user 4 | I want to install and configure dashboard-view plugin 5 | 6 | Scenario: Configure dashboard 7 | Given I have installed the "dashboard-view" plugin 8 | When I create a view with a type "Dashboard" and name "dashboard" 9 | And I configure dummy dashboard 10 | And I create job "job_in_view" in the view 11 | And I build "job_in_view" in view 12 | Then the build should succeed 13 | And the dashboard sould contain details of "job_in_view" 14 | -------------------------------------------------------------------------------- /features/deploy_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Auto-deployment to application server via deploy plugin 2 | In order to get rapid feedback on applications under the development, 3 | As a Jenkins user 4 | I want to automate the delivery of web applications 5 | 6 | @native(docker) 7 | Scenario: Deploy sample webapp to Tomcat7 8 | Given I have installed the "deploy" plugin 9 | And a docker fixture "tomcat7" 10 | And a job 11 | When I configure the job 12 | And I add a shell build step 13 | """ 14 | [ -d my-webapp ] || mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-webapp -DarchetypeArtifactId=maven-archetype-webapp 15 | cd my-webapp 16 | mvn install 17 | """ 18 | And I deploy "my-webapp/target/*.war" to docker tomcat7 fixture at context path "test" 19 | And I save the job 20 | And I build the job 21 | Then the build should succeed 22 | And console output should match "to container Tomcat 7.x Remote" 23 | And docker tomcat7 fixture should show "Hello World!" at "/test/" 24 | 25 | When I configure the job 26 | And I change a shell build step to "cd my-webapp && echo 'Hello Jenkins' > src/main/webapp/index.jsp && mvn install" 27 | And I save the job 28 | When I build the job 29 | Then the build should succeed 30 | And console output should match "Redeploying" 31 | And docker tomcat7 fixture should show "Hello Jenkins" at "/test/" 32 | 33 | 34 | -------------------------------------------------------------------------------- /features/description_setter_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Set the description for each build, based upon a RegEx test of the build log file 2 | In order to be able to see important build information on project and build page 3 | As a Jenkins user 4 | I want to be able to set build description based upon regular expression 5 | 6 | Scenario: Set build description based upon build log file 7 | Given I have installed the "description-setter" plugin 8 | And a job 9 | When I configure the job 10 | And I add a shell build step "echo '=== test ==='" 11 | And I add "Set build description" post-build action 12 | And I set up "===(.*)===" as the description setter reg-exp 13 | And I set up "Descrption setter test works!" as the description setter description 14 | And I save the job 15 | And I build the job 16 | Then the build should have description "Descrption setter test works!" 17 | Then the build should have description "Descrption setter test works!" in build history 18 | 19 | -------------------------------------------------------------------------------- /features/disk_usage_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Monitor disk usage builds and jobs 2 | In order to be able to identify jobs consuming a lot of disk space and know how many disk space is consumed by builds 3 | As a Jenkins user 4 | I want to monitor disk usage of builds and jobs 5 | 6 | Scenario: Install Disk usage plugin 7 | When I install the "disk-usage" plugin from the update center 8 | Then I should be able to configure Disk usage globally 9 | And plugin page "disk-usage" should exist 10 | 11 | Scenario: Record disk usage 12 | Given I have installed the "disk-usage" plugin 13 | When I update disk usage 14 | Then the disk usage should be updated 15 | 16 | Scenario: Show disk usage graph on project page 17 | Given I have installed the "disk-usage" plugin 18 | And a simple job 19 | When I build the job 20 | And I enable disk usage graph on the project page 21 | And I update disk usage 22 | Then the project page should contain disk usage graph 23 | 24 | Scenario: Reflect disk changes in disk usage report 25 | Given I have installed the "disk-usage" plugin 26 | And a job 27 | When I add a shell build step in the job configuration 28 | """ 29 | touch file 30 | """ 31 | And I build the job 32 | And I enable disk usage graph on the project page 33 | And I update disk usage 34 | Then the job workspace should occupy some space 35 | When I wipe out job workspace 36 | And I update disk usage 37 | Then the job workspace should occupy no space 38 | -------------------------------------------------------------------------------- /features/docker_test.feature: -------------------------------------------------------------------------------- 1 | Feature: Fixtures via docker 2 | To test Jenkins features that require non-trivial fixtures, 3 | this test uses Docker to launch a fixture without affecting the host environment. 4 | 5 | @native(docker) 6 | Scenario: Run an SSH server 7 | Given a docker fixture "sshd" 8 | Then I can login via ssh 9 | 10 | -------------------------------------------------------------------------------- /features/email_ext_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Adds support for editable email configuration 2 | In order to be able to send customized mail notifications 3 | As a Jenkins user 4 | I want to install and configure email-ext plugin 5 | 6 | Scenario: Build 7 | Given I have installed the "email-ext" plugin 8 | And a default mailer setup 9 | And a job 10 | And I add always fail build step 11 | And I configure editable email "Modified $DEFAULT_SUBJECT" for "dev@example.com" 12 | """ 13 | $DEFAULT_CONTENT 14 | with amendment 15 | """ 16 | And I save the job 17 | And I build the job 18 | Then the build should fail 19 | And a mail message "^Modified " for "dev@example.com" should match 20 | """ 21 | with amendment$ 22 | """ 23 | 24 | -------------------------------------------------------------------------------- /features/envinject_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Allow to inject build environment variables 2 | In order to be able to make the build more flexible 3 | As a Jenkins user 4 | I want to be able to have an isolated environment for my job. 5 | 6 | Scenario: Prepare environment for the build process via properties content 7 | Given I have installed the "envinject" plugin 8 | And a job 9 | When I prepare environment for the build by injecting variables 10 | """ 11 | ENV_VAR_TEST=injected variable test 12 | """ 13 | And I add a shell build step "echo $ENV_VAR_TEST" 14 | And I save the job 15 | And I build the job 16 | Then console output should match "^ENV_VAR_TEST=injected variable test$" 17 | Then console output should match "^injected variable test$" 18 | 19 | Scenario: Inject environment variables to the build process via properties content 20 | Given I have installed the "envinject" plugin 21 | And a job 22 | When I inject environment variables to the build 23 | """ 24 | ENV_VAR_TEST=injected variable test 25 | """ 26 | And I add a shell build step "echo $ENV_VAR_TEST" 27 | And I save the job 28 | And I build the job 29 | Then console output should match "^ENV_VAR_TEST=injected variable test$" 30 | Then console output should match "^injected variable test$" 31 | 32 | Scenario: Inject environment variables as a build step via properties content 33 | Given I have installed the "envinject" plugin 34 | And a job 35 | When I add build step injecting variables to the build 36 | """ 37 | ENV_VAR_TEST=injected variable test 38 | """ 39 | And I add a shell build step "echo $ENV_VAR_TEST" 40 | And I save the job 41 | And I build the job 42 | Then console output should match "^ENV_VAR_TEST=injected variable test$" 43 | Then console output should match "^injected variable test$" 44 | -------------------------------------------------------------------------------- /features/findbugs_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Allow reporting for FindBugs analysis 2 | In order to be able to see possible problems in the project code easily 3 | As a Jenkins user 4 | I want to be able to show reports from FindBugs analysis 5 | 6 | Scenario: Record FindBugs analysis 7 | Given I have installed the "findbugs" plugin 8 | And a job 9 | When I configure the job 10 | And I copy resource "findbugs_plugin/findbugsXml.xml" into workspace 11 | And I add "Publish FindBugs analysis results" post-build action 12 | And I set up "findbugsXml.xml" as the FindBugs results 13 | And I save the job 14 | And I build the job 15 | Then the build should have "FindBugs Warnings" action 16 | And the job should have "FindBugs Warnings" action 17 | -------------------------------------------------------------------------------- /features/git_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Allow use of Git as a build SCM 2 | In order to be able to use of Git as a build SCM 3 | As a Jenkins user 4 | I want to poll and checkout source code from Git repository 5 | 6 | Scenario: Simple checkout from Git repository 7 | Given I have installed the "git" plugin 8 | And a job 9 | When I check out code from Git repository "git://github.com/jenkinsci/git-plugin.git" 10 | And I add a shell build step "test -f pom.xml" 11 | And I save the job 12 | And I build the job 13 | Then the build should succeed 14 | 15 | Scenario: Checkout branch from Git repository 16 | Given I have installed the "git" plugin 17 | And a job 18 | When I check out code from Git repository "git://github.com/jenkinsci/git-plugin.git" 19 | And I setup branch specifier to "svn" 20 | And I add a shell build step 21 | """ 22 | if [ `git rev-parse origin/svn` = `git rev-parse HEAD` ]; then 23 | exit 0 24 | fi 25 | exit 1 26 | """ 27 | And I save the job 28 | And I build the job 29 | Then the build should succeed 30 | 31 | Scenario: Checkout branch from Git repository 32 | Given I have installed the "git" plugin 33 | And a job 34 | When I check out code from Git repository "git://github.com/jenkinsci/git-plugin.git" 35 | And I setup local branch to "selenium_test_branch" 36 | And I add a shell build step 37 | """ 38 | if [ `git rev-parse selenium_test_branch` = `git rev-parse HEAD` ]; then 39 | exit 0 40 | fi 41 | exit 1 42 | """ 43 | And I save the job 44 | And I build the job 45 | Then the build should succeed 46 | 47 | Scenario: Simple checkout from Git repository 48 | Given I have installed the "git" plugin 49 | And a job 50 | When I check out code from Git repository "git://github.com/jenkinsci/git-plugin.git" 51 | And I setup local Git repo dir to "selenium_test_dir" 52 | And I add a shell build step 53 | """ 54 | if [ ! -d selenium_test_dir ]; then 55 | exit 1 56 | fi 57 | cd selenium_test_dir 58 | test -f pom.xml 59 | """ 60 | And I save the job 61 | And I build the job 62 | Then the build should succeed 63 | 64 | Scenario: Simple checkout from Git repository 65 | Given I have installed the "git" plugin 66 | And a job 67 | When I check out code from Git repository "git://github.com/jenkinsci/git-plugin.git" 68 | And I setup Git repo name to "selenium_test_repo" 69 | And I add a shell build step "test -f pom.xml" 70 | And I save the job 71 | And I build the job 72 | Then the build should succeed 73 | -------------------------------------------------------------------------------- /features/gradle_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Test Gradle plugin 2 | 3 | Scenario: Add Auto-Installed Gradle 4 | Given I have installed the "gradle" plugin 5 | And I have Gradle "1.5" auto-installation named "gradle-1.5" configured 6 | And a job 7 | When I configure the job 8 | And I add script for creating "build.gradle" file : 9 | """ 10 | task hello { 11 | doLast { 12 | println 'Hello world!' 13 | } 14 | } 15 | """ 16 | And I add Gradle build step 17 | And I set Gradle version "gradle-1.5", build step description "test" and tasks "hello" 18 | And I save the job 19 | And I build the job 20 | Then the build should succeed 21 | And console output should contain "Hello world!" 22 | 23 | Scenario: Execute gradle script hello.gradle from gradle directory with quiet switch 24 | Given I have installed the "gradle" plugin 25 | And I have Gradle "1.5" auto-installation named "gradle-1.5" configured 26 | And a job 27 | When I configure the job 28 | And I add script for creating "hello.gradle" file in directory "gradle" : 29 | """ 30 | task hello { 31 | doLast { 32 | println 'Hello world!' 33 | } 34 | } 35 | """ 36 | And I add Gradle build step 37 | And I set Gradle version "gradle-1.5", build step description "test" and tasks "hello" 38 | And I set Gradle script file name "hello.gradle" 39 | And I set Gradle script direcotry path "gradle" 40 | And I set Gradle switches "--quiet" 41 | And I save the job 42 | And I build the job 43 | Then the build should succeed 44 | And console output should contain "gradle --quiet" 45 | And console output should contain "Hello world!" 46 | -------------------------------------------------------------------------------- /features/groovy_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Executing groovy scripts 2 | 3 | @native(groovy) 4 | Scenario: Run groovy script 5 | Given I have installed the "groovy" plugin 6 | And a job 7 | And I add groovy script step 8 | """ 9 | println('hello world') 10 | """ 11 | And I save the job 12 | And I build the job 13 | Then the build should succeed 14 | And console output should contain "hello world" 15 | 16 | Scenario: Run system groovy script as a command 17 | Given I have installed the "groovy" plugin 18 | When I create a job named "system-groovy-test" 19 | And I add system groovy script step 20 | """ 21 | j = jenkins.model.Jenkins.instance; 22 | println 'this is a job ' + j.getItem('system-groovy-test').displayName 23 | """ 24 | And I save the job 25 | And I build the job 26 | Then the build should succeed 27 | And console output should contain "this is a job system-groovy-test" 28 | 29 | @native(groovy) 30 | Scenario: Run groovy script from a file 31 | Given I have installed the "groovy" plugin 32 | And a job 33 | When I add a shell build step "echo println \'hello\' > hello.groovy" 34 | And I add groovy file step "hello.groovy" 35 | And I save the job 36 | And I build the job 37 | Then the build should succeed 38 | And console output should contain "hello" 39 | 40 | Scenario: Add and run auto-installed Groovy 41 | Given I have installed the "groovy" plugin 42 | And I have Groovy "2.1.1" auto-installation named "groovy_2.1.1" configured 43 | And a job 44 | When I add groovy script step using "groovy_2.1.1" 45 | """ 46 | println 'Groovy version: ' + groovy.lang.GroovySystem.getVersion() 47 | """ 48 | And I save the job 49 | And I build the job 50 | Then the build should succeed 51 | And console output should contain "Groovy version: 2.1.1" 52 | And console output should contain 53 | """ 54 | Unpacking http://dist.groovy.codehaus.org/distributions/groovy-binary-2.1.1.zip 55 | """ 56 | 57 | 58 | @native(groovy) 59 | Scenario: Add and run auto-installed Groovy 60 | Given I have installed the "groovy" plugin 61 | And fake Groovy installation at "/tmp/fake-groovy" 62 | And I have Groovy "local_groovy_2.1.1" installed in "/tmp/fake-groovy" configured 63 | And a job 64 | When I add groovy script step using "local_groovy_2.1.1" 65 | """ 66 | println 'Groovy version: ' + groovy.lang.GroovySystem.getVersion() 67 | """ 68 | And I save the job 69 | And I build the job 70 | Then the build should succeed 71 | And console output should contain "fake groovy at /tmp/fake-groovy/bin/groovy" 72 | -------------------------------------------------------------------------------- /features/htmlpublisher_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Publish HTML directories 2 | As a Jenkins user 3 | I want to publishe various html reports 4 | 5 | Scenario: Publish whole directory 6 | Given I have installed the "htmlpublisher" plugin 7 | And a simple job 8 | When I configure the job 9 | And I copy resource "htmlpublisher_plugin/*" into workspace 10 | And I configure "." directory to be published as "My report" 11 | And I set index file to "home.html" 12 | And I save the job 13 | And I build the job 14 | Then the build should succeed 15 | And the html report "My report" should be correclty published 16 | -------------------------------------------------------------------------------- /features/javadoc_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Test Javadoc plugin 2 | 3 | Scenario: Publish javadoc from freestyle job 4 | Given a Maven 5 | And a job 6 | When I configure the job 7 | And I add build steps to generate javadoc 8 | And I add a Publish javadoc post build step with path "my-app/target/site/apidocs/" 9 | And I save the job 10 | And I build the job 11 | Then the build should succeed 12 | And the job should have "Javadoc" action 13 | And the javadoc should display "com.mycompany.app" 14 | 15 | Scenario: Publish javadoc from matrix job 16 | Given a Maven 17 | And a matrix job 18 | When I configure the job 19 | And I add build steps to generate javadoc 20 | And I add a Publish javadoc post build step with path "my-app/target/site/apidocs/" 21 | And I save the job 22 | And I build the job 23 | Then javadoc should display "com.mycompany.app" for default configuration 24 | -------------------------------------------------------------------------------- /features/jira_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Update JIRA tickets when a build is ready 2 | In order to notify people waiting for a bug fix 3 | As a Jenkins developer 4 | I want JIRA issues to be updated when a new build is made 5 | 6 | @native(docker) 7 | Scenario: JIRA ticket gets updated with a build link 8 | Given a docker fixture "jira" 9 | And "ABC" project on docker jira fixture 10 | And a new issue in "ABC" project on docker jira fixture 11 | And a new issue in "ABC" project on docker jira fixture 12 | And I have installed the "jira" plugin 13 | 14 | Given I have installed the "git" plugin 15 | And an empty test git repository 16 | And a job 17 | 18 | Then I configure docker fixture as JIRA site 19 | 20 | Then I configure the job 21 | And I check out code from the test Git repository 22 | And I add "Update relevant JIRA issues" post-build action 23 | And I save the job 24 | 25 | Then I commit "initial commit" to the test Git repository 26 | And I build the job 27 | And the build should succeed 28 | 29 | When I commit "[ABC-1] fixed" to the test Git repository 30 | And I commit "[ABC-2] fixed" to the test Git repository 31 | And I build the job 32 | Then the build should succeed 33 | And the build should link to JIRA ABC-1 ticket 34 | And the build should link to JIRA ABC-2 ticket 35 | And JIRA ABC-1 ticket has comment from admin that refers to the build 36 | 37 | 38 | @nojenkins 39 | Scenario: quick test of local git repository 40 | Given an empty test git repository 41 | Then I commit "[ABC-1] fixed" to the test Git repository 42 | And I commit "[ABC-2] fixed" to the test Git repository 43 | 44 | -------------------------------------------------------------------------------- /features/job_config_history_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Test JobConfigHistory plugin 2 | 3 | Scenario: Save job config history 4 | Given I have installed the "jobConfigHistory" plugin 5 | And a simple job 6 | When I configure the job 7 | And I add a shell build step "ls" 8 | And I save the job 9 | And I visit job action named "Job Config History" 10 | Then jobConfigHistory page should show difference 11 | 12 | Scenario: Show difference in config history 13 | Given I have installed the "jobConfigHistory" plugin 14 | And a simple job 15 | When I configure the job 16 | And I add a shell build step "ls" 17 | And I save the job 18 | And I configure the job 19 | And I change a shell build step to "ls -ls" 20 | And I save the job 21 | And I visit job action named "Job Config History" 22 | And I dispaly difference 23 | Then configuration should have "ls -ls" instead of "ls" 24 | -------------------------------------------------------------------------------- /features/job_parameter_summary_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Sumarize job parameters 2 | In order to be able to check code style of my project 3 | As a Jenkins user 4 | I want to be able to publish Checkstyle report 5 | 6 | Scenario: Show freestyle job parameter summary 7 | Given I have installed the "job-parameter-summary" plugin 8 | And a job 9 | When I configure the job 10 | And I add a string parameter "MY_STRING_PARAM_0" defaulting to "MY_STRING_VAL_0" 11 | And I add a string parameter "MY_STRING_PARAM_1" defaulting to "MY_STRING_VAL_1" 12 | And I save the job 13 | Then summary should contain String Parameter "MY_STRING_PARAM_0" defaulting to "MY_STRING_VAL_0" 14 | And summary should contain String Parameter "MY_STRING_PARAM_1" defaulting to "MY_STRING_VAL_1" 15 | -------------------------------------------------------------------------------- /features/junit_publisher.feature: -------------------------------------------------------------------------------- 1 | Feature: Test Junit test result publisher 2 | 3 | Scenario: Publish test result which passed 4 | When I create a job named "javadoc-test" 5 | And I configure the job 6 | And I copy resource "junit/success" into workspace 7 | And I set Junit archiver path "success/*.xml" 8 | And I save the job 9 | And I build the job 10 | Then the build should succeed 11 | And I visit build action named "Test Result" 12 | Then the page should say "0 failures" 13 | 14 | Scenario: Publish test result which failed 15 | When I create a job named "javadoc-test" 16 | And I configure the job 17 | And I copy resource "junit/failure" into workspace 18 | And I set Junit archiver path "failure/*.xml" 19 | And I save the job 20 | And I build the job 21 | Then the build should be unstable 22 | And I visit build action named "Test Result" 23 | Then the page should say "1 failures" 24 | 25 | Scenario: Publish rest of parameterized tests 26 | Given a job 27 | When I configure the job 28 | And I copy resource "junit/parameterized" into workspace 29 | And I set Junit archiver path "parameterized/*.xml" 30 | And I save the job 31 | And I build the job 32 | Then the build should be unstable 33 | And I visit build action named "Test Result" 34 | And "JUnit.testScore[0]" error summary should match "expected:<42> but was:<0>" 35 | And "JUnit.testScore[1]" error summary should match "expected:<42> but was:<1>" 36 | And "JUnit.testScore[2]" error summary should match "expected:<42> but was:<2>" 37 | And "TestNG.testScore" error summary should match "expected:<42> but was:<0>" 38 | And "TestNG.testScore" error summary should match "expected:<42> but was:<1>" 39 | And "TestNG.testScore" error summary should match "expected:<42> but was:<2>" 40 | -------------------------------------------------------------------------------- /features/mailer_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Notify users via email 2 | In order to have all contributors informed 3 | As a Jenkins project manager 4 | I want to send and configure mail notifications 5 | 6 | Scenario: Send test email 7 | Given a default mailer setup 8 | When I send test mail to "admin@example.com" 9 | Then a mail message "Test email #1" for "admin@example.com" should match 10 | """ 11 | This is test email #1 sent from Jenkins 12 | """ 13 | 14 | Scenario: Send mail for failed build 15 | Given a default mailer setup 16 | And a job 17 | When I configure the job 18 | And I add always fail build step 19 | And I configure mail notification for "dev@example.com mngmnt@example.com" 20 | And I save the job 21 | And I build the job 22 | Then a mail message "Build failed in Jenkins: .* #1" for "dev@example.com mngmnt@example.com" should match 23 | """ 24 | failure 25 | """ 26 | -------------------------------------------------------------------------------- /features/matrix_reloaded_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Test matrix-reloaded plugin 2 | 3 | Scenario: Build Matrix configuration 4 | Given I have installed the "matrix-reloaded" plugin 5 | When I create a matrix job 6 | And I configure user axis "AAA" with values "111 222" 7 | And I configure user axis "BBB" with values "333 444" 8 | And I save the job 9 | And I build the job 10 | And I visit build action named "Matrix Reloaded" 11 | Then I should see matrix configuration "AAA=111,BBB=333" 12 | And I should see matrix configuration "AAA=111,BBB=444" 13 | And I should see matrix configuration "AAA=222,BBB=333" 14 | And I should see matrix configuration "AAA=222,BBB=444" 15 | 16 | Scenario: Run Matrix configuration 17 | Given I have installed the "matrix-reloaded" plugin 18 | When I create a matrix job 19 | And I configure user axis "AAA" with values "111 222" 20 | And I configure user axis "BBB" with values "333 444" 21 | And I save the job 22 | And I build the job 23 | And I visit build action named "Matrix Reloaded" 24 | And I select matrix configuration "AAA=111,BBB=333" 25 | And I rebuild matrix job 26 | Then combination "AAA=111,BBB=333" should be built 27 | And combination "AAA=111,BBB=444" should not be built 28 | And combination "AAA=222,BBB=333" should not be built 29 | And combination "AAA=222,BBB=444" should not be built 30 | -------------------------------------------------------------------------------- /features/multiple_scms_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Test Multiple SCMs plugin 2 | 3 | Scenario: Checkout from multiple SCMs 4 | Given I have installed the "subversion" plugin 5 | And I have installed the "git" plugin 6 | And I have installed the "multiple-scms" plugin 7 | And a job 8 | When I configure the job 9 | And I choose Multiple SCMs SCM 10 | And I add Git scm url "git://github.com/jenkinsci/git-plugin.git" and directory name "git-plugin" 11 | And I add Subversion scm url "https://svn.jenkins-ci.org/trunk/jenkins/test-projects/model-ant-project/" and directory name "model-ant-project" 12 | And I add a shell build step 13 | """ 14 | test -d model-ant-project/.svn 15 | cd git-plugin/ 16 | test -f pom.xml 17 | """ 18 | And I save the job 19 | And I build the job 20 | Then the build should succeed 21 | -------------------------------------------------------------------------------- /features/nested_view_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Test Nested view plugin 2 | 3 | Scenario: Create Nested view 4 | Given I have installed the "nested-view" plugin 5 | And a simple job 6 | When I create a view with a type "Nested View" and name "Nested" 7 | Then I should see the view on the main page 8 | 9 | Scenario: Add subviews to a Nested view 10 | Given I have installed the "nested-view" plugin 11 | And a simple job 12 | When I create a view with a type "Nested View" and name "Nested" 13 | And I create a subview of the view with a type "List View" and name "list" 14 | And I create a subview of the view with a type "List View" and name "list2" 15 | And I visit the view page 16 | Then I should see "list" view as a subview of the view 17 | And I should see "list2" view as a subview of the view 18 | 19 | Scenario: Set default view of a Nested view 20 | Given I have installed the "nested-view" plugin 21 | And a simple job 22 | When I create a view with a type "Nested View" and name "Nested" 23 | And I create a subview of the view with a type "List View" and name "list" 24 | And I create a subview of the view with a type "List View" and name "list2" 25 | And I configure subview "list" as a default of the view 26 | And I save the view 27 | And I visit the view page 28 | Then I should see "list" subview as an active view 29 | And I should see "list2" subview as an inactive view 30 | -------------------------------------------------------------------------------- /features/nodelabelparameter_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Use node name and label as parameter 2 | In order to control where a build should run at the time it is triggered 3 | As a Jenkins user 4 | I want to specify the name of the slave or the label as a build parameter 5 | 6 | Scenario: Build on a particular slave 7 | Given I have installed the "nodelabelparameter" plugin 8 | And a job 9 | And a slave named "slave42" 10 | When I configure the job 11 | And I add node parameter "slavename" 12 | And I save the job 13 | And I build the job with parameter 14 | | slavename | slave42 | 15 | Then the build should run on "slave42" 16 | 17 | Scenario: Run on label 18 | Given I have installed the "nodelabelparameter" plugin 19 | And a job 20 | And a slave named "slave42" 21 | And a slave named "slave43" 22 | When I configure the job 23 | And I add label parameter "slavelabel" 24 | And I save the job 25 | And I build the job with parameter 26 | | slavelabel | slave42 | 27 | Then the build should run on "slave42" 28 | And I build the job with parameter 29 | | slavelabel | !slave42 && !slave43 | 30 | Then the build should run on "master" 31 | 32 | Scenario: Run on several slaves 33 | Given I have installed the "nodelabelparameter" plugin 34 | And a job 35 | And a slave named "slave42" 36 | When I configure the job 37 | And I add node parameter "slavename" 38 | And I allow multiple nodes 39 | And I enable concurrent builds 40 | And I save the job 41 | And I build the job with parameter 42 | | slavename | slave42, master | 43 | Then the job should have 2 builds 44 | And the job should be built on "master" 45 | And the job should be built on "slave42" 46 | -------------------------------------------------------------------------------- /features/plot_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Adds Plotting support 2 | In order to be able to visualize build metrics 3 | As a Jenkins user 4 | I want to configure and generate various plots 5 | 6 | Scenario: Generate simple plot 7 | Given I have installed the "plot" plugin 8 | And a job 9 | When I configure the job 10 | And I copy resource "plot_plugin/plot.csv" into workspace 11 | And I add plot "My plot" in group "My group" 12 | And I configure csv data source "plot.csv" 13 | And I save the job 14 | And I build the job 15 | Then the build should succeed 16 | And there should be a plot called "My plot" in group "My group" 17 | 18 | @bug(18585) 19 | @bug(18674) 20 | Scenario: Post-build rendering should work 21 | Given I have installed the "plot" plugin 22 | And a job 23 | When I configure the job 24 | And I add plot "Some plot" in group "Plots" 25 | And I save the job 26 | And I configure the job 27 | And I configure csv data source "plot.csv" 28 | And I save the job 29 | And I build the job 30 | Then the build should succeed 31 | And there should be a plot called "Some plot" in group "Plots" 32 | -------------------------------------------------------------------------------- /features/pmd_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Tests for PMD plugin 2 | 3 | Scenario: Configure a job with PMD post-build steps 4 | Given I have installed the "pmd" plugin 5 | And a job 6 | When I configure the job 7 | And I add "Publish PMD analysis results" post-build action 8 | And I copy resource "pmd_plugin/pmd.xml" into workspace 9 | And I set path to the pmd result "pmd.xml" 10 | And I save the job 11 | And I build the job 12 | Then the build should succeed 13 | And build page should has pmd summary "0 warnings" 14 | 15 | Scenario: Configure a job with PMD post-build steps to run always 16 | Given I have installed the "pmd" plugin 17 | And a job 18 | When I configure the job 19 | And I add "Publish PMD analysis results" post-build action 20 | And I copy resource "pmd_plugin/pmd.xml" into workspace 21 | And I set path to the pmd result "pmd.xml" 22 | And I add always fail build step 23 | And I set publish always pdm 24 | And I save the job 25 | And I build the job 26 | Then the build should fail 27 | And build page should has pmd summary "0 warnings" 28 | 29 | Scenario: Configure a job with PMD post-build steps which display some warnings 30 | Given I have installed the "pmd" plugin 31 | And a job 32 | When I configure the job 33 | And I add "Publish PMD analysis results" post-build action 34 | And I copy resource "pmd_plugin/pmd-warnings.xml" into workspace 35 | And I set path to the pmd result "pmd-warnings.xml" 36 | And I save the job 37 | And I build the job 38 | Then the build should succeed 39 | And the build should have "PMD Warnings" action 40 | And build page should has pmd summary "9 warnings" 41 | 42 | -------------------------------------------------------------------------------- /features/postbuildscript_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: PostBuildScript support 2 | As a Jenkins user 3 | I want to attach custom post-build steps 4 | 5 | Background: 6 | Given I have installed the "postbuildscript" plugin 7 | And a job 8 | 9 | Scenario: Execute shell post-build script 10 | When I add marker post-build script 11 | And I build the job 12 | Then the post-build script should have been executed 13 | 14 | Scenario: Do not execute fail post-build script for jobs that succeeded 15 | When I add marker post-build script 16 | And I allow the script to run only for builds that failed 17 | And I build the job 18 | Then the post-build script should not have been executed 19 | 20 | Scenario: Do not execute success post-build script for jobs that failed 21 | When I add marker post-build script 22 | And I allow the script to run only for builds that succeeded 23 | And I add always fail build step in the job configuration 24 | And I build the job 25 | Then the post-build script should not have been executed 26 | -------------------------------------------------------------------------------- /features/priority_sorter_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Priority Sorter Plugin 2 | 3 | Background: 4 | Given I have installed the "PrioritySorter" plugin 5 | And a dumb slave 6 | And I restart Jenkins 7 | 8 | Scenario: Match jobs by name 9 | When I configure absolute sorting strategy with 2 priorities 10 | And I set priority 2 for job "low_priority" 11 | And I set priority 1 for job "high_priority" 12 | 13 | And I create a job named "low_priority" 14 | And I tie the job to the "slave" label 15 | And I queue a build 16 | And I create a job named "high_priority" 17 | And I tie the job to the "slave" label 18 | And I queue a build 19 | 20 | And I add the label "slave" to the slave 21 | Then the build should succeed 22 | And jobs should be executed in order on the slave 23 | | high_priority | low_priority | 24 | 25 | Scenario: Match jobs by view 26 | When I configure absolute sorting strategy with 2 priorities 27 | 28 | And I set priority 2 for view "normal" 29 | And I create a view named "normal" 30 | And I create job "P2" in the view 31 | And I tie the job to the "slave" label 32 | And I queue a build 33 | 34 | And I set priority 1 for view "prioritized" 35 | And I create a view named "prioritized" 36 | And I create job "P1" in the view 37 | And I tie the job to the "slave" label 38 | And I queue a build 39 | 40 | And I add the label "slave" to the slave 41 | Then the build should succeed 42 | And jobs should be executed in order on the slave 43 | | P1 | P2 | 44 | -------------------------------------------------------------------------------- /features/project_description_setter_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Set project description based on file in workspace 2 | In order to be able to change project description dynamically based upon build output 3 | As a Jenkins user 4 | I want to be able to set project description using a file in the workspace 5 | 6 | Scenario: Set project description based upon file in workspace 7 | Given I have installed the "project-description-setter" plugin 8 | And a job 9 | When I configure the job 10 | And I add a shell build step "echo 'Project description setter test' > desc.txt" 11 | And I setup project description from the file "desc.txt" in workspace 12 | And I save the job 13 | And I build the job 14 | Then the job should have description "Project description setter test" 15 | 16 | -------------------------------------------------------------------------------- /features/scp_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Tests for SCP plugin 2 | 3 | @native(docker) 4 | Scenario: Configure a job with SCP publishing 5 | Given I have installed the "scp" plugin 6 | And a docker fixture "sshd" 7 | And a job 8 | When I configure docker fixture as SCP site 9 | And I configure the job 10 | And I copy resource "pmd_plugin/pmd.xml" into workspace 11 | And I publish "pmd.xml" with SCP plugin 12 | And I save the job 13 | And I build the job 14 | Then the build should succeed 15 | And SCP plugin should have published "pmd.xml" on docker fixture 16 | -------------------------------------------------------------------------------- /features/script.feature: -------------------------------------------------------------------------------- 1 | Feature: Adds Scripting support 2 | 3 | Scenario: Execute system script 4 | When I execute system script 5 | """ 6 | println Jenkins.instance.displayName; 7 | """ 8 | Then the system script output should match "Jenkins" 9 | 10 | Scenario: Execute system script on slave 11 | Given a slave named "my_slave" 12 | When I execute system script on "my_slave" 13 | """ 14 | println 6 * 7; 15 | """ 16 | Then the system script output should match "42" 17 | -------------------------------------------------------------------------------- /features/step_definitions/build_history_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I lock the build$/ do 2 | @job.last_build.open 3 | 4 | step %{I click the "Keep this build forever" button} 5 | end 6 | 7 | Then /^the global build history should show the build$/ do 8 | visit '/view/All/builds' 9 | page.should have_content("#{@job.name} #1") 10 | end 11 | 12 | Then /^the job (should|should not) have build (\d+)$/ do |should_or_not, buildNumber| 13 | @job.build(buildNumber).open 14 | 15 | hold_the_build = have_content("Build ##{buildNumber}") 16 | page.send should_or_not, hold_the_build 17 | end 18 | 19 | Then /^the job should have (\d+) builds?$/ do |count| 20 | (@job.next_build_number - 1).should eq count.to_i 21 | end 22 | 23 | Then /^the job should be built on "(.*?)"$/ do |name| 24 | @job.last_build.wait_until_finished 25 | $jenkins.node(name).build_history.should include @job 26 | end 27 | -------------------------------------------------------------------------------- /features/step_definitions/docker_steps.rb: -------------------------------------------------------------------------------- 1 | require 'jenkins/fixtures' 2 | 3 | Given /^a docker fixture "([^"]*)"$/ do |name| 4 | @docker ||= {} 5 | @docker[:default] = @docker[name] = Jenkins::Fixtures::Fixture.start(name) 6 | end 7 | 8 | # this is for illustration only and we'll remove this 9 | Then /^I can login via ssh( to fixture "([^"]*)")?$/ do |_,name| 10 | name ||= :default 11 | @docker[name].ssh_with_publickey("uname -a") 12 | end 13 | 14 | After('@docker') do |scenario| 15 | if @docker 16 | @docker.each do |k,v| 17 | next if k==:default 18 | puts "Shutting down: #{v}" 19 | v.clean 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /features/step_definitions/general_steps.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # vim: tabstop=2 expandtab shiftwidth=2 3 | require 'pry' 4 | 5 | Transform /^(should|should not)$/ do |should_or_not| 6 | should_or_not.gsub(' ', '_').to_sym 7 | end 8 | 9 | When /^I visit the home page$/ do 10 | visit "/" 11 | end 12 | 13 | When /^I check the "([^"]*)" checkbox$/ do |name| 14 | find(:xpath, "//input[@name='#{name}']").set(true) 15 | end 16 | 17 | When /^I click the "([^"]*)" button$/ do |name| 18 | find(:xpath, "//button[text()='#{name}']").click 19 | end 20 | 21 | # Choose an option by value or text in select identified by it's visual label 22 | When /^I select "(.*?)" as a "(.*?)"$/ do |choice, select| 23 | select = find(:xpath, "//td[@class='setting-name' and text()='#{select}']/../td[@class='setting-main']/select") 24 | option = select.find(:xpath, "option[@value='#{choice}' or text()='#{choice}']") 25 | option.select_option 26 | end 27 | 28 | When /^I debug$/ do 29 | binding.pry 30 | end 31 | 32 | When /^I wait for (\d+) seconds?$/ do |seconds| 33 | sleep seconds.to_i 34 | end 35 | 36 | When /^I close the error dialog$/ do 37 | click_link 'Close' 38 | end 39 | 40 | When /^I restart Jenkins/ do 41 | @runner.restart 42 | end 43 | 44 | Then /^the page (should|should not) say "([^"]*)"$/ do |should_or_not, content| 45 | page.send should_or_not, have_content(content) 46 | end 47 | 48 | Then(/^I will write the rest of the test$/) do 49 | pending 50 | end 51 | 52 | Then /^the error description should contain$/ do |text| 53 | find(:css, "#error-description pre").text.should include text 54 | end 55 | -------------------------------------------------------------------------------- /features/step_definitions/jenkins_configuration_steps.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | Given /^I add Java version "([^"]*)" with name "([^"]*)" installed automatically to Jenkins config page$/ do |version, name| 4 | @runner.wait_for_updates 'JDK' 5 | @jenkins_config = Jenkins::JenkinsConfig.get(@base_url, 'Jenkins global configuration') 6 | @jenkins_config.enter_oracle_credentials(ENV['ORACLE_LOGIN'],ENV['ORACLE_PASSWORD']) 7 | @jenkins_config.configure do 8 | @jenkins_config.add_tool("JDK") 9 | @jenkins_config.add_jdk_auto_installation(name,version) 10 | end 11 | end 12 | 13 | Then /^I should be able to configure (.*) globally$/ do |section_name| 14 | @jenkins_config = Jenkins::JenkinsConfig.get(@base_url, 'Jenkins global configuration') 15 | @jenkins_config.open 16 | page.should have_xpath "//div[@class='section-header' and normalize-space(text())='#{section_name}']" 17 | end 18 | -------------------------------------------------------------------------------- /features/step_definitions/junit_publisher_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I set Junit archiver path "([^"]*)"$/ do |path| 2 | @job.ensure_config_page 3 | find(:xpath, "//button[text()='Add post-build action']").click 4 | find(:xpath, "//a[text()='Publish JUnit test result report']").click 5 | find(:xpath, "//input[@name='_.testResults']").set(path) 6 | end 7 | 8 | Then /^"(.*?)" error summary should match "(.*?)"$/ do |test, message| 9 | toggle test 10 | page.text.should include message 11 | toggle test 12 | end 13 | 14 | def toggle(test) 15 | xpath = "//a[text()='#{test}']/../a[starts-with(@href, 'javascript')]" 16 | elements = all(:xpath, xpath) 17 | elements.length.should be >= 1 18 | # JUnit report produced by TestNG contains colliding test names 19 | for e in elements do 20 | e.click 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /features/step_definitions/logging_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I create logger "(.*?)" logging$/ do |name, config| 2 | Jenkins::Logger.create(name, config.rows_hash) 3 | end 4 | -------------------------------------------------------------------------------- /features/step_definitions/matrix_steps.rb: -------------------------------------------------------------------------------- 1 | Given /^a matrix job$/ do 2 | @job = Jenkins::Job.create('Matrix', @base_url) 3 | end 4 | 5 | When /^I create a matrix job$/ do 6 | @job = Jenkins::Job.create('Matrix', @base_url) 7 | end 8 | 9 | When /^I configure user axis "([^"]*)" with values "([^"]*)"$/ do |name ,value| 10 | @job.add_user_axis(name, value) 11 | end 12 | 13 | When /^I configure slaves axis with value "([^"]*)"$/ do |value| 14 | @job.add_slaves_axis(value) 15 | end 16 | 17 | When /^I configure to run configurations sequentially$/ do 18 | @job.run_configurations_sequentially 19 | end 20 | 21 | When /^I configure to execute touchstone builds first with filter "([^"]*)" and required result "([^"]*)"$/ do |filter, result| 22 | @job.touchstone_builds_first(filter, result) 23 | end 24 | 25 | When /^I set combination filter to "([^"]*)"$/ do |filter| 26 | find(:path, '/hasCombinationFilter').check 27 | find(:path, '/hasCombinationFilter/combinationFilter').set(filter) 28 | end 29 | 30 | Then /^combination "([^"]*)" (should|should not) be built$/ do |configuration, should_or_not| 31 | config = @job.last_build.wait_until_finished.configuration(configuration) 32 | config.exists?.send should_or_not, be 33 | end 34 | 35 | Then /^combination "([^"]*)" (should|should not) be built in build (\d+)$/ do |configuration, should_or_not, build| 36 | config = @job.build(build).wait_until_finished.configuration(configuration) 37 | config.exists?.send should_or_not, be 38 | end 39 | 40 | Then /^the configuration "([^"]*)" should be built on "([^"]*)"$/ do |configuration, slave| 41 | config = @job.configuration configuration 42 | expression = "(Building|Building remotely)( on " + slave +")" 43 | config.last_build.wait_until_finished.console.should match expression 44 | end 45 | 46 | Then /^I console output of configurations should match "([^"]*)"$/ do |script| 47 | @job.last_build.wait_until_finished 48 | configurations = @job.configurations 49 | index = 0 50 | while index build.xml << EOF \n #{ant_xml} \nEOF") 38 | @ant_step = @job.add_build_step 'Ant' 39 | @ant_step.target = 'hello' 40 | @ant_step.version = version 41 | end 42 | end 43 | 44 | When /^I add an Ant build step$/ do |ant_xml| 45 | @job.configure do 46 | @job.add_shell_step("cat > build.xml << EOF \n #{ant_xml} \nEOF") 47 | @ant_step = @job.add_build_step 'Ant' 48 | @ant_step.target = 'hello' 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/audit_trail_steps.rb: -------------------------------------------------------------------------------- 1 | # It takes a couple of seconds for the plugin to start recording and displaying events. 2 | # It is supposed to be ready after this step. 3 | Given /^I have set up the Audit Trail plugin$/ do 4 | step 'I have installed the "audit-trail" plugin' 5 | @auditTrail = $jenkins.logger 'Audit Trail' 6 | end 7 | 8 | Then /^the audit trail should be empty$/ do 9 | @auditTrail.should be_empty 10 | end 11 | 12 | Then /^the audit trail should contain event "(.*?)"$/ do |event| 13 | @auditTrail.events.should include event 14 | end 15 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/batch_task_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I add batch task "(.*?)"$/ do |name| 2 | task = Plugin::BatchTask::Declaration.add(@job) 3 | task.name = name 4 | end 5 | 6 | When /^I configure batch trigger for "(.*?)"$/ do |task| 7 | @job.save 8 | # Needed to save configured batch tasks before configuring triggers 9 | @job.configure 10 | step %{I configure "#{@job.name}" batch trigger for "#{task}"} 11 | end 12 | 13 | When /^I configure "(.*?)" batch trigger for "(.*?)"$/ do |job, task| 14 | @job.add_postbuild_step('Invoke batch tasks').task(job, task) 15 | end 16 | 17 | When /^I run "(.*?)" batch task manually$/ do |task| 18 | task(@job, task).build! 19 | end 20 | 21 | Then /^the batch task "(.*?)" (should|should not) run$/ do |task, should_or_not| 22 | task(@job, task).send should_or_not, exist 23 | end 24 | 25 | Then /^"(.*?)" batch task "(.*?)" (should|should not) run$/ do |job_name, task, should_or_not| 26 | task($jenkins.job(job_name), task).send should_or_not, exist 27 | end 28 | 29 | def task(job, task) 30 | Plugin::BatchTask::Task.new(job, task) 31 | end 32 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/build_timeout_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I set the build timeout to (\d+) minutes$/ do |timeout| 2 | @buildTimeout = Plugins::BuildTimeout.new @job 3 | @buildTimeout.abortAfter timeout 4 | end 5 | 6 | When /^I set the build timeout to likely stuck$/ do 7 | @buildTimeout = Plugins::BuildTimeout.new @job 8 | @buildTimeout.abortWhenStuck 9 | end 10 | 11 | When /^I set abort build description$/ do 12 | @buildTimeout.useDescription 13 | end 14 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/checkstyle_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I set up "([^"]*)" as the Checkstyle results$/ do |results| 2 | find(:path, '/publisher/pattern').set(results) 3 | end 4 | 5 | When /^I visit Checkstyle report$/ do 6 | @checkstyle = Plugins::Checkstyle.new(@job) 7 | visit @checkstyle.url 8 | end 9 | 10 | 11 | Then /^I should see there are (\d+) warnings$/ do |warn_number| 12 | expect(warn_number.to_i).to eq(@checkstyle.warnings_number) 13 | end 14 | 15 | Then /^I should see there are (\d+) new warnings$/ do |new_warn_number| 16 | expect(new_warn_number.to_i).to eq(@checkstyle.new_warnings_number) 17 | end 18 | 19 | Then /^I should see there are (\d+) fixed warnings$/ do |fixed_warn_number| 20 | expect(fixed_warn_number.to_i).to eq(@checkstyle.fixed_warnings_number) 21 | end 22 | 23 | Then /^I should see there are (\d+) high priority warnings$/ do |high_warn_number| 24 | expect(high_warn_number.to_i).to eq(@checkstyle.high_warnings_number) 25 | end 26 | 27 | Then /^I should see there are (\d+) normal priority warnings$/ do |normal_warn_number| 28 | expect(normal_warn_number.to_i).to eq(@checkstyle.normal_warnings_number) 29 | end 30 | 31 | Then /^I should see there are (\d+) low priority warnings$/ do |low_warn_number| 32 | expect(low_warn_number.to_i).to eq(@checkstyle.low_warnings_number) 33 | end 34 | 35 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/cobertura_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I set up "([^"]*)" as the Cobertura report$/ do |report| 2 | find(:path, '/publisher/coberturaReportFile').set(report) 3 | end 4 | 5 | When /^I visit Cobertura report$/ do 6 | @cobertura = Plugins::Cobertura.new(@job) 7 | visit @cobertura.url 8 | end 9 | 10 | 11 | Then /^I should see the coverage of packages is (\d+)%$/ do |coverage| 12 | expect(coverage.to_i).to eq(@cobertura.packages_coverage) 13 | end 14 | 15 | Then /^I should see the coverage of files is (\d+)%$/ do |coverage| 16 | expect(coverage.to_i).to eq(@cobertura.files_coverage) 17 | end 18 | 19 | Then /^I should see the coverage of classes is (\d+)%$/ do |coverage| 20 | expect(coverage.to_i).to eq(@cobertura.classes_coverage) 21 | end 22 | 23 | Then /^I should see the coverage of methods is (\d+)%$/ do |coverage| 24 | expect(coverage.to_i).to eq(@cobertura.methods_coverage) 25 | end 26 | 27 | Then /^I should see the coverage of lines is (\d+)%$/ do |coverage| 28 | expect(coverage.to_i).to eq(@cobertura.lines_coverage) 29 | end 30 | 31 | Then /^I should see the coverage of conditionals is (\d+)%$/ do |coverage| 32 | expect(coverage.to_i).to eq(@cobertura.conditionals_coverage) 33 | end 34 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/dashboard-view_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I configure dummy dashboard$/ do 2 | @view.configure do 3 | find(:path, '/hetero-list-add[topPortlet]').click 4 | click_link 'Build statistics' 5 | 6 | find(:path, '/hetero-list-add[bottomPortlet]').click 7 | click_link 'Jenkins jobs list' 8 | end 9 | end 10 | 11 | Then /^the dashboard sould contain details of "(.*?)"$/ do |arg1| 12 | @view.open 13 | 14 | page.should have_text 'Build statistics' 15 | page.should have_text 'Jenkins jobs list' 16 | 17 | page.should have_link 'job_in_view' 18 | page.should have_link '#1' 19 | 20 | allSuccess = '//table[@id="statistics"]//td[text()="Success"]/../td[text()="100.0"]' 21 | page.should have_xpath allSuccess 22 | end 23 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/deploy_steps.rb: -------------------------------------------------------------------------------- 1 | When(/^I deploy "([^"]*)" to docker tomcat7 fixture at context path "([^"]*)"$/) do |war,path| 2 | step = @job.add_postbuild_step 'Deploy WAR' 3 | step.archive = war 4 | step.contextPath = path 5 | step.container = 'Tomcat 7.x' 6 | step.user = 'admin' 7 | step.password = 'tomcat' 8 | step.url = @docker['tomcat7'].url 9 | end 10 | 11 | When(/^docker tomcat7 fixture should show "([^"]*)" at "([^"]*)"$/) do |pattern, url| 12 | http = RestClient.get @docker['tomcat7'].url+url 13 | http.to_str.should match /#{pattern}/ 14 | end 15 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/description_setter_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I set up "([^"]*)" as the description setter reg-exp$/ do |regexp| 2 | find(:path, '/publisher/regexp').set(regexp) 3 | end 4 | 5 | When /^I set up "([^"]*)" as the description setter description$/ do |description| 6 | find(:path, '/publisher/description').set(description) 7 | end 8 | 9 | Then /^the build should have description "([^"]*)"$/ do |description| 10 | @job.last_build.wait_until_finished.open 11 | desc = first(:xpath,'//div[@id="description"]/div') 12 | desc.should have_content(description) 13 | end 14 | 15 | Then /^the build should have description "([^"]*)" in build history$/ do |description| 16 | @job.last_build.wait_until_finished 17 | @job.open 18 | desc = find(:xpath,'//table[@id="buildHistory"]/tbody/tr/td[@class="desc"]') 19 | desc.should have_content(description) 20 | end 21 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/disk_usage_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I update disk usage$/ do 2 | @disk_usage = Plugins::DiskUsage.new(@basedir, "Disk usage plugin") 3 | @disk_usage.update 4 | end 5 | 6 | When /^I enable disk usage graph on the project page$/ do 7 | @jenkins_config = Jenkins::JenkinsConfig.get(@base_url, 'Jenkins global configuration') 8 | @jenkins_config.configure do 9 | find(:xpath, "//input[@path='/hudson-plugins-disk_usage-DiskUsageProjectActionFactory/showGraph']").check 10 | end 11 | end 12 | 13 | Then /^the disk usage should be updated$/ do 14 | @disk_usage.wait_for_update(@runner.log_watcher) 15 | end 16 | 17 | Then /^the project page should contain disk usage graph$/ do 18 | step %{I visit the job page} 19 | # changed in v0.22 and v0.23 20 | page.should have_xpath("//img[@src='disk-usage/graph/png' or starts-with(@src, 'diskUsage/graph/png')]") 21 | end 22 | 23 | Then /^the job workspace should occupy some space$/ do 24 | @job.open 25 | page.should have_text /Workspace [1-9]\d*,/ 26 | end 27 | 28 | Then /^the job workspace should occupy no space$/ do 29 | @job.open 30 | page.should have_text "Workspace 0," 31 | end 32 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/email_ext_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I configure editable email "(.*?)" for "(.*?)"$/ do |subject, recipient, body| 2 | emailext = @job.add_postbuild_step 'Email-ext' 3 | emailext.subject = subject 4 | emailext.recipient = recipient 5 | emailext.body = body 6 | end 7 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/envinject_plugin.rb: -------------------------------------------------------------------------------- 1 | 2 | When /^I prepare environment for the build by injecting variables$/ do |env_var| 3 | @job.open_config 4 | find(:path, "/properties/org-jenkinsci-plugins-envinject-EnvInjectJobProperty/on").set(true) 5 | find(:path, "/properties/org-jenkinsci-plugins-envinject-EnvInjectJobProperty/on/propertiesContent").set(env_var) 6 | end 7 | 8 | When /^I inject environment variables to the build$/ do |env_var| 9 | @job.open_config 10 | find(:path, "/org-jenkinsci-plugins-envinject-EnvInjectBuildWrapper").set(true) 11 | find(:path, "/org-jenkinsci-plugins-envinject-EnvInjectBuildWrapper/propertiesContent").set(env_var) 12 | end 13 | 14 | When /^I add build step injecting variables to the build$/ do |env_var| 15 | @job.open_config 16 | envinject_step = @job.add_build_step 'Env Inject' 17 | envinject_step.vars = env_var 18 | end 19 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/findbugs_steps.rb: -------------------------------------------------------------------------------- 1 | 2 | When /^I set up "([^"]*)" as the FindBugs results$/ do |results| 3 | find(:path, '/publisher/pattern').set(results) 4 | end 5 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/git_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I check out code from Git repository "([^"]*)"$/ do |url| 2 | @gitscm = @job.add_scm 'Git' 3 | @gitscm.url url 4 | end 5 | 6 | When /^I setup branch specifier to "([^"]*)"$/ do |branch| 7 | @gitscm.branch branch 8 | end 9 | 10 | When /^I setup local branch to "([^"]*)"$/ do |branch| 11 | @gitscm.local_branch branch 12 | end 13 | 14 | When /^I setup local Git repo dir to "([^"]*)"$/ do |dir| 15 | @gitscm.local_dir dir 16 | end 17 | 18 | When /^I setup Git repo name to "([^"]*)"$/ do |repo_name| 19 | @gitscm.repo_name repo_name 20 | end 21 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/gitrepo_steps.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Steps for interacting with local Git repository for tests 3 | # 4 | 5 | Given /^an empty test git repository$/ do 6 | @repo = Jenkins::Git::GitRepo.new 7 | @repo.init 8 | @cleanup << Proc.new do 9 | @repo.clean 10 | end 11 | end 12 | 13 | When /^I check out code from the test Git repository$/ do 14 | step "I check out code from Git repository \"#{@repo.ws}\"" 15 | end 16 | 17 | When(/^I commit "([^"]*)" to the test Git repository$/) do |msg| 18 | @repo.commit msg 19 | end -------------------------------------------------------------------------------- /features/step_definitions/plugins/gradle_steps.rb: -------------------------------------------------------------------------------- 1 | Given /^I have Gradle "([^"]*)" auto-installation named "([^"]*)" configured$/ do |version, name| 2 | @runner.wait_for_updates 'Gradle' 3 | @jenkins_config = Jenkins::JenkinsConfig.get(@base_url, 'Jenkins global configuration') 4 | @jenkins_config.configure do 5 | @jenkins_config.add_tool("Gradle") 6 | sleep 1 7 | find(:xpath, "//div[@name='tool' and child::div[text()='Gradle']][last()]//input[@name='_.name']").set(name) 8 | find(:xpath, "//div[@name='tool' and child::div[text()='Gradle']][last()]//input[@name='hudson-tools-InstallSourceProperty']").set(true) 9 | find(:xpath, "//div[@name='tool' and child::div[text()='Gradle']][last()]//select[@name='_.id']/option[@value='#{version}']").click 10 | end 11 | end 12 | 13 | When /^I add script for creating "([^"]*)" file :$/ do |file, gradle_script| 14 | @job.add_shell_step("cat > #{file} << EOF \n #{gradle_script} \nEOF") 15 | end 16 | 17 | When /^I add script for creating "([^"]*)" file in directory "([^"]*)" :$/ do |file, directory, gradle_script| 18 | @job.add_shell_step("mkdir #{directory} \n cd #{directory} \n cat > #{file} << EOF \n #{gradle_script} \nEOF") 19 | end 20 | 21 | When /I add Gradle build step/ do 22 | @step = @job.add_build_step 'Gradle' 23 | end 24 | 25 | When /^I set Gradle script file name "([^"]*)"$/ do |name| 26 | @step.file name 27 | end 28 | 29 | When /^I set Gradle script direcotry path "([^"]*)"$/ do |path| 30 | @step.dir path 31 | end 32 | 33 | When /^I set Gradle switches "([^"]*)"$/ do |switches| 34 | @step.switches switches 35 | end 36 | 37 | When /^I set Gradle version "([^"]*)", build step description "([^"]*)" and tasks "([^"]*)"$/ do |version, description, tasks| 38 | @step.version version 39 | @step.description description 40 | @step.tasks tasks 41 | end 42 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/groovy_steps.rb: -------------------------------------------------------------------------------- 1 | Given /^I have Groovy "([^"]*)" auto-installation named "([^"]*)" configured$/ do |version, name| 2 | @runner.wait_for_updates 'Groovy' 3 | $jenkins.configure do 4 | tool = $jenkins.configure.add_tool_installer 'Groovy' 5 | tool.name = name 6 | tool.install_version = version 7 | end 8 | end 9 | 10 | Given /^I have Groovy "([^"]*)" installed in "([^"]*)" configured$/ do |name, groovy_home| 11 | $jenkins.configure do 12 | tool = $jenkins.configure.add_tool_installer 'Groovy' 13 | tool.name = name 14 | tool.home = groovy_home 15 | end 16 | end 17 | 18 | When /^I add system groovy script step$/ do |script| 19 | step = @job.add_build_step 'System groovy' 20 | step.command = script 21 | end 22 | 23 | When /^I add groovy script step$/ do |script| 24 | step = @job.add_build_step 'Groovy' 25 | step.command = script 26 | end 27 | 28 | When /^I add groovy script step using "(.*?)"$/ do |groovy, script| 29 | step = @job.add_build_step 'Groovy' 30 | step.version = groovy 31 | step.command = script 32 | end 33 | 34 | When /^I add groovy file step "(.*?)"$/ do |path| 35 | step = @job.add_build_step 'Groovy' 36 | step.file = path 37 | end 38 | 39 | # this needs preinstalled groovy to work 40 | Given /^fake Groovy installation at "([^"]*)"$/ do |path| 41 | real = ENV['PATH'].split(':').find { |p| File.exists? "#{p}/groovy" } 42 | 43 | FileUtils.mkdir_p "#{path}/bin" 44 | groovy="#{path}/bin/groovy" 45 | open(groovy,'wb') do |f| 46 | f.write """#!/bin/sh 47 | echo fake groovy at $0 48 | export GROOVY_HOME= 49 | exec #{real}/groovy \"$@\" 50 | """ 51 | end 52 | File.chmod(0755,groovy) 53 | end 54 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/htmlpublisher_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I configure "(.*?)" directory to be published as "(.*?)"$/ do |dirname, title| 2 | @html_publisher ||= @job.add_postbuild_step 'Publish HTML' 3 | @html_publisher.add_report title, dirname 4 | end 5 | 6 | When /^I set index file to "(.*?)"$/ do |indexName| 7 | @html_publisher.lastReport.index = indexName 8 | end 9 | 10 | Then /^the html report "(.*?)" should be correclty published$/ do |title| 11 | visit @job.url + '/' + title.gsub(' ', '_') 12 | within_frame 'myframe' do 13 | find(:css, 'h1').should be_visible 14 | find(:css, 'p', :visible => false).should_not be_visible 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/javadoc_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I add a Publish javadoc post build step with path "([^"]*)"$/ do |path| 2 | step = @job.add_postbuild_step 'Javadoc' 3 | step.dir path 4 | end 5 | 6 | When /^I add build steps to generate javadoc$/ do 7 | create_project = @job.add_build_step 'Maven' 8 | create_project.goals "archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=com.mycompany.app -DartifactId=my-app -Dversion=1.0 -B" 9 | 10 | generate_javadoc = @job.add_build_step 'Maven' 11 | generate_javadoc.goals "javadoc:javadoc -f my-app/pom.xml" 12 | end 13 | 14 | Then /^the javadoc should display "([^"]*)"$/ do |content| 15 | @job.open 16 | find(:xpath, "//div[@id='tasks']/div/a[text()='Javadoc']").click 17 | within_frame "classFrame" do 18 | page.should have_content content 19 | end 20 | end 21 | 22 | Then /^javadoc should display "([^"]*)" for default configuration$/ do |content| 23 | @job.last_build.wait_until_finished 24 | visit (@job.url + "/default") 25 | find(:xpath, "//div[@id='tasks']/div/a[text()='Javadoc']").click 26 | within_frame "classFrame" do 27 | page.should have_content content 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/jira_steps.rb: -------------------------------------------------------------------------------- 1 | When /^"([^"]*)" project on docker jira fixture$/ do |name| 2 | c = @docker['jira'] 3 | c.wait_for_ready 4 | c.create_project(name) 5 | end 6 | 7 | Then /^I configure docker fixture as JIRA site$/ do 8 | @jenkins_config = Jenkins::JenkinsConfig.get(@base_url, 'Jenkins global configuration') 9 | @jenkins_config.configure do 10 | Plugins::JIRA::GlobalConfig.add(@docker['jira'].url,"admin","admin") 11 | end 12 | end 13 | 14 | When /^a new issue in "([^"]*)" project on docker jira fixture$/ do |project| 15 | @docker['jira'].create_issue project 16 | end 17 | 18 | When /^the build should link to JIRA ([^ ]+) ticket$/ do |ticket| 19 | @job.last_build.open 20 | find_link(ticket).click # make sure you can jump to it 21 | end 22 | 23 | When /^JIRA ([^ ]+) ticket has comment from admin that refers to the build$/ do |ticket| 24 | build_url = @job.build(@job.last_build.json['number']).url 25 | comments = @docker['jira'].soap.get_comments_for_issue_with_key(ticket) 26 | 27 | raise "matching comment not found that links to #{build_url}" unless comments.find do |comment| 28 | comment.body =~ /#{build_url}/ 29 | end 30 | end -------------------------------------------------------------------------------- /features/step_definitions/plugins/job_config_history_steps.rb: -------------------------------------------------------------------------------- 1 | Then /^jobConfigHistory page should show difference/ do 2 | sleep 1 3 | all(:xpath, "//tr//a[contains(text(),'View as XML')]").length.should be >= 2 4 | all(:xpath, "//tr//a[contains(text(),'(RAW)')]").length.should be >= 2 5 | end 6 | 7 | When /^I dispaly difference/ do 8 | # There are two buttons 9 | first(:xpath, "//button[text()='Show Diffs']").click 10 | end 11 | 12 | Then /^configuration should have "([^"]*)" instead of "([^"]*)"/ do |current, original| 13 | page.should have_xpath("//td[@class='diff_original']/pre[normalize-space(text())='#{original}']") 14 | page.should have_xpath("//td[@class='diff_revised']/pre[normalize-space(text())='#{current}']") 15 | end 16 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/job_parameter_summary_steps.rb: -------------------------------------------------------------------------------- 1 | Then /^summary should contain String Parameter "([^"]+)" defaulting to "([^"]+)"$/ do |name, default| 2 | @job.open 3 | page.should have_xpath "//h2[text() = 'Build Parameters']" 4 | page.text.should match /String Parameter\s+#{name}\s+=\s+("?)#{default}\1/ 5 | end 6 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/mailer_steps.rb: -------------------------------------------------------------------------------- 1 | Given /^a default mailer setup$/ do 2 | @mailer = $jenkins.configure.mailer 3 | @mailer.setup_defaults 4 | end 5 | 6 | When /^I send test mail to "(.*?)"$/ do |recipient| 7 | @mailer.send_test_mail(recipient) 8 | sleep 3 9 | page.should have_content 'Email was successfully sent' 10 | end 11 | 12 | When /^I configure mail notification for "(.*?)"$/ do |recipients| 13 | step = @job.add_postbuild_step 'Mailer' 14 | step.recipients recipients 15 | end 16 | 17 | Then /^a mail message "(.*?)" for "(.*?)" should match$/ do |subject, recipients, body| 18 | message = $jenkins.configure.wait_for_cond(message: "Email not delivered in time") do 19 | @mailer.mail subject 20 | end 21 | 22 | message.subject.should match subject 23 | message.to.should be == recipients.split 24 | message.body.decoded.should match body 25 | end 26 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/matrix_reloaded_steps.rb: -------------------------------------------------------------------------------- 1 | Then /^I should see matrix configuration "([^"]*)"$/ do |configuration| 2 | page.should have_xpath("//input[@name='MRP::#{configuration}']") 3 | end 4 | 5 | When /^I select matrix configuration "([^"]*)"$/ do |configuration| 6 | find(:xpath, "//input[@name='MRP::#{configuration}']").set(true) 7 | end 8 | 9 | When /^I rebuild matrix job$/ do 10 | find(:xpath, "//form[@action='configSubmit']//button[text()='Rebuild Matrix']").click 11 | end 12 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/multiple_scms_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I choose Multiple SCMs SCM$/ do 2 | @multiscm = @job.add_scm 'Multiple SCMs' 3 | end 4 | 5 | When /^I add Git scm url "([^"]*)" and directory name "([^"]*)"$/ do |url, dirname| 6 | @gitscm = @multiscm.add 'Git' 7 | @gitscm.url url 8 | @gitscm.local_dir dirname 9 | end 10 | 11 | When /^I add Subversion scm url "([^"]*)" and directory name "([^"]*)"$/ do |url, dirname| 12 | @svnscm = @multiscm.add "Subversion" 13 | @svnscm.url url 14 | @svnscm.local_dir dirname 15 | end 16 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/nested_view_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I create a subview of the view with a type "([^"]*)" and name "([^"]*)"$/ do |type, name| 2 | visit("#{@view.url}/newView") 3 | fill_in "name", :with => name 4 | find(:xpath, "//input[following-sibling::label[child::b[text()='#{type}']]]").set(true) 5 | click_button "OK" 6 | end 7 | 8 | When /^I should see "([^"]*)" view as a subview of the view$/ do |name| 9 | @view.open 10 | page.should have_xpath("//table[@id='projectstatus']//a[text()='#{name}']") 11 | end 12 | 13 | When /^I configure subview "([^"]*)" as a default of the view$/ do |name| 14 | visit(@view.configure_url) 15 | find(:xpath, "//select[@name='defaultView']/option[text()='#{name}']").click 16 | end 17 | 18 | Then /^I should see "([^"]*)" subview as an active view$/ do |name| 19 | @view.open 20 | page.should have_xpath("//table[@id='viewList']//td[@class='active' and text()='#{name}']") 21 | end 22 | 23 | Then /^I should see "([^"]*)" subview as an inactive view$/ do |name| 24 | @view.open 25 | page.should have_xpath("//table[@id='viewList']//td[contains(@class,'inactive')]/a[text()='#{name}']") 26 | end 27 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/plot_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I add plot "(.*?)" in group "(.*?)"$/ do |title, group| 2 | @plot_step = @job.add_postbuild_step 'Plot' 3 | @plot_step.group = group 4 | @plot_step.title = title 5 | end 6 | 7 | When /^I configure csv data source "(.*?)"$/ do |path| 8 | @plot_step.source('csv', path) 9 | end 10 | 11 | Then /^there should be a plot called "(.*?)" in group "(.*?)"$/ do |title, group| 12 | @job.last_build.wait_until_finished 13 | visit @job.url + '/plot' 14 | page.should have_xpath "//h1[contains(text(), '#{group}')]" 15 | page.should have_xpath "//select[@name='choice']/option[contains(text(), '#{title}')]" 16 | end 17 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/pmd_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I set path to the pmd result "([^"]*)"$/ do |path| 2 | find(:xpath, "//div[@descriptorid='hudson.plugins.pmd.PmdPublisher']//input[@name='_.pattern']").set(path) 3 | end 4 | 5 | Then /^build page should has pmd summary "([^"]*)"$/ do |content| 6 | @job.last_build.open 7 | page.should have_content "#{content}" 8 | end 9 | 10 | Then /^I set publish always pdm$/ do 11 | find(:xpath, "//div[@descriptorid='hudson.plugins.pmd.PmdPublisher']//button[text()='Advanced...']").click 12 | find(:xpath, "//div[@descriptorid='hudson.plugins.pmd.PmdPublisher']//input[@name='canRunOnFailed']").set(true) 13 | end 14 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/postbuildscript_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I add marker post-build script$/ do 2 | 3 | @marker = Jenkins::PageObject.random_name 4 | 5 | @job.configure do 6 | postBuildStep = Plugins::PostBuildScript::Publisher.add(@job) 7 | shell_step = postBuildStep.add_step 'Shell' 8 | shell_step.command "echo '#{@marker}'" 9 | end 10 | end 11 | 12 | When /^I allow the script to run only for builds that (failed|succeeded)$/ do |status| 13 | 14 | checkboxes = { 15 | 'failed' => 'scriptOnlyIfFailure', 16 | 'succeeded' => 'scriptOnlyIfSuccess', 17 | } 18 | 19 | @job.configure do 20 | check checkboxes[status] 21 | end 22 | end 23 | 24 | Then /^the post-build script (should|should not) have been executed$/ do |should_or_not| 25 | @job.last_build.console.send should_or_not, include(@marker) 26 | end 27 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/priority_sorter_plugin_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I configure absolute sorting strategy with (\d+) priorities$/ do |num| 2 | global = Jenkins::Plugin::PrioritySorter::Global.new @jenkins 3 | $jenkins.configure do 4 | global.strategy = 'Absolute' 5 | global.priorities = num.to_i 6 | end 7 | end 8 | 9 | When /^I set priority (\d+) for job "(.*?)"$/ do |priority, job_name| 10 | page = Jenkins::Plugin::PrioritySorter::Page.new 11 | page.configure do 12 | group = page.add_group 13 | group.priority = priority 14 | group.pattern = job_name 15 | end 16 | end 17 | 18 | When /^I set priority (\d+) for view "(.*?)"$/ do |priority, view_name| 19 | page = Jenkins::Plugin::PrioritySorter::Page.new 20 | page.configure do 21 | group = page.add_group 22 | group.priority = priority 23 | group.view = view_name 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/project_description_setter_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I setup project description from the file "([^"]*)" in workspace/ do |file_name| 2 | find(:path, "/org-jenkinsCi-plugins-projectDescriptionSetter-DescriptionSetterWrapper").set(true) 3 | find(:path, "/org-jenkinsCi-plugins-projectDescriptionSetter-DescriptionSetterWrapper/projectDescriptionFilename").set(file_name) 4 | end 5 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/scp_steps.rb: -------------------------------------------------------------------------------- 1 | # scp plugin: https://wiki.jenkins-ci.org/display/JENKINS/SCP+plugin 2 | 3 | When /^I configure docker fixture as SCP site$/ do 4 | @jenkins_config = Jenkins::JenkinsConfig.get(@base_url, 'Jenkins global configuration') 5 | @jenkins_config.configure do 6 | Plugins::SCP::GlobalConfig.add("localhost",@docker[:default].port(22),"/tmp","test","test","") 7 | end 8 | end 9 | 10 | When /^I publish "([^"]*)" with SCP plugin$/ do |files| 11 | step = @job.add_postbuild_step('Publish artifacts to SCP Repository') 12 | step.add(files, files) 13 | end 14 | 15 | When /^SCP plugin should have published "([^"]*)" on docker fixture$/ do |name| 16 | @docker[:default].cp "/tmp/#{name}","/tmp" 17 | # TODO: md5sum check? 18 | end 19 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/scriptler_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I upload script "([^"]+)"$/ do |local_path| 2 | @scriptler = Jenkins::Scriptler::Page.new(@base_url) 3 | @script = @scriptler.upload_script_from local_path 4 | end 5 | 6 | When /^I create script$/ do |script| 7 | @scriptler = Jenkins::Scriptler::Page.new(@base_url) 8 | name = Jenkins::PageObject.random_name 9 | @script = @scriptler.create_script name, script 10 | end 11 | 12 | When /^I delete script "([^"]+)"$/ do |id| 13 | @scriptler.get_script(id).delete 14 | end 15 | 16 | When /^I run the script$/ do 17 | @script.run 18 | end 19 | 20 | When /^I run the script on ([^"]+)/ do |node| 21 | @script.run on: transform(node) 22 | end 23 | 24 | When /^I run parameterized script with:$/ do |table| 25 | @script.run with: table.rows_hash 26 | end 27 | 28 | When /^I add script parameters:$/ do |table| 29 | @script.set_parameters table.rows_hash 30 | end 31 | 32 | 33 | Then /^the script output should match "([^"]+)"$/ do |output| 34 | @script.output.should match /#{Regexp.escape(output)}/ 35 | end 36 | 37 | Then /^script "([^"]+)" (should|should not) exist$/ do |id, should_or_not| 38 | @scriptler.get_script(id).send should_or_not, exist 39 | end 40 | 41 | Then /^the script output on (.+?) should match "([^"]+)"$/ do |node, output| 42 | @script.output.should include "\n[#{transform(node)}]:\n#{output}" 43 | end 44 | 45 | Then /^the script should not be run on (.+?)$/ do |node| 46 | @script.output.should_not include "\n[#{transform(node)}]:\n" 47 | end 48 | 49 | def transform(node_specifier) 50 | 51 | return node_specifier unless node_specifier =~ /^(master|all slaves|all nodes)$/ 52 | 53 | if node_specifier == 'all nodes' 54 | node_specifier = 'all' 55 | end 56 | 57 | return "(#{node_specifier})" 58 | end 59 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/subversion_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I check out code from Subversion repository "([^"]*)"$/ do |url| 2 | @svnscm = @job.add_scm 'Subversion' 3 | @svnscm.url url 4 | end 5 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/timestamper_steps.rb: -------------------------------------------------------------------------------- 1 | Given /^a job inserting timestamps$/ do 2 | step "a job" 3 | 4 | @job.configure do 5 | find(:path, '/hudson-plugins-timestamper-TimestamperBuildWrapper').check 6 | end 7 | end 8 | 9 | When /^I set "([^"]+)" as (system time|elapsed time) timestamp format$/ do |format, kind| 10 | @jenkins = Jenkins::JenkinsConfig.get(@base_url, 'Jenkins global configuration') 11 | 12 | paths = { 13 | 'system time' => '/hudson-plugins-timestamper-TimestamperConfig/systemTimeFormat', 14 | 'elapsed time' => '/hudson-plugins-timestamper-TimestamperConfig/elapsedTimeFormat' 15 | } 16 | 17 | @jenkins.configure do 18 | find(:path, paths[kind]).set(format) 19 | end 20 | end 21 | 22 | When /^I select (system time|elapsed time|no) timestamps$/ do |kind| 23 | visit @job.last_build.console_url 24 | 25 | paths = { 26 | 'system time' => 'timestamper-systemTime', 27 | 'elapsed time' => 'timestamper-elapsedTime', 28 | 'no' => 'timestamper-none' 29 | } 30 | 31 | choose paths[kind] 32 | end 33 | 34 | Then /^console timestamps matches regexp "([^"]+)"$/ do |pattern| 35 | timestamps_should match pattern 36 | end 37 | 38 | Then /^there are no timestamps in the console$/ do 39 | timestamps_should be_empty 40 | end 41 | 42 | def timestamps_should(match_condition) 43 | page.all(:xpath, '//pre/span[@class="timestamp"]').each { |timestamp| 44 | timestamp.text.should match_condition 45 | } 46 | end 47 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/violations_step.rb: -------------------------------------------------------------------------------- 1 | When /^I configure violations reporting$/ do 2 | if @job.is_a? Jenkins::MavenJob 3 | find(:path, '/hudson-plugins-violations-hudson-maven-ViolationsMavenReporter').check 4 | else 5 | @job.add_postbuild_action 'Report Violations' 6 | end 7 | end 8 | 9 | When /^I set "([^"]+)" reporter applied at "([^"]+)"$/ do |kind, pattern| 10 | find(:xpath, "//input[@name='#{kind}.pattern']").set(pattern) 11 | end 12 | 13 | Then /^there should be (\d+) "([^"]+)" violations in (\d+) files$/ do |count, kind, file_count| 14 | step %{I visit build action named "Violations"} 15 | assert_violations count, kind, file_count 16 | end 17 | 18 | Then /^there should be (\d+) "([^"]+)" violations in (\d+) files for module "([^"]+)"$/ do |count, kind, file_count, module_name| 19 | module_url = @job.last_build.wait_until_finished.module(module_name).url 20 | 21 | visit "#{module_url}/violations" 22 | 23 | assert_violations count, kind, file_count 24 | end 25 | 26 | private 27 | def assert_violations(count, kind, file_count) 28 | row = find(:xpath, "//td//a[@href='##{kind}' and text()='#{kind}']/../..") 29 | violations = row.find(:xpath, "./td[2]").text.to_i 30 | files = row.find(:xpath, "./td[3]").text.to_i 31 | 32 | violations.should eq(count.to_i) 33 | files.should eq(file_count.to_i) 34 | end 35 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/warnings_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I add console parser for "([^"]*)"$/ do |tool| 2 | find(:path, '/publisher/repeatable-add').click 3 | find(:xpath, "//select[@path='/publisher/consoleParsers/parserName']/option[text()='#{tool}']") 4 | .select_option 5 | end 6 | 7 | When /^I add workspace parser for "([^"]*)" applied at "([^"]*)"$/ do |tool, pattern| 8 | find(:path, '/publisher/repeatable-add[1]').click 9 | find(:path, '/publisher/parserConfigurations/pattern').set(pattern) 10 | find(:xpath, "//select[@path='/publisher/parserConfigurations/parserName']/option[text()='#{tool}']") 11 | .select_option 12 | end 13 | 14 | 15 | Then /^build should have (\d+) "([^"]+)" warnings?$/ do |count, tool| 16 | @job.last_build.wait_until_finished 17 | 18 | should_or_not = count.to_i > 0 ? 'should' : 'should not' 19 | 20 | step %{the job #{should_or_not} have "#{tool} Warnings" action} 21 | step %{the build #{should_or_not} have "#{tool} Warnings" action} 22 | @job.last_build.open 23 | step %{the page should say "#{tool} Warnings: #{count}"}; 24 | end 25 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/ws_cleanup_steps.rb: -------------------------------------------------------------------------------- 1 | Then /^there (should|should not) be "([^"]*)" in the workspace$/ do |should_or_not, filename| 2 | @job.last_build.wait_until_finished 3 | @job.workspace.contains(filename).send should_or_not, eql(true), "Artifact not present" 4 | end 5 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/xunit_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I publish "(.*?)" report from "(.*?)"$/ do |kind, path| 2 | xunit = @job.add_postbuild_step 'xUnit' 3 | junit = xunit.add_tool kind 4 | junit.pattern = path 5 | end 6 | 7 | Then /^the job page should contain test result trend chart$/ do 8 | @job.open 9 | page.should have_xpath '//img[@alt="[Test result trend chart]"]' 10 | end 11 | -------------------------------------------------------------------------------- /features/step_definitions/plugins/xvnc_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I let xvnc run during the build$/ do 2 | find(:path, '/hudson-plugins-xvnc-Xvnc').check 3 | end 4 | 5 | When /^I let xvnc run during the build taking screanshot at the end$/ do 6 | step 'I let xvnc run during the build' 7 | find(:path, '/hudson-plugins-xvnc-Xvnc/takeScreenshot').check 8 | end 9 | 10 | When /^I set xvnc display number to (\d+)$/ do |displayNumber| 11 | jenkins = Jenkins::JenkinsConfig.get(@base_url, 'Jenkins global configuration') 12 | jenkins.configure do 13 | # xvnc 1.11 and earlier 14 | # find(:path, '/hudson-plugins-xvnc-Xvnc/baseDisplayNumber').set(displayNumber) 15 | find(:path, '/hudson-plugins-xvnc-Xvnc/minDisplayNumber').set(displayNumber) 16 | find(:path, '/hudson-plugins-xvnc-Xvnc/maxDisplayNumber').set(displayNumber) 17 | end 18 | end 19 | 20 | Then /^xvnc run during the build$/ do 21 | console = @job.last_build.console 22 | console.should have_content 'Starting xvnc' 23 | console.should have_content 'Killing Xvnc process ID' 24 | end 25 | 26 | Then /^took a screanshot$/ do 27 | @job.last_build.console.should have_content 'Taking screenshot' 28 | step %{the artifact "screenshot.jpg" should be archived} 29 | end 30 | 31 | Then /^used display number (\d+)$/ do |displayNumber| 32 | @job.last_build.console.should have_content " :#{displayNumber} " 33 | end 34 | -------------------------------------------------------------------------------- /features/step_definitions/script_steps.rb: -------------------------------------------------------------------------------- 1 | When /^I execute system script$/ do |script| 2 | visit $jenkins.base_url + '/script' 3 | run script 4 | end 5 | 6 | When /^I execute system script on "(.*?)"$/ do |computer, script| 7 | visit $jenkins.node(computer).url + '/script' 8 | run script 9 | end 10 | 11 | When /^the system script output should match "(.*?)"$/ do |expected| 12 | find(:css, 'h2 + pre').text.should == expected 13 | end 14 | 15 | def run(script) 16 | textarea = Jenkins::Util::CodeMirror.new(page, '/script') 17 | textarea.set_content script 18 | 19 | click_button 'Run' 20 | end 21 | -------------------------------------------------------------------------------- /features/step_definitions/slave_steps.rb: -------------------------------------------------------------------------------- 1 | Given /^a dumb slave$/ do 2 | @slave = Jenkins::Slave.named_slave(@base_url, Jenkins::Slave.random_name) 3 | end 4 | 5 | Given /^a slave named "([^"]*)"$/ do |name| 6 | @slave = Jenkins::Slave.named_slave(@base_url, name) 7 | end 8 | 9 | 10 | When /^I create dumb slave named "([^"]*)"$/ do |name| 11 | @slave = Jenkins::Slave.named_slave(@base_url, name) 12 | end 13 | 14 | When /^I add the label "([^"]*)" to the slave$/ do |label| 15 | @slave.configure do 16 | @slave.labels = label 17 | end 18 | end 19 | 20 | When /^I set the executors to "([^"]*)"$/ do |count| 21 | @slave.configure do 22 | @slave.executors = count 23 | end 24 | end 25 | 26 | 27 | Then /^the job should be tied to the "([^"]*)" label$/ do |label| 28 | visit("/label/#{label}") 29 | step %{the page should say "#{@job.name}"} 30 | end 31 | 32 | Then /^the job should be tied to the slave$/ do 33 | step %{the job should be tied to the "#{@slave.name}" label} 34 | end 35 | 36 | Then /^the build should run on the slave$/ do 37 | @job.last_build.wait_until_finished.node.should eq @slave.name 38 | end 39 | 40 | Then /^the build should run on "(.*?)"$/ do |name| 41 | @job.last_build.wait_until_finished.node.should eq name 42 | end 43 | 44 | Then /^the build #(\d+) should run on "(.*?)"$/ do |number, name| 45 | @job.build(number).wait_until_finished.node.should eq name 46 | end 47 | 48 | Then /^I should see "([^"]*)" executors configured$/ do |count| 49 | visit("/computer/#{@slave.name}") 50 | @slave.executor_count.should == count.to_i 51 | end 52 | 53 | Then /^jobs should be executed in order on the slave$/ do |table| 54 | visit @slave.url + '/builds' 55 | page.text.should match table.raw[0].reverse.join('.*') 56 | end 57 | -------------------------------------------------------------------------------- /features/step_definitions/view_steps.rb: -------------------------------------------------------------------------------- 1 | Given /^a view$/ do 2 | step %{a view named "#{Jenkins::View.random_name}"} 3 | end 4 | 5 | Given /^a view named "(.*?)"$/ do |name| 6 | @view = Jenkins::View.create_view(@base_url, name, "List View") 7 | end 8 | 9 | When /^I create a view with a type "([^"]*)" and name "([^"]*)"$/ do |type, name| 10 | @view = Jenkins::View.create_view(@base_url, name, type) 11 | end 12 | 13 | When /^I create a view named "(.*?)"$/ do |name| 14 | @view = Jenkins::View.create_view(@base_url, name, "List View") 15 | end 16 | 17 | When /^I create job "(.*?)" in the view$/ do |name| 18 | @job = Jenkins::Job.create_named 'FreeStyle', @view.url, name 19 | end 20 | 21 | When /^I save the view$/ do 22 | click_button "OK" 23 | end 24 | 25 | When /^I visit the view page$/ do 26 | @view.open 27 | end 28 | 29 | When /^I build "([^"]*)" in view$/ do |job| 30 | if @view.nil? 31 | visit @base_url 32 | else 33 | @view.open 34 | end 35 | 36 | find(:xpath, "//a[contains(@href, '/#{job}/build?')]/img[contains(@title, 'Schedule a build')]").click 37 | end 38 | 39 | Then /^I should see the view on the main page$/ do 40 | visit(@base_url) 41 | page.should have_xpath("//table[@id='viewList']//a[text()='#{@view.name}']") 42 | end 43 | -------------------------------------------------------------------------------- /features/subversion_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Subversion support 2 | As a user 3 | I want to be able to check out source code from Subversion 4 | 5 | Scenario: Run basic Subversion build 6 | Given I have installed the "subversion" plugin 7 | And a job 8 | When I check out code from Subversion repository "https://svn.jenkins-ci.org/trunk/jenkins/test-projects/model-ant-project/" 9 | And I add a shell build step "test -d .svn" 10 | And I save the job 11 | And I build the job 12 | Then the build should succeed 13 | And console output should contain "test -d .svn" 14 | 15 | Scenario: Check out specified Subversion revision 16 | Given I have installed the "subversion" plugin 17 | And a job 18 | When I check out code from Subversion repository "https://svn.jenkins-ci.org/trunk/jenkins/test-projects/model-ant-project@40156" 19 | And I save the job 20 | And I build the job 21 | Then the build should succeed 22 | And console output should contain "At revision 40156" 23 | 24 | Scenario: Always check out fresh copy 25 | Given I have installed the "subversion" plugin 26 | And a job 27 | When I check out code from Subversion repository "https://svn.jenkins-ci.org/trunk/jenkins/test-projects/model-ant-project" 28 | And I select "Always check out a fresh copy" as a "Check-out Strategy" 29 | And I save the job 30 | And I build 2 jobs 31 | Then the build should succeed 32 | And console output should contain "Checking out https://svn.jenkins-ci.org/trunk/jenkins/test-projects/model-ant-project" 33 | -------------------------------------------------------------------------------- /features/support/env.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # vim: tabstop=2 expandtab shiftwidth=2 3 | 4 | $LOAD_PATH.push File.dirname(__FILE__) + "/../../lib" 5 | 6 | require 'capybara/cucumber' 7 | require 'sauce/cucumber' 8 | require 'jenkins/cucumber' 9 | require 'jenkins/env' 10 | -------------------------------------------------------------------------------- /features/support/hooks.rb: -------------------------------------------------------------------------------- 1 | # This is not loaded by cucumber in dryrun mode 2 | require File.dirname(__FILE__) + '/env.rb' 3 | 4 | controller_factory = JenkinsControllerFactory.get 5 | 6 | Before do |scenario| 7 | # in case we are using Sauce, set the test name 8 | Sauce.config do |c| 9 | c[:name] = Sauce::Capybara::Cucumber.name_from_scenario(scenario) 10 | end 11 | 12 | @cleanup = [] # procs/lambdas that are run for cleanup 13 | at_exit do # in case VM got aborted before it gets to 'After' 14 | @cleanup.each { |c| c.call() } 15 | end 16 | end 17 | 18 | Before("~@nojenkins") do |scenario| 19 | # skip scenario and initialization when not applicable 20 | next if scenario.skip_not_applicable 21 | 22 | @runner = controller_factory.create(@controller_options||{}) 23 | @runner.start 24 | $jenkins = Jenkins::JenkinsRoot.new @runner 25 | 26 | @cleanup << Proc.new do 27 | @runner.stop # if test fails, stop in at_exit is not called 28 | @runner.teardown 29 | @runner = nil 30 | end 31 | 32 | @base_url = @runner.url 33 | Capybara.app_host = @base_url 34 | 35 | scenario.skip_not_applicable @runner 36 | end 37 | 38 | After do |scenario| 39 | @cleanup.each { |c| c.call() } 40 | @cleanup.clear 41 | end 42 | 43 | After("~@nojenkins") do |scenario| 44 | @runner.diagnose if @runner && scenario.failed? 45 | end 46 | -------------------------------------------------------------------------------- /features/timestamper_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Timestamper support 2 | In order to have more informative build logs 3 | As a Jenkins user 4 | I want to decorate console log entries with timestamps 5 | 6 | Background: 7 | Given I have installed the "timestamper" plugin 8 | And a job inserting timestamps 9 | 10 | Scenario: Display no timestamps 11 | When I build the job 12 | And I select no timestamps 13 | Then there are no timestamps in the console 14 | 15 | Scenario: Display system time timestamps 16 | When I build the job 17 | And I select system time timestamps 18 | Then console timestamps matches regexp "\d\d:\d\d:\d\d" 19 | 20 | Scenario: Display elapsed time timestamps 21 | When I build the job 22 | And I select elapsed time timestamps 23 | Then console timestamps matches regexp "\d\d:\d\d:\d\d.\d\d\d" 24 | 25 | Scenario: Display specific system time timestamps 26 | When I set "'At 'HH:mm:ss' system time'" as system time timestamp format 27 | And I build the job 28 | And I select system time timestamps 29 | Then console timestamps matches regexp "At \d\d:\d\d:\d\d system time" 30 | 31 | Scenario: Display specific elapsed time timestamps 32 | When I set "'Exactly 'HH:mm:ss.S' after launch'" as elapsed time timestamp format 33 | And I build the job 34 | And I select elapsed time timestamps 35 | Then console timestamps matches regexp "Exactly \d\d:\d\d:\d\d.\d\d\d after launch" 36 | -------------------------------------------------------------------------------- /features/violations_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Add violations support 2 | In order to be able to detect violation 3 | As a Jenkins user 4 | I want to configure, collect and visualize violations 5 | 6 | Scenario: Report violations in FreeStyle project 7 | Given I have installed the "violations" plugin 8 | And a job 9 | When I configure the job 10 | And I copy resource "violations_plugin/*" into workspace 11 | And I configure violations reporting 12 | And I set "fxcop" reporter applied at "fxcop/*" 13 | And I save the job 14 | And I build the job 15 | Then the build should have "Violations" action 16 | And the job should have "Violations" action 17 | And there should be 2 "fxcop" violations in 2 files 18 | 19 | Scenario: Report violations in Maven project 20 | Given I have installed the "violations" plugin 21 | And I have default Maven configured 22 | And a Maven job 23 | When I configure the job 24 | And I copy resource "violations_plugin/*" into workspace 25 | And I configure violations reporting 26 | And I set "fxcop" reporter applied at "fxcop/*" 27 | And I save the job 28 | And I build the job 29 | Then the build should have "Violations" action 30 | And the job should have "Violations" action 31 | And there should be 2 "fxcop" violations in 2 files for module "gid$example" 32 | -------------------------------------------------------------------------------- /features/warnings_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Adds Warnings collection support 2 | In order to be able to collect and analyze warnings 3 | As a Jenkins user 4 | I want to install and configure Warnings plugin 5 | 6 | Scenario: Detect no errors in console log and workspace when there are none 7 | Given I have installed the "warnings" plugin 8 | And a job 9 | When I configure the job 10 | And I add "Scan for compiler warnings" post-build action 11 | And I add console parser for "Maven" 12 | And I add workspace parser for "Java Compiler (javac)" applied at "**/*" 13 | And I save the job 14 | And I build the job 15 | Then build should have 0 "Java" warnings 16 | Then build should have 0 "Maven" warnings 17 | 18 | Scenario: Detect errors in console log 19 | Given I have installed the "warnings" plugin 20 | And a job 21 | When I configure the job 22 | And I add "Scan for compiler warnings" post-build action 23 | And I add console parser for "Maven" 24 | And I add a shell build step "mvn clean install || true" 25 | And I save the job 26 | And I build the job 27 | Then build should have 1 "Maven" warning 28 | 29 | Scenario: Detect errors in workspace 30 | Given I have installed the "warnings" plugin 31 | And a job 32 | When I configure the job 33 | And I add "Scan for compiler warnings" post-build action 34 | And I add workspace parser for "Java Compiler (javac)" applied at "**/*" 35 | And I add a shell build step 36 | """ 37 | echo '@Deprecated class a {} class b extends a {}' > a.java 38 | javac -Xlint a.java 2> out.log || true 39 | """ 40 | And I save the job 41 | And I build the job 42 | Then build should have 1 "Java" warning 43 | 44 | Scenario: Do not detect errors in ignored parts of the workspace 45 | Given I have installed the "warnings" plugin 46 | And a job 47 | When I configure the job 48 | And I add "Scan for compiler warnings" post-build action 49 | And I add workspace parser for "Maven" applied at "no_errors_here.log" 50 | And I add a shell build step "mvn clean install > errors.log || true" 51 | And I save the job 52 | And I build the job 53 | Then build should have 0 "Maven" warning 54 | -------------------------------------------------------------------------------- /features/ws_cleanup_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Cleanup job workspace 2 | As a Jenkins user 3 | I want to automatically cleanup my workspace 4 | 5 | Scenario: Do not clean up by default 6 | Given I have installed the "ws-cleanup" plugin 7 | And a simple job 8 | When I configure the job 9 | And I add a shell build step "touch artifact" 10 | And I save the job 11 | And I build the job 12 | Then there should be "artifact" in the workspace 13 | 14 | Scenario: Clean up after build 15 | Given I have installed the "ws-cleanup" plugin 16 | And a simple job 17 | When I configure the job 18 | And I add a shell build step "touch artifact" 19 | And I add "Delete workspace when build is done" post-build action 20 | And I save the job 21 | And I build the job 22 | Then there should not be "artifact" in the workspace 23 | 24 | Scenario: Clean up before build 25 | Given I have installed the "ws-cleanup" plugin 26 | And a simple job 27 | When I configure the job 28 | And I check the "hudson-plugins-ws_cleanup-PreBuildCleanup" checkbox 29 | # Creating directory that already exists would fail the build 30 | And I add a shell build step "mkdir artifact.d" 31 | And I save the job 32 | And I build 2 jobs 33 | Then the build should succeed 34 | And there should be "artifact.d" in the workspace 35 | 36 | -------------------------------------------------------------------------------- /features/xunit_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Add xUnit support 2 | 3 | Scenario: Publish xUnit results 4 | Given I have installed the "xunit" plugin 5 | And a job 6 | When I configure the job 7 | And I copy resource "junit/failure" into workspace 8 | And I publish "JUnit" report from "failure/TEST*.xml" 9 | And I save the job 10 | And I build 2 jobs 11 | Then the build should succeed 12 | And I visit build action named "Test Result" 13 | Then the page should say "1 failures" 14 | And the job page should contain test result trend chart 15 | -------------------------------------------------------------------------------- /features/xvnc_plugin.feature: -------------------------------------------------------------------------------- 1 | Feature: Adds Xvnc support 2 | In order to be able to run Xvnc based builds 3 | As a Jenkins user 4 | I want to able to setup Xvnc server 5 | 6 | @native(vncserver) 7 | Scenario: Run xvnc during build 8 | Given I have installed the "xvnc" plugin 9 | And a job 10 | When I configure the job 11 | And I let xvnc run during the build 12 | And I save the job 13 | And I build the job 14 | Then the build should succeed 15 | And xvnc run during the build 16 | 17 | @native(vncserver,import) 18 | Scenario: Run xvnc during build taking screenshot at the end 19 | Given I have installed the "xvnc" plugin 20 | And a job 21 | When I configure the job 22 | And I let xvnc run during the build taking screanshot at the end 23 | And I save the job 24 | And I build the job 25 | Then the build should succeed 26 | And xvnc run during the build 27 | And took a screanshot 28 | 29 | @native(vncserver) 30 | Scenario: Run xvnc on specific display number 31 | Given I have installed the "xvnc" plugin 32 | And a job 33 | When I set xvnc display number to 42 34 | And I configure the job 35 | And I let xvnc run during the build 36 | And I save the job 37 | And I build the job 38 | Then the build should succeed 39 | And xvnc run during the build 40 | And used display number 42 41 | -------------------------------------------------------------------------------- /fixtures/jira/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Runs JIRA 3 | # 4 | # The initial password is 'admin:admin' 5 | # 6 | FROM ubuntu 7 | 8 | # base package installation 9 | RUN apt-get install -y apt-transport-https && echo "deb https://sdkrepo.atlassian.com/debian/ stable contrib" >> /etc/apt/sources.list && apt-get update 10 | RUN apt-get install -y --allow-unauthenticated openjdk-6-jdk atlassian-plugin-sdk netcat 11 | 12 | # this will install the whole thing, launches Tomcat, 13 | # asks the user to do Ctrl+C to quit, then it shuts down presumably because it 14 | # fails to read from stdin? 15 | RUN atlas-run-standalone --product jira < /dev/null 16 | 17 | # unlike the above command, this launches Tomcat then hangs, because it feeds its own tail 18 | # and so stdin will block 19 | CMD atlas-run-standalone --product jira < /dev/stderr 20 | 21 | -------------------------------------------------------------------------------- /fixtures/jira/jira.rb: -------------------------------------------------------------------------------- 1 | require 'jiraSOAP' 2 | 3 | module Jenkins 4 | module Fixtures 5 | # Represents the JIRA instance 6 | class JIRA < Fixture 7 | # block until JIRA becomes ready 8 | def wait_for_ready 9 | print "Waiting for JIRA to be ready... " 10 | STDOUT.flush 11 | 12 | start = Time.now.to_i 13 | Capybara.current_session.tap do |c| 14 | while true 15 | c.visit url 16 | if c.title =~ /System Dashboard/ 17 | puts " done" 18 | return 19 | end 20 | sleep 1 21 | end 22 | end 23 | end 24 | 25 | # JIRA top URL 26 | # @return [String] 27 | def url 28 | "http://localhost:#{port(2990)}/jira/" 29 | end 30 | 31 | # Create a new project on this JIRA 32 | # @param key [String] all caps ID of this project, like 'JENKINS' 33 | # @param display_name [String] human readable name of this project 34 | def create_project(key,display_name=nil) 35 | jira = soap() 36 | 37 | p = ::JIRA::Project.new() 38 | p.name = display_name || key 39 | p.key = key 40 | p.lead = "admin" 41 | 42 | jira.create_project_with_project p 43 | end 44 | 45 | # Create a new issue 46 | # @return [JIRA::Issue] newly created ticket. Its 'key' property returns the issue ID like JENKINS-12345 47 | def create_issue(key, summary="Test ticket", description="some description") 48 | jira = soap() 49 | 50 | issue = ::JIRA::Issue.new.tap do |i| 51 | i.project_name = key 52 | i.type_id = 1 # Bug 53 | i.priority_id = 1 # whatever 54 | i.summary = summary 55 | i.description = description 56 | end 57 | 58 | i = jira.create_issue_with_issue issue 59 | end 60 | 61 | # Create A JIRA SOAP client 62 | # @return [JIRA::JIRAService] 63 | def soap 64 | @soap if @soap 65 | @soap=::JIRA::JIRAService.new(url).tap { |x| x.login 'admin','admin'} 66 | end 67 | 68 | register "jira", [2990] 69 | end 70 | end 71 | end 72 | -------------------------------------------------------------------------------- /fixtures/jira/test.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'rubygems' 3 | require 'pp' 4 | require 'jira' 5 | 6 | # Consider the use of :use_ssl and :ssl_verify_mode options if running locally 7 | # for tests. 8 | 9 | username = "admin" 10 | password = "admin" 11 | 12 | options = { 13 | :username => username, 14 | :password => password, 15 | :site => 'http://localhost:49153/', 16 | :context_path => '/jira', 17 | :auth_type => :basic, 18 | :use_ssl => false 19 | } 20 | 21 | client = JIRA::Client.new(options) 22 | 23 | # Show all projects 24 | projects = client.Project.all 25 | 26 | projects.each do |project| 27 | puts "Project -> key: #{project.key}, name: #{project.name}" 28 | 29 | end 30 | 31 | 32 | -------------------------------------------------------------------------------- /fixtures/jira/test2.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'jiraSOAP' 3 | 4 | jira = JIRA::JIRAService.new 'http://localhost:49176/jira/' 5 | jira.login 'admin','admin' 6 | 7 | #p = jira.project_with_key 'ABC' 8 | #puts p 9 | #puts p.inspect 10 | 11 | #p = JIRA::Project.new() 12 | #p.name = "API test" 13 | #p.key = "API" 14 | #p.lead_username = "admin" 15 | 16 | #jira.create_project_with_project p 17 | 18 | #issue = JIRA::Issue.new.tap do |i| 19 | # i.project_name = "ABC" 20 | # i.type_id = 1 # Bug 21 | # i.priority_id = 1 # whatever 22 | # i.summary = "Test ticket" 23 | # i.description = "Description" 24 | #end 25 | # 26 | #i = jira.create_issue_with_issue issue 27 | #puts i.key 28 | # 29 | 30 | i = jira.get_issue_with_key "ABC-1" 31 | puts i.inspect 32 | 33 | comments = jira.get_comments_for_issue_with_key "ABC-1" 34 | puts comments[0].body 35 | #comments.each do |c| 36 | # puts c.id 37 | # puts c.body 38 | #end 39 | -------------------------------------------------------------------------------- /fixtures/sshd/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Runs sshd and allow the 'test' user to login 3 | # 4 | 5 | FROM ubuntu 6 | 7 | # install SSHD 8 | RUN apt-get install -y openssh-server 9 | RUN mkdir -p /var/run/sshd 10 | 11 | # create a test user 12 | RUN useradd test -d /home/test && \ 13 | mkdir -p /home/test/.ssh && \ 14 | chown test /home/test && \ 15 | echo "test:test" | chpasswd && \ 16 | echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDzpxmTW9mH87DMkMSqBrSecoSHVCkKbW5IOO+4unak8M8cyn+b0iX07xkBn4hUJRfKA7ezUG8EX9ru5VinteqMOJOPknCuzmUS2Xj/WJdcq3BukBxuyiIRoUOXsCZzilR/DOyNqpjjI3iNb4los5//4aoKPCmLInFnQ3Y42VaimH1298ckEr4tRxsoipsEAANPXZ3p48gGwOf1hp56bTFImvATNwxMViPpqyKcyVaA7tXCBnEk/GEwb6MiroyHbS0VvBz9cZOpJv+8yQnyLndGdibk+hPbGp5iVAIsm28FEF+4FvlYlpBwq9OYuhOCREJvH9CxDMhbOXgwKPno9GyN kohsuke@atlas' > /home/test/.ssh/authorized_keys 17 | 18 | # run SSHD in the foreground with error messages to stderr 19 | CMD /usr/sbin/sshd -D -e 20 | -------------------------------------------------------------------------------- /fixtures/sshd/sshd.rb: -------------------------------------------------------------------------------- 1 | module Jenkins 2 | module Fixtures 3 | # Represents a server with SSHD 4 | class SSHD < Fixture 5 | 6 | # SSH private key to talk to this host 7 | # @return [String] 8 | def private_key 9 | key = SSHD.dir+"/unsafe" # 'self.dir' which might point to subtype 10 | File.chmod(0600,key) 11 | key 12 | end 13 | 14 | # ssh command line 15 | def ssh 16 | "ssh -p #{port(22)} -o StrictHostKeyChecking=no -i #{private_key} test@localhost" 17 | end 18 | 19 | # login with SSH public key and make sure you can connect 20 | def ssh_with_publickey(cmd) 21 | if !system("#{ssh} #{cmd}") 22 | raise "ssh failed!" 23 | end 24 | end 25 | 26 | def ssh_popen(cmd,&block) 27 | IO.popen("exec #{ssh} #{cmd} 2>&1",&block) 28 | end 29 | 30 | register "sshd", [22] 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /fixtures/sshd/unsafe: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEA86cZk1vZh/OwzJDEqga0nnKEh1QpCm1uSDjvuLp2pPDPHMp/ 3 | m9Il9O8ZAZ+IVCUXygO3s1BvBF/a7uVYp7XqjDiTj5Jwrs5lEtl4/1iXXKtwbpAc 4 | bsoiEaFDl7Amc4pUfwzsjaqY4yN4jW+JaLOf/+GqCjwpiyJxZ0N2ONlWoph9dvfH 5 | JBK+LUcbKIqbBAADT12d6ePIBsDn9Yaeem0xSJrwEzcMTFYj6asinMlWgO7VwgZx 6 | JPxhMG+jIq6Mh20tFbwc/XGTqSb/vMkJ8i53RnYm5PoT2xqeYlQCLJtvBRBfuBb5 7 | WJaQcKvTmLoTgkRCbx/QsQzIWzl4MCj56PRsjQIDAQABAoIBAAGTiy7Q4U9n3DT2 8 | ms8ey/xacVEO0lUm8Be3hpWDX1Eh3bUp+jlf2q8C/P5tscwZkVXVQFMAqjc1B42U 9 | Hka3fpT5qLq9D82RuEWu8oF0aUZINaoBdK2i0SWcDXvlv9nvgyxvQPiJqgOOLzF7 10 | D0CGKPrW0urOCNbFmkY4wYMMpOrYXnwb6bc1p7snbzeRigaoGvSgvH7fx2Steg1o 11 | j50C4BKVtXPKQdmckG2SFn0T+U1iCsRG+KNcENX2vX8gyrXImAH093WTjKsmM9et 12 | ddWB+molSnXR/MNrf6BB2mpvXLNyR2/RgBd2jwSQnpDkpms4Br5nek3YYN1dBRL4 13 | 6bofHWECgYEA+7n5OIEbvpMtGxJwOovj0KZMzPkHyQH/DZzo48rS+39goNk/0KLF 14 | c3L3sHbT3Lr4qA/6JOCjlzw7o2AbOrRL4ke1uqcCVQMdDqZdvNezMvTzqEbQGdHD 15 | aFnEcUV2tvEwP11q37ianBRPH5stOnEwQNuv6AJo5LKwi4mTS7qEW9cCgYEA98oJ 16 | h+vMKpXGdJzkSDMzYBrC2tYgqjby6+zGKz8BZ58YecsL+oi2GXBaDTfK+16CKeFM 17 | 8+qQN9Kl1ZNOlk64XJXjt77h0FcFuGe+6rUpM1aEizrf9sWPVZO+QQfhnjsiAhtQ 18 | YX783ydy9rMn1FDPMtNNq4GMhGsFCaL4RupOjjsCgYAnk9XbTHFQRVOSLhP3IIdx 19 | BrSMhZrzv5yaR1FWf00svZozr/SYmP7yZ+EJnaUxzzPJOLnbknYmERJPXYzqbe6A 20 | ZUXtUtTLCPJIm1+hkUhbeqfUjU2qwZA3l+WK6aEAomszizyCcEPexlKqZXt29NTh 21 | XakKkVZsnqujRL4j6e9lgQKBgQDvhD8EQJyAyXgkvoc3dy6BBj019WdrwWO9Q4km 22 | wmdkN3gcOnYgvUdwfZa+UiEGLAub2eldmW3AWADu2s5LIlq5PDX7Jir3DTc9UiNM 23 | ksL5mfbS8p0M11i+uupbx/eB0N0FtktTgsGCH4rUBsdIRriSA4h/cOFYGm6rKvnc 24 | 6p32gwKBgHZYmXzuBWZlWEmPiXbTaI4egJugur5FrT6BJfiLsN2MHBJi9k1IpKEP 25 | SaT+v0IXJ8jP4gSiu4/gyJQpkn7yiMNhwYWlQt+1zyIkHjUsEG82Z8Mqpjx2EJgG 26 | MxDybQux1uk0hyCmMS757WkbTyi0pTWz7PgTIdfmYqhZVV8KRSUi 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /fixtures/sshd/unsafe.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDzpxmTW9mH87DMkMSqBrSecoSHVCkKbW5IOO+4unak8M8cyn+b0iX07xkBn4hUJRfKA7ezUG8EX9ru5VinteqMOJOPknCuzmUS2Xj/WJdcq3BukBxuyiIRoUOXsCZzilR/DOyNqpjjI3iNb4los5//4aoKPCmLInFnQ3Y42VaimH1298ckEr4tRxsoipsEAANPXZ3p48gGwOf1hp56bTFImvATNwxMViPpqyKcyVaA7tXCBnEk/GEwb6MiroyHbS0VvBz9cZOpJv+8yQnyLndGdibk+hPbGp5iVAIsm28FEF+4FvlYlpBwq9OYuhOCREJvH9CxDMhbOXgwKPno9GyN kohsuke@atlas 2 | -------------------------------------------------------------------------------- /fixtures/tomcat7/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Runs Tomcat7 on Ubuntu at port 8080, with the admin app 3 | # 4 | # The admin user has username 'admin' and password 'tomcat' 5 | # 6 | 7 | FROM ubuntu 8 | 9 | # Tomcat7 is from Universe 10 | RUN echo "deb http://archive.ubuntu.com/ubuntu precise universe" >> /etc/apt/sources.list 11 | RUN apt-get update 12 | RUN apt-get install -y tomcat7 tomcat7-admin 13 | 14 | # configure the admin user 15 | RUN echo '' > /etc/tomcat7/tomcat-users.xml 16 | 17 | EXPOSE 8080 18 | CMD CATALINA_BASE=/var/lib/tomcat7/ /usr/share/tomcat7/bin/catalina.sh run 19 | -------------------------------------------------------------------------------- /fixtures/tomcat7/tomcat7.rb: -------------------------------------------------------------------------------- 1 | module Jenkins 2 | module Fixtures 3 | # Represents a server that runs Tomcat7 4 | class Tomcat7 < Fixture 5 | 6 | # Tomcat's URL 7 | # @return [String] 8 | def url 9 | "http://localhost:#{port(8080)}" 10 | end 11 | 12 | register "tomcat7", [8080] 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /fixtures/winstone_docker/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Container for running jenkins.war 3 | # 4 | # See winstone_docker_controller.rb 5 | # 6 | 7 | FROM jenkins/sshd 8 | 9 | # JDK is from Universe 10 | RUN echo deb http://archive.ubuntu.com/ubuntu precise universe >> /etc/apt/sources.list 11 | RUN apt-get update 12 | RUN apt-get install --no-install-recommends -y openjdk-7-jdk curl wget ant maven 13 | -------------------------------------------------------------------------------- /fixtures/winstone_docker/winstone_docker.rb: -------------------------------------------------------------------------------- 1 | module Jenkins 2 | module Fixtures 3 | # Let Jenkins run inside this container 4 | class WinstoneDocker < Fixture.find("sshd") 5 | 6 | register "winstone_docker", [22,8080] 7 | 8 | # when running container, mount the entire host so that we can access jenkins.war anywhere 9 | # @docker_opts = "-v /:/root" 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /grab-latest-rc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -xe 2 | 3 | curl -L "http://mirrors.jenkins-ci.org/war-rc/latest/jenkins.war" > jenkins.war 4 | -------------------------------------------------------------------------------- /jenkins-selenium-tests.gemspec: -------------------------------------------------------------------------------- 1 | require File.expand_path('../lib/jenkins/version', __FILE__) 2 | 3 | Gem::Specification.new do |gem| 4 | gem.authors = ['Jenkins project'] 5 | gem.description = %q{End-to-end test harness for Jenkins} 6 | gem.summary = %q{Ruby + CLOUD = Blimpy} 7 | gem.homepage = "https://github.com/jenkinsci/selenium-tests" 8 | 9 | gem.files = `git ls-files`.split($\) 10 | gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) 11 | gem.name = "jenkins-selenium-tests" 12 | gem.require_paths = ["lib"] 13 | gem.version = Jenkins::VERSION 14 | 15 | gem.add_dependency "rake" 16 | gem.add_dependency "selenium-webdriver" 17 | gem.add_dependency "sauce-cucumber" 18 | gem.add_dependency "rest-client" 19 | gem.add_dependency "pry" 20 | 21 | gem.add_dependency "cucumber", '1.2.5' 22 | gem.add_dependency "capybara", "~> 2.1.0" 23 | gem.add_dependency "json" 24 | gem.add_dependency "rspec" 25 | gem.add_dependency "tempdir" 26 | gem.add_dependency "mail" 27 | gem.add_dependency "promise" 28 | gem.add_dependency "vagrant", '~> 1.0' 29 | gem.add_dependency "jiraSOAP" # for testing JIRA plugin 30 | gem.add_dependency "rdoc" 31 | 32 | gem.add_dependency "aspector" 33 | end 34 | -------------------------------------------------------------------------------- /lib/jenkins/build.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # vim: tabstop=2 expandtab shiftwidth=2 3 | 4 | require 'jenkins/pageobject' 5 | 6 | module Jenkins 7 | class Build < PageObject 8 | attr_accessor :job, :number 9 | 10 | def initialize(base_url, job, number) 11 | @base_url = base_url 12 | @job = job 13 | @number = number 14 | super(base_url, "#{job}/#{number}") 15 | end 16 | 17 | def url 18 | @job.url + "/#{@number}" 19 | end 20 | 21 | def artifact_url(artifact) 22 | url + "/artifact/#{artifact}" 23 | end 24 | 25 | def console_url() 26 | "#{url}/console" 27 | end 28 | 29 | def open 30 | visit(url) 31 | end 32 | 33 | def json_api_url 34 | "#{url}/api/json" 35 | end 36 | 37 | def console 38 | @console ||= begin 39 | visit(console_url) 40 | find(:xpath, "//pre").plain 41 | rescue Capybara::Ambiguous 42 | find(:xpath, "//pre[@id='out']").plain 43 | end 44 | end 45 | 46 | def node 47 | slave = json['builtOn'] 48 | return 'master' if slave == '' 49 | return slave 50 | end 51 | 52 | def result? 53 | wait_until_finished 54 | 55 | @result ||= self.json['result'] 56 | end 57 | 58 | def wait_until_finished 59 | wait_until_started 60 | 61 | while in_progress? 62 | sleep 1 63 | end 64 | 65 | return self 66 | end 67 | 68 | # @return [Jenkins::Build] this object itself 69 | def wait_until_started 70 | wait_for_cond do 71 | has_started? 72 | end 73 | 74 | return self 75 | end 76 | 77 | def succeeded? 78 | result? == 'SUCCESS' 79 | end 80 | 81 | def unstable? 82 | result? == 'UNSTABLE' 83 | end 84 | 85 | def failed? 86 | result? == 'FAILED' 87 | end 88 | 89 | def has_started? 90 | 91 | return true if !@result.nil? 92 | 93 | begin 94 | self.json 95 | return true # We have json. Build has started 96 | rescue Exception 97 | return false 98 | end 99 | end 100 | 101 | def in_progress? 102 | 103 | return false if !@result.nil? 104 | 105 | return false if !has_started? 106 | 107 | data = self.json 108 | return data['building'] || data['result'].nil? 109 | end 110 | 111 | # assert that the build should have succeeded 112 | def should_succeed 113 | succeeded?.should eql(true), "\nConsole output:\n#{console}\n\n" 114 | end 115 | end 116 | end 117 | -------------------------------------------------------------------------------- /lib/jenkins/build_step.rb: -------------------------------------------------------------------------------- 1 | require 'jenkins/step' 2 | 3 | module Jenkins 4 | class BuildStep 5 | include Jenkins::Step 6 | 7 | def self.add(job, title) 8 | select_step label(title), find(:path, '/hetero-list-add[builder]') 9 | 10 | prefix = all(:xpath, "//div[@name='builder']").last[:path] 11 | 12 | return type(title).new(job, prefix) 13 | end 14 | 15 | @@types = Hash.new 16 | 17 | def self.register(title, label) 18 | raise "#{title} already registered" if @@types.has_key? title 19 | 20 | @@types[title] = {type: self, label: label} 21 | end 22 | 23 | def self.get(title) 24 | return @@types[title] if @@types.has_key? title 25 | 26 | raise "Unknown #{self.name.split('::').last} type #{title}. #{@@types.keys}" 27 | end 28 | end 29 | 30 | class ShellBuildStep < BuildStep 31 | 32 | register 'Shell', 'Execute shell' 33 | 34 | def command(text) 35 | control('command').set(text) 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /lib/jenkins/capybara.rb: -------------------------------------------------------------------------------- 1 | require 'aspector' 2 | 3 | # Monkey patching Capybara 4 | module Capybara 5 | module Node 6 | class Element 7 | # Visually navigate to the element in order to interact with it. 8 | # Elements without path attribute are ignored 9 | def locate 10 | path = self[:path] 11 | 12 | if !path.nil? 13 | session.execute_script %{ 14 | // Scroll to the element. It will appear at the top edge of the screen. 15 | element = document.evaluate( 16 | "//*[@path='#{path}']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null 17 | ).singleNodeValue.scrollIntoView(); 18 | 19 | // Scroll a bit back so breadcrumbs are not hiding the element. 20 | window.scrollBy(0, -40); 21 | } 22 | end 23 | return self 24 | end 25 | 26 | def check 27 | ensure_checkable.set(true) 28 | end 29 | 30 | def uncheck 31 | ensure_checkable.set(false) 32 | end 33 | 34 | def plain 35 | native.text 36 | end 37 | 38 | def select(opition) 39 | self.find(:option, opition).select_option 40 | end 41 | 42 | private 43 | def ensure_checkable 44 | type = self[:type] 45 | elementDescription = !type ? tag_name : "#{tag_name} of type #{type}" 46 | 47 | if type != 'checkbox' && type != 'radio' 48 | raise "Element #{elementDescription} is not checkbox nor radio" 49 | end 50 | 51 | return self 52 | end 53 | end 54 | end 55 | end 56 | 57 | # Introduce ':path' selector to find an element with matching path attribute 58 | Capybara.add_selector(:path) do 59 | xpath { |path| XPath.descendant[XPath.attr(:path) == path.to_s] } 60 | end 61 | 62 | # Automatically call .locate after finders returning exactly one result element 63 | aspector(Capybara::Node::Finders) do 64 | logger.level = Aspector::Logging::WARN 65 | 66 | after :find, :first do |element, *args| 67 | return nil if element.nil? 68 | return element.locate 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /lib/jenkins/controller/centos_controller.rb: -------------------------------------------------------------------------------- 1 | %w(vagrant_controller).each { |f| require File.dirname(__FILE__)+"/"+f } 2 | 3 | class CentOSController < VagrantController 4 | register :centos 5 | 6 | def initialize(opts) 7 | super(opts) 8 | @repo_url = opts[:repo_url] || ENV['REPO_URL'] || 'http://pkg.jenkins-ci.org/redhat/jenkins.repo' 9 | end 10 | 11 | # start VM and install RPM package, but only for the first time 12 | def configure 13 | @vm.channel.system_ssh("sudo wget -O /etc/yum.repos.d/jenkins.repo #@repo_url") 14 | @vm.channel.system_ssh("sudo rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key",:error_check=>false) 15 | @vm.channel.system_ssh("sudo yum -y install jenkins curl") 16 | @vm.channel.system_ssh("sudo service iptables stop") 17 | @vm.channel.system_ssh("sudo /etc/init.d/jenkins stop") 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/jenkins/controller/jboss_controller.rb: -------------------------------------------------------------------------------- 1 | %w(local_controller log_watcher).each { |f| require File.dirname(__FILE__)+"/"+f } 2 | 3 | # Runs Jenkins on JBoss 4 | # 5 | # @attr [String] opts 6 | # specify the location of jenkins.war 7 | # @attr [String] jboss_home 8 | # specify the location of JBoss installation 9 | class JBossController < LocalJenkinsController 10 | register :jboss 11 | 12 | def initialize(opts) 13 | super(opts) 14 | 15 | @jboss_home = opts[:jboss_home] || ENV['JBOSS_HOME'] || File.expand_path("./jboss") 16 | raise "#@jboss_home doesn't exist, maybe you forgot to set JBOSS_HOME env var or provide jboss_home parameter? " if !File.directory?(@jboss_home) 17 | end 18 | 19 | def start_process 20 | ENV["JENKINS_HOME"] = @tempdir 21 | FileUtils.rm("#@jboss_home/standalone/deployments/jenkins.war") if File.exists?("#@jboss_home/standalone/deployments/jenkins.war") 22 | FileUtils.rm("#@jboss_home/standalone/deployments/jenkins.war.deployed") if File.exists?("#@jboss_home/standalone/deployments/jenkins.war.deployed") 23 | FileUtils.rm("#@jboss_home/standalone/deployments/jenkins.war.failed") if File.exists?("#@jboss_home/standalone/deployments/jenkins.war.failed") 24 | 25 | FileUtils.cp(@war,"#@jboss_home/standalone/deployments") 26 | @jboss_log = "#@jboss_home/standalone/log/server.log" 27 | FileUtils.rm @jboss_log if File.exists?(@jboss_log) 28 | 29 | IO.popen("#@jboss_home/bin/standalone.sh") 30 | end 31 | 32 | def stop! 33 | system("#@jboss_home/bin/jboss-cli.sh --connect --command=:shutdown") 34 | end 35 | 36 | def url 37 | "http://127.0.0.1:8080/jenkins" 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/jenkins/controller/opensuse_controller.rb: -------------------------------------------------------------------------------- 1 | %w(vagrant_controller).each { |f| require File.dirname(__FILE__)+"/"+f } 2 | 3 | class OpenSUSEController < VagrantController 4 | register :opensuse 5 | 6 | def initialize(opts) 7 | super(opts) 8 | @repo_url = opts[:repo_url] || ENV['REPO_URL'] || 'http://pkg.jenkins-ci.org/opensuse/' 9 | end 10 | 11 | # start VM and install RPM package, but only for the first time 12 | def configure 13 | @vm.channel.system_ssh("sudo zypper addrepo #@repo_url jenkins") 14 | @vm.channel.system_ssh("sudo zypper -n --gpg-auto-import-keys install jenkins") 15 | @vm.channel.system_ssh("sudo /etc/init.d/jenkins stop") 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/jenkins/controller/tomcat_controller.rb: -------------------------------------------------------------------------------- 1 | %w(local_controller log_watcher).each { |f| require File.dirname(__FILE__)+"/"+f } 2 | 3 | # Runs Jenkins on Tomcat 4 | # 5 | # @attr [String] opts 6 | # specify the location of jenkins.war 7 | # @attr [String] catalina_home 8 | # specify the location of Tomcat installation 9 | class TomcatController < LocalJenkinsController 10 | register :tomcat 11 | 12 | def initialize(opts) 13 | super(opts) 14 | @catalina_home = opts[:catalina_home] || ENV['CATALINA_HOME'] || File.expand_path("./tomcat") 15 | raise "#@catalina_home doesn't exist, maybe you forgot to set CATALINA_HOME env var or provide catalina_home parameter? " if !File.directory?(@catalina_home) 16 | end 17 | 18 | def start_process 19 | ENV["JENKINS_HOME"] = @tempdir 20 | FileUtils.rm_rf("#@catalina_home/webapps/jenkins") if Dir.exists?("#@catalina_home/webapps/jenkins") 21 | FileUtils.rm("#@catalina_home/webapps/jenkins.war") if File.exists?("#@catalina_home/webapps/jenkins.war") 22 | FileUtils.cp(@war,"#@catalina_home/webapps") 23 | @tomcat_log = "#@catalina_home/logs/catalina.out" 24 | FileUtils.rm @tomcat_log if File.exists?(@tomcat_log) 25 | 26 | @is_running = system("#@catalina_home/bin/startup.sh") 27 | raise "Cannot start Tomcat" if !@is_running 28 | 29 | IO.popen("tail -f #@tomcat_log") 30 | end 31 | 32 | def stop! 33 | puts 34 | print " Stopping a temporary Jenkins/Tomcat instance\n" 35 | @is_running = !system("#@catalina_home/bin/shutdown.sh") 36 | raise "Cannot stop Tomcat" if @is_running 37 | end 38 | 39 | def url 40 | "http://127.0.0.1:8080/jenkins" 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /lib/jenkins/controller/ubuntu_controller.rb: -------------------------------------------------------------------------------- 1 | %w(vagrant_controller).each { |f| require File.dirname(__FILE__)+"/"+f } 2 | 3 | class UbuntuController < VagrantController 4 | register :ubuntu 5 | 6 | def initialize(opts) 7 | super(opts) 8 | @repo_url = opts[:repo_url] || ENV['REPO_URL'] || 'http://pkg.jenkins-ci.org/debian binary/' 9 | end 10 | 11 | # start VM and install debian package, but only for the first time 12 | def configure 13 | @vm.channel.system_ssh("wget -O - http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add -") 14 | @vm.channel.system_ssh("echo deb #@repo_url > /etc/apt/sources.list.d/jenkins.list", :sudo=>true) 15 | @vm.channel.system_ssh("sudo apt-get update") 16 | @vm.channel.system_ssh("sudo apt-get install -y jenkins curl") 17 | @vm.channel.system_ssh("sudo /etc/init.d/jenkins stop") 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/jenkins/controller/vagrant_controller.rb: -------------------------------------------------------------------------------- 1 | %w(jenkins_controller).each { |f| require File.dirname(__FILE__)+"/"+f } 2 | 3 | # abstract controller that puts Jenkins in a Linux via vagrant 4 | class VagrantController < JenkinsController 5 | 6 | # start VM and install Jenkins 7 | def self.launch 8 | unless @launched 9 | @env = Vagrant::Environment.new({ :ui_class => Vagrant::UI::Colored, 10 | :cwd => "#{File.dirname(__FILE__)}/../../vagrant/#@type" }) 11 | @env.load! 12 | 13 | # start the VM 14 | @env.cli("up") 15 | 16 | @vm = @env.vms[:default] 17 | yield @vm 18 | @launched = true 19 | end 20 | return @vm 21 | end 22 | 23 | # clean up JENKINS_HOME before we start a new Jenkins instance 24 | def wipe 25 | @vm.channel.system_ssh("sudo rm -rf /var/lib/jenkins/*") 26 | end 27 | 28 | def hook_script(name) 29 | if File.exists? name 30 | puts "Running #{name}" 31 | @vm.channel.system_ssh IO.read(name) 32 | end 33 | end 34 | 35 | def start! 36 | @vm = self.class.launch do |vm| 37 | @vm = vm 38 | hook_script "pre-configure.sh" 39 | configure # to be provided by subtypes to actually install Jenkins 40 | hook_script "post-configure.sh" 41 | end 42 | 43 | puts 44 | print " Bringing up a temporary Jenkins instance" 45 | 46 | @vm.channel.system_ssh("sudo kill -9 $(pgrep java) > /dev/null 2>&1", :error_check=>false) 47 | wipe 48 | hook_script "pre-start.sh" 49 | @vm.channel.system_ssh("sudo /etc/init.d/jenkins start") 50 | @pipe = IO.popen("ssh -q -p 2222 -i ~/.vagrant.d/insecure_private_key vagrant@127.0.0.1 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null sudo tail -F /var/log/jenkins/jenkins.log") 51 | @pid = @pipe.pid 52 | 53 | @log_watcher = LogWatcher.new(@pipe,@log) 54 | @log_watcher.wait_for_ready 55 | end 56 | 57 | def teardown 58 | unless @pid.nil? 59 | Process.kill 9,@pid 60 | @pid = nil 61 | end 62 | @log_watcher.close 63 | unless @log.nil? 64 | @log.close 65 | @log = nil 66 | end 67 | end 68 | 69 | def stop! 70 | if @vm 71 | @vm.channel.system_ssh("sudo /etc/init.d/jenkins stop") 72 | end 73 | end 74 | 75 | def url 76 | "http://127.0.0.1:8080" 77 | end 78 | end 79 | -------------------------------------------------------------------------------- /lib/jenkins/controller/winstone_controller.rb: -------------------------------------------------------------------------------- 1 | %w(local_controller log_watcher).each { |f| require File.dirname(__FILE__)+"/"+f } 2 | 3 | # Runs jenkins.war on the same system with built-in Winstone container 4 | class WinstoneJenkinsController < LocalJenkinsController 5 | register :local # backward compatibility 6 | register :winstone 7 | 8 | # @param [Hash] opts 9 | # :war => specify the location of jenkins.war 10 | def initialize(opts) 11 | super(opts) 12 | set_random_ports 13 | end 14 | 15 | def start_process 16 | @process = IO.popen(["exec", "java", 17 | "-DJENKINS_HOME=#{@tempdir}", 18 | "-jar", @war, "--ajp13Port=-1", "--controlPort=#@control_port", 19 | "--httpPort=#@http_port","2>&1"].join(' ')) 20 | end 21 | 22 | def start! 23 | super 24 | rescue RetryException => e 25 | print e.message 26 | STDOUT.flush 27 | set_random_ports 28 | start! 29 | end 30 | 31 | def stop! 32 | TCPSocket.open("localhost", @control_port) do |sock| 33 | sock.write("0") 34 | end 35 | Process.kill("KILL",@pid) 36 | @process.close 37 | end 38 | 39 | def url 40 | "http://127.0.0.1:#@http_port" 41 | end 42 | 43 | private 44 | def set_random_ports 45 | @http_port = random_local_port 46 | @control_port = random_local_port 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /lib/jenkins/controller/winstone_docker_controller.rb: -------------------------------------------------------------------------------- 1 | %w(local_controller log_watcher).each { |f| require File.dirname(__FILE__)+"/"+f } 2 | 3 | # Runs jenkins.war inside docker so that it gets a different IP address 4 | # even though it's run on the same host. 5 | # 6 | # For efficiency, the docker container gets the entire host file system bind-mounted on it, 7 | # and we ssh into that box and start jenkins. 8 | class WinstoneDockerJenkinsController < LocalJenkinsController 9 | register :winstone_docker 10 | 11 | # @param [Hash] opts 12 | # :war => specify the location of jenkins.war 13 | def initialize(opts) 14 | super(opts) 15 | end 16 | 17 | # @return [Jenkins::Fixtures::WinstoneDocker] 18 | def container 19 | @container 20 | end 21 | 22 | def start_process 23 | @war = File.expand_path(File.readlink(@war)) # turn into absolute path 24 | fixture = @opts[:fixture]||"winstone_docker" # fixture to use 25 | 26 | @container = Jenkins::Fixtures::Fixture.find(fixture).start! "-v #{@tempdir}:/work -v #{File.dirname(@war)}:/war" 27 | 28 | @process = @container.ssh_popen(["java","-DJENKINS_HOME=/work", 29 | "-jar", "/war/#{File.basename(@war)}", "--ajp13Port=-1", "--controlPort=8081", 30 | "--httpPort=8080","< /dev/null"].join(' ')) 31 | end 32 | 33 | def stop! 34 | TCPSocket.open(container.ip_address, 8081) do |sock| 35 | sock.write("0") 36 | end 37 | Process.kill("INT",@pid) 38 | @process.close 39 | @container.clean 40 | end 41 | 42 | def url 43 | "http://#{container.ip_address}:8080" 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /lib/jenkins/cucumber.rb: -------------------------------------------------------------------------------- 1 | # Monkey patching Cucumber 2 | module Cucumber 3 | module Ast 4 | # A tag attached to a Feature or a Scenario 5 | # 6 | # In 'asdf(gh, jk)' the 'asdf' part is the name and 'gh' and 'jk' are its values 7 | class Tag 8 | 9 | attr_reader :name, :values 10 | 11 | # Parse tag literal 12 | def self.parse(tag) 13 | m = tag.name.match /^@(\w+)\(([^\)]+)\)$/ 14 | if m.nil? 15 | return m 16 | end 17 | 18 | return Tag.new(m[1], m[2].split(/\s*,\s*/)) 19 | end 20 | 21 | def initialize(name, values) 22 | @name = name 23 | @values = values 24 | end 25 | end 26 | 27 | class Scenario 28 | 29 | def skip_not_applicable(runner=nil) 30 | should_run = if runner.nil? 31 | Jenkins::ScenarioSkipper.should_run? self 32 | else 33 | Jenkins::ScenarioSkipper.should_run_against? self, runner 34 | end 35 | 36 | skip! if !should_run 37 | 38 | return !should_run 39 | end 40 | 41 | def skip! 42 | @steps.each{|step_invocation| step_invocation.skip_invoke!} 43 | end 44 | 45 | def tag(name) 46 | for tagString in tags 47 | tag = Cucumber::Ast::Tag.parse(tagString) 48 | if !tag.nil? && tag.name == name 49 | return tag 50 | end 51 | end 52 | 53 | return nil 54 | end 55 | 56 | def tags 57 | @tags.tags + feature.tags 58 | end 59 | end 60 | 61 | class Feature 62 | 63 | def tags 64 | @tags.tags 65 | end 66 | end 67 | end 68 | end 69 | -------------------------------------------------------------------------------- /lib/jenkins/env.rb: -------------------------------------------------------------------------------- 1 | require 'capybara' 2 | require 'jenkins/capybara' 3 | require 'capybara/session' 4 | require 'selenium-webdriver' 5 | require 'etc' 6 | require 'jenkins/version' 7 | 8 | Capybara.register_driver :selenium do |app| 9 | http_client = Selenium::WebDriver::Remote::Http::Default.new 10 | http_client.timeout = 120 11 | Capybara::Selenium::Driver.new(app, :browser => (ENV['BROWSER'] || :firefox).to_sym, :http_client => http_client) 12 | end 13 | 14 | Capybara.run_server = false 15 | Capybara.default_selector = :css 16 | Capybara.default_driver = :selenium 17 | 18 | if ENV['SAUCE_ACCESS_KEY'] 19 | # TODO: how to select the browser to run the test with? 20 | puts "Using Sauce OnDemand" 21 | Capybara.default_driver = :sauce 22 | Sauce.config do |c| 23 | c[:username] = 'jenkinsci' 24 | c[:start_tunnel] = true 25 | c[:browser_version] = '16' 26 | c['selenium-version'] = '2.26.0' 27 | c['custom-data'] = { :by => Etc.getlogin } 28 | end 29 | end 30 | 31 | # Include Page objects: 32 | PAGE_OBJECTS_BASE = File.dirname(__FILE__) + "/.." 33 | 34 | %w[ 35 | /lib/jenkins/*.rb 36 | /lib/jenkins/controller/*.rb 37 | /lib/jenkins/plugins/*.rb 38 | ]. each do |path| 39 | Dir.glob(Jenkins::ROOTDIR+path).each do |name| 40 | require name 41 | end 42 | end 43 | 44 | -------------------------------------------------------------------------------- /lib/jenkins/jenkins.rb: -------------------------------------------------------------------------------- 1 | require 'jenkins/pluginmanager' 2 | require 'jenkins/job' 3 | 4 | module Jenkins 5 | # 6 | # Top-level object that acts as an entry point to various systems 7 | # 8 | class JenkinsRoot 9 | attr_accessor :base_url 10 | 11 | # @param controller [JenkinsController] encapsulates running Jenkins 12 | def initialize(controller) 13 | @controller = controller 14 | @base_url = controller.url 15 | end 16 | 17 | # @return [JenkinsController] encapsulates running Jenkins 18 | def controller 19 | @controller 20 | end 21 | 22 | # @return [Jenkins::PluginManager] 23 | def plugin_manager 24 | Jenkins::PluginManager.new(@base_url, nil) 25 | end 26 | 27 | def node(name) 28 | if name == 'master' 29 | Jenkins::Master.new(@base_url) 30 | else 31 | Jenkins::Slave.new(@base_url, name) 32 | end 33 | end 34 | 35 | def job(name) 36 | Jenkins::Job.new(@base_url, name) 37 | end 38 | 39 | # create a new job with a random name 40 | # @param title [String] prefix of the display name that indicates the job type to be created. 41 | # @param name [String] the name of the newly created job. leave it to nil to assign a random value 42 | # @return [Jenkins::Job] 43 | def create_job(title, name=nil) 44 | Jenkins::Job.create title, @base_url, name 45 | end 46 | 47 | # Create a page object for the global configuration page 48 | # If a block is passed, it gets called in the context of the global config page object 49 | # @return [Jenkins::JenkinsConfig] 50 | def configure(&block) 51 | config = Jenkins::JenkinsConfig.new(@base_url, 'Jenkins global configuration') 52 | config.configure(&block) if block 53 | config 54 | end 55 | 56 | # @return [LogWatcher] 57 | def log 58 | @controller.log_watcher 59 | end 60 | 61 | def logger(name) 62 | Jenkins::Logger.new name 63 | end 64 | end 65 | 66 | class RestartNeeded < Exception 67 | end 68 | end 69 | -------------------------------------------------------------------------------- /lib/jenkins/jenkins_config.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'jenkins/pageobject' 4 | require 'jenkins/step' 5 | 6 | module Jenkins 7 | # System configuration page 8 | class JenkinsConfig < PageObject 9 | include Jenkins::Step::Static 10 | 11 | def initialize(*args) 12 | super(*args) 13 | end 14 | 15 | def configure_url 16 | @base_url + "/configure" 17 | end 18 | 19 | def configure(&block) 20 | open 21 | unless block.nil? 22 | yield self 23 | save 24 | end 25 | end 26 | 27 | def open 28 | visit(configure_url) 29 | 30 | wait_for_cond do 31 | begin 32 | # wait until the config screen gets fully loaded 33 | !find(:css,"div.behavior-loading").visible? 34 | rescue Capybara::ElementNotFound 35 | # At least in Firefox, element with "display:none" results in element not found 36 | true 37 | end 38 | end 39 | end 40 | 41 | # set the number of executors on the master 42 | def executors=(v) 43 | find(:path, '/jenkins-model-MasterBuildConfiguration/numExecutors').set v.to_s 44 | end 45 | 46 | def add_tool_installer(title) 47 | click_button "Add #{title}" 48 | 49 | type = Jenkins::ToolInstaller.get title 50 | return type.new self 51 | end 52 | 53 | def add_tool(name) 54 | click_button(name) 55 | end 56 | 57 | def add_jdk_auto_installation(name, version) 58 | ensure_config_page 59 | find(:path, "/hudson-model-JDK/tool/name").set(name) 60 | # by default Install automatically is checked 61 | select = find(:path, "/hudson-model-JDK/tool/properties/hudson-tools-InstallSourceProperty/installers/id") 62 | select.find(:xpath, "//option[@value='#{version}']").click 63 | find(:path, "/hudson-model-JDK/tool/properties/hudson-tools-InstallSourceProperty/installers/acceptLicense").click 64 | end 65 | 66 | def enter_oracle_credentials(login, password) 67 | visit("/descriptorByName/hudson.tools.JDKInstaller/enterCredential") 68 | find(:xpath, "//input[@name='username']").set(login) 69 | find(:xpath, "//input[@name='password']").set(password) 70 | click_button("OK") 71 | click_button("Close") 72 | end 73 | 74 | def add_cloud(name) 75 | select_step name, find(:path, '/jenkins-model-GlobalCloudConfiguration/hetero-list-add[cloud]') 76 | # TODO: binding of fragments like BuildStep does 77 | end 78 | 79 | def mailer 80 | return Plugins::Mailer.new(self, '/hudson-tasks-Mailer') 81 | end 82 | 83 | def self.get(base_url, name) 84 | self.new(base_url, name) 85 | end 86 | end 87 | end 88 | -------------------------------------------------------------------------------- /lib/jenkins/logger.rb: -------------------------------------------------------------------------------- 1 | module Jenkins 2 | class Logger < PageObject 3 | 4 | def self.create(name, loggers) 5 | visit $jenkins.base_url + '/log/new' 6 | find(:path, '/name').set name 7 | click_button 'OK' 8 | 9 | loggers.each do |logger, level| 10 | click_button 'Add' 11 | 12 | sleep 1 13 | 14 | all(:xpath, '//input[@name="_.name"]').last.set logger 15 | all(:xpath, '//select[@name="level"]').last.select level 16 | end 17 | 18 | click_button 'Save' 19 | end 20 | 21 | def initialize(name) 22 | super($jenkins.base_url, name) 23 | 24 | begin 25 | sleep 1 26 | open 27 | end until page.has_xpath? "//h1[text()='#{name}']" 28 | end 29 | 30 | def url 31 | base_url + "/log/#{name}/" 32 | end 33 | 34 | def open 35 | visit url 36 | end 37 | 38 | def events 39 | open 40 | events = [] 41 | all(:css, '#main-panel pre').each do |row| 42 | matcher = /((?:\/\w+)+.*?) by /.match(row.text) 43 | next if matcher.nil? # Earlier versions used one element per log entry newer use two 44 | events << matcher[1] 45 | end 46 | 47 | return events 48 | end 49 | 50 | def empty? 51 | open 52 | first(:css, '#main-panel pre').nil? 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /lib/jenkins/pagearea.rb: -------------------------------------------------------------------------------- 1 | module Jenkins 2 | module PageArea 3 | include Capybara::DSL 4 | 5 | def initialize(parent, path_prefix) 6 | @parent = parent 7 | @path_prefix = path_prefix 8 | end 9 | 10 | def path(relative_path) 11 | return "#{@path_prefix}/#{relative_path}" 12 | end 13 | 14 | # Find control on given path relative to the pagearea 15 | # 16 | # Several paths can be provided to find the first matching element. Useful 17 | # when element path changed between versions. 18 | def control(*relative_paths) 19 | exception = nil 20 | for p in relative_paths do 21 | begin 22 | return find :path, path(p) 23 | rescue Capybara::ElementNotFound => e 24 | exception = e 25 | end 26 | end 27 | 28 | raise e 29 | end 30 | 31 | def self.included(receiver) 32 | receiver.extend Capybara::DSL 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /lib/jenkins/parameter.rb: -------------------------------------------------------------------------------- 1 | require 'jenkins/pagearea' 2 | 3 | module Jenkins 4 | class Parameter 5 | include Jenkins::PageArea 6 | 7 | attr_reader :name 8 | 9 | def self.add(job, title) 10 | find(:xpath, "//input[@name='parameterized']").check 11 | find(:xpath, "//button[text()='Add Parameter']").click 12 | find(:xpath, "//a[text()='#{title}']").click 13 | sleep 0.5 14 | prefix = all(:xpath, "//div[@name='parameter']").last[:path] 15 | 16 | return get(title).new(job, prefix) 17 | end 18 | 19 | @@types = Hash.new 20 | 21 | # Register Parameter type 22 | def self.register(title) 23 | @@types[title] = self 24 | end 25 | 26 | # Get type by title 27 | def self.get(title) 28 | return @@types[title] 29 | end 30 | 31 | def name=(name) 32 | @name = name 33 | control('name').set(name) 34 | end 35 | 36 | def description=(description) 37 | control('description').set(value) 38 | end 39 | 40 | def fill_with(value) 41 | raise "To be implemented by a subclass" 42 | end 43 | 44 | #Override 45 | def path(relative_path) 46 | if page.current_url.ends_with? '/configure' 47 | # Path on /configure page 48 | super relative_path 49 | else 50 | # Path on /build page 51 | elem = find(:xpath, "//input[@name='name' and @value='#{name}']", visible: false) 52 | elem[:path].gsub(/\/name$/, '') + '/' + relative_path 53 | end 54 | end 55 | end 56 | 57 | class StringParameter < Parameter 58 | 59 | register 'String Parameter' 60 | 61 | def fill_with(value) 62 | control('value').set value 63 | end 64 | 65 | def default=(value) 66 | control('defaultValue').set(value) 67 | end 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /lib/jenkins/pluginmanager.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # vim: tabstop=2 expandtab shiftwidth=2 3 | 4 | require 'jenkins/pageobject' 5 | 6 | module Jenkins 7 | class PluginManager < PageObject 8 | def initialize(*args) 9 | super(*args) 10 | @updated = false 11 | end 12 | 13 | def url 14 | @base_url + "/pluginManager" 15 | end 16 | 17 | def open 18 | visit url 19 | end 20 | 21 | def check_for_updates 22 | visit "#{url}/checkUpdates" 23 | 24 | wait_for("//span[@id='completionMarker' and text()='Done']", timeout: 100) 25 | 26 | @updated = true 27 | # This is totally arbitrary, it seems that the Available page doesn't 28 | # update properly if you don't sleep a bit 29 | sleep 5 30 | end 31 | 32 | def installed?(name) 33 | visit "#{url}/installed" 34 | page.has_xpath?("//input[@url='plugin/#{name}']") 35 | end 36 | 37 | def install_plugin!(name) 38 | 39 | return if installed?(name) 40 | 41 | unless @updated 42 | check_for_updates 43 | end 44 | 45 | install! name 46 | 47 | start = Time.now.to_i 48 | try_again = true 49 | wait_for_cond(timeout: 180, message: "Plugin installation took too long") do 50 | if try_again && $jenkins.log.has_logged?(/: (?Failed to download from .*\.hpi)/) 51 | puts "Plugin installation failed. Retrying." 52 | install! name 53 | try_again = false 54 | end 55 | installed? name 56 | end 57 | 58 | installation_time = Time.now.to_i - start 59 | if installation_time > 30 60 | puts "Plugin installation took #{installation_time} seconds" 61 | end 62 | 63 | # TODO install several plugins in one step so will have to wait and 64 | # restart at most once per scenario 65 | visit '/updateCenter' 66 | if page.has_content?('Jenkins needs to be restarted for the update to take effect') 67 | raise Jenkins::RestartNeeded.new 68 | end 69 | end 70 | 71 | private 72 | def install!(name) 73 | visit "#{url}/available" 74 | first(:xpath, "//input[starts-with(@name,'plugin.#{name}.')]").set(true) 75 | find_button('Install').click 76 | end 77 | end 78 | end 79 | -------------------------------------------------------------------------------- /lib/jenkins/plugins/ant.rb: -------------------------------------------------------------------------------- 1 | require 'jenkins/build_step' 2 | require 'jenkins/pageobject' 3 | 4 | module Plugins 5 | class Ant < Jenkins::PageObject 6 | 7 | def self.add_auto_installation(name, version) 8 | find(:path, "/hudson-tasks-Ant$AntInstallation/tool/name").set(name) 9 | # by default Install automatically is checked 10 | find(:path, "/hudson-tasks-Ant$AntInstallation/tool/properties/hudson-tools-InstallSourceProperty/installers/id") 11 | find(:xpath, "//option[@value='#{version}']").click 12 | end 13 | 14 | def self.add_local_installation(name, ant_home) 15 | find(:path, "/hudson-tasks-Ant$AntInstallation/tool/name").set(name) 16 | # by default Install automatically is checked - need to uncheck 17 | find(:path, "/hudson-tasks-Ant$AntInstallation/tool/properties/hudson-tools-InstallSourceProperty").click 18 | find(:path, "/hudson-tasks-Ant$AntInstallation/tool/home").set(ant_home) 19 | end 20 | 21 | def prepare_autoinstall(runner) 22 | tempdir = runner.tempdir 23 | FileUtils.mkdir_p tempdir+'/updates' 24 | File.open("#{tempdir}/updates/hudson.tasks.Ant.AntInstaller", 'w') { |file| file.write('{"list": [{"id": "1.8.4", "name": "1.8.4", "url": "http://archive.apache.org/dist/ant/binaries/apache-ant-1.8.4-bin.zip"}]}') } 25 | end 26 | end 27 | 28 | class AntStep < Jenkins::BuildStep 29 | 30 | register 'Ant', 'Invoke Ant' 31 | 32 | def target=(name) 33 | control('targets').set name 34 | end 35 | 36 | def version=(name) 37 | control('antName').select name 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /lib/jenkins/plugins/batch_task.rb: -------------------------------------------------------------------------------- 1 | require 'jenkins/pagearea' 2 | 3 | module Plugin 4 | module BatchTask 5 | class Declaration 6 | include Jenkins::PageArea 7 | 8 | PREFIX = '/properties/hudson-plugins-batch_task-BatchTaskProperty/on' 9 | 10 | def self.add(job) 11 | checkbox = find(:path, PREFIX) 12 | if !checkbox.checked? 13 | checkbox.check 14 | else 15 | click_button 'Add another task...' 16 | sleep 1 17 | end 18 | 19 | path_prefix = all(:xpath, "//input[@name='batch-task.name']") 20 | .last[:path][0..-6] 21 | 22 | return Declaration.new(job, path_prefix) 23 | end 24 | 25 | def name=(name) 26 | control('name').set name 27 | end 28 | 29 | def script=(script) 30 | control('script').set script 31 | end 32 | end 33 | 34 | class Trigger < Jenkins::PostBuildStep 35 | register 'Invoke batch tasks', 'Invoke batch tasks' 36 | 37 | def task(job,task) 38 | control('configs/project').set job 39 | control('configs/task').click #options are not evailable while project has focus 40 | control('configs/task').select task 41 | end 42 | 43 | def allow_unstable 44 | control('evenIfUnstable').check 45 | end 46 | end 47 | 48 | class Task < Jenkins::PageObject 49 | 50 | def initialize(parent, name) 51 | super(parent.base_url, name) 52 | @parent = parent 53 | end 54 | 55 | def url 56 | @parent.url + '/batchTasks/task/' + name 57 | end 58 | 59 | def build! 60 | visit url 61 | click_link 'Build Now' 62 | end 63 | 64 | def exists? 65 | visit url 66 | page.has_content? '#1-1' 67 | end 68 | end 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /lib/jenkins/plugins/build_timeout.rb: -------------------------------------------------------------------------------- 1 | require 'jenkins/pagearea' 2 | 3 | module Plugins 4 | class BuildTimeout 5 | include Jenkins::PageArea 6 | 7 | def initialize(job) 8 | @job = job 9 | end 10 | 11 | def abortAfter(timeout) 12 | ensure_active 13 | 14 | choose 'Absolute' 15 | fill_in '_.timeoutMinutes', :with => timeout 16 | end 17 | 18 | def abortWhenStuck 19 | ensure_active 20 | 21 | choose 'Likely stuck' 22 | end 23 | 24 | def useDescription 25 | ensure_active 26 | 27 | check '_.writingDescription' 28 | end 29 | 30 | private 31 | def ensure_active 32 | @job.ensure_config_page 33 | find(:path, "/hudson-plugins-build_timeout-BuildTimeoutWrapper").set true 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/jenkins/plugins/checkstyle.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'capybara' 4 | require 'capybara/dsl' 5 | 6 | module Plugins 7 | class Checkstyle 8 | include Capybara::DSL 9 | extend Capybara::DSL 10 | 11 | def initialize(job) 12 | @job = job 13 | end 14 | 15 | def url 16 | @job.url + "/checkstyle" 17 | end 18 | 19 | def high_prio_url 20 | @job.last_build.url + "checkstyleResult/HIGH" 21 | end 22 | 23 | def warnings_number 24 | visit url 25 | find(:xpath, '//table[@id="summary"]/tbody/tr/td[@class="pane"][1]').text.to_i 26 | end 27 | 28 | def new_warnings_number 29 | visit url 30 | find(:xpath, '//table[@id="summary"]/tbody/tr/td[@class="pane"][2]/a').text.to_i 31 | end 32 | 33 | def fixed_warnings_number 34 | visit url 35 | find(:xpath, '//table[@id="summary"]/tbody/tr/td[@class="pane"][3]').text.to_i 36 | end 37 | 38 | def high_warnings_number 39 | visit url 40 | find(:xpath, '//table[@id="analysis.summary"]/tbody/tr/td[@class="pane"][2]/a').text.to_i 41 | end 42 | 43 | def normal_warnings_number 44 | visit url 45 | find(:xpath, '//table[@id="analysis.summary"]/tbody/tr/td[@class="pane"][3]').text.to_i 46 | end 47 | 48 | def low_warnings_number 49 | visit url 50 | find(:xpath, '//table[@id="analysis.summary"]/tbody/tr/td[@class="pane"][4]').text.to_i 51 | end 52 | 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /lib/jenkins/plugins/cobertura.rb: -------------------------------------------------------------------------------- 1 | require 'capybara' 2 | require 'capybara/dsl' 3 | 4 | module Plugins 5 | class Cobertura 6 | include Capybara::DSL 7 | extend Capybara::DSL 8 | 9 | def initialize(job) 10 | @job = job 11 | end 12 | 13 | def url 14 | @job.url + "/cobertura" 15 | end 16 | 17 | def packages_coverage 18 | visit url 19 | find(:xpath, '//th[text()="Packages"]/../td').text.to_i 20 | end 21 | 22 | def files_coverage 23 | visit url 24 | find(:xpath, '//th[text()="Files"]/../td').text.to_i 25 | end 26 | 27 | def classes_coverage 28 | visit url 29 | find(:xpath, '//th[text()="Classes"]/../td').text.to_i 30 | end 31 | 32 | def methods_coverage 33 | visit url 34 | find(:xpath, '//th[text()="Methods"]/../td').text.to_i 35 | end 36 | 37 | def lines_coverage 38 | visit url 39 | find(:xpath, '//th[text()="Lines"]/../td').text.to_i 40 | end 41 | 42 | def conditionals_coverage 43 | visit url 44 | find(:xpath, '//th[text()="Conditionals"]/../td').text.to_i 45 | end 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /lib/jenkins/plugins/deploy.rb: -------------------------------------------------------------------------------- 1 | module Plugin 2 | module Deploy 3 | class Pubished < Jenkins::PostBuildStep 4 | register 'Deploy WAR', 'Deploy war/ear to a container' 5 | 6 | def archive=(archive) 7 | control('war').set archive 8 | end 9 | 10 | def contextPath=(contextPath) 11 | control('contextPath').set contextPath 12 | end 13 | 14 | def container=(container) 15 | control('').select container 16 | end 17 | 18 | def user=(user) 19 | control('adapter/userName').set user 20 | end 21 | 22 | def password=(password) 23 | control('adapter/password').set password 24 | end 25 | 26 | def url=(url) 27 | control('adapter/url').set url 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/jenkins/plugins/disk_usage.rb: -------------------------------------------------------------------------------- 1 | require 'jenkins/pageobject' 2 | 3 | module Plugins 4 | class DiskUsage < Jenkins::PageObject 5 | 6 | def update 7 | visit "#{@baseurl}/plugin/disk-usage" 8 | click_button 'Record Disk Usage' 9 | rescue Capybara::ElementNotFound => ex #v0.22 10 | click_button 'Record Builds Disk Usage' 11 | click_button 'Record Jobs Disk Usage' 12 | click_button 'Record Workspaces Disk Usage' 13 | end 14 | 15 | def wait_for_update(log_watcher) 16 | log_watcher.wait_until_logged(/Finished Project disk usage. \d+ ms/, 5) 17 | rescue LogWatcher::TimeoutException => ex # after v0.22 18 | log_watcher.should have_logged 'Finished Calculation of builds disk usage' 19 | log_watcher.should have_logged 'Finished Calculation of job directories' 20 | log_watcher.should have_logged 'Finished Calculation of workspace usage' 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/jenkins/plugins/email_ext.rb: -------------------------------------------------------------------------------- 1 | require 'jenkins/post_build_step' 2 | 3 | module Plugins 4 | class EmailExtPublisher < Jenkins::PostBuildStep 5 | 6 | register 'Email-ext', 'Editable Email Notification' 7 | 8 | def subject=(subject) 9 | control("project_default_subject").set subject 10 | end 11 | 12 | def recipient=(recipient) 13 | control("project_recipient_list", "recipientlist_recipients").set recipient 14 | 15 | ensure_advanced_opened 16 | # check we really want to send it to the recipients 17 | control('project_triggers/sendToList').check 18 | end 19 | 20 | def body=(body) 21 | control("project_default_content").set body 22 | end 23 | 24 | private 25 | @advanced_opened = false 26 | def ensure_advanced_opened 27 | return if @advanced_opened 28 | control('advanced-button').click 29 | @advanced_opened = true 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/jenkins/plugins/envinject.rb: -------------------------------------------------------------------------------- 1 | require 'jenkins/pagearea' 2 | 3 | module Plugins 4 | module EnvInject 5 | class Step < Jenkins::BuildStep 6 | 7 | register 'Env Inject', 'Inject environment variables' 8 | 9 | def vars=(vars) 10 | control('propertiesContent').set vars 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/jenkins/plugins/gradle.rb: -------------------------------------------------------------------------------- 1 | module Plugins 2 | class GradleBuildStep < Jenkins::BuildStep 3 | 4 | register 'Gradle', 'Invoke Gradle script' 5 | 6 | def file(name) 7 | control("buildFile").set(name) 8 | end 9 | 10 | def dir(name) 11 | control("rootBuildScriptDir").set(name) 12 | end 13 | 14 | def switches(switches) 15 | control("switches").set(switches) 16 | end 17 | 18 | def version(version) 19 | path = path("useWrapper[false]/gradleName") 20 | find(:xpath, "//select[@path='#{path}']/option[@value='#{version}']").select_option 21 | end 22 | 23 | def description(description) 24 | control("description").set(description) 25 | end 26 | 27 | def tasks(tasks) 28 | control("tasks").set(tasks) 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/jenkins/plugins/groovy.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'jenkins/pageobject' 3 | 4 | module Plugins 5 | module Groovy 6 | class SystemBuildStep < Jenkins::BuildStep 7 | register 'System groovy', 'Execute system Groovy script' 8 | 9 | def command=(text) 10 | control('scriptSource[0]').check 11 | 12 | area_path = path('scriptSource[0]/command') 13 | textarea = find(:path, area_path, :visible => false) 14 | if textarea[:class].include? 'codemirror' 15 | codemirror = Jenkins::Util::CodeMirror.new(page, area_path) 16 | codemirror.set_content text 17 | else 18 | textarea.set text 19 | end 20 | end 21 | 22 | def file=(path) 23 | control('scriptSource[1]').check 24 | control('scriptSource[1]/scriptFile').set path 25 | end 26 | end 27 | 28 | class BuildStep < SystemBuildStep 29 | register 'Groovy', 'Execute Groovy script' 30 | 31 | def version=(version) 32 | control('groovyName').select version 33 | end 34 | end 35 | 36 | class Tool < Jenkins::ToolInstaller 37 | register 'Groovy' 38 | 39 | def initialize(global) 40 | super(global, '/hudson-plugins-groovy-GroovyInstallation/tool') 41 | end 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /lib/jenkins/plugins/htmlpublisher.rb: -------------------------------------------------------------------------------- 1 | require 'jenkins/post_build_step' 2 | 3 | module Plugins 4 | class PublishHtmlPostBuildStep < Jenkins::PostBuildStep 5 | 6 | register 'Publish HTML', 'Publish HTML reports' 7 | 8 | attr_accessor :lastReport 9 | 10 | def add_report(title, directory) 11 | control('repeatable-add').click 12 | 13 | newReport = HTMLReportConfiguration.new self, path('reportTargets') 14 | newReport.dir = directory 15 | newReport.title = title 16 | return @lastReport = newReport 17 | end 18 | end 19 | 20 | class HTMLReportConfiguration 21 | include Jenkins::PageArea 22 | 23 | def dir=(path) 24 | control("reportDir").set path 25 | end 26 | 27 | def index=(path) 28 | control("reportFiles").set path 29 | end 30 | 31 | def title=(title) 32 | control("reportName").set title 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /lib/jenkins/plugins/javadoc.rb: -------------------------------------------------------------------------------- 1 | require 'jenkins/post_build_step' 2 | 3 | module Plugins 4 | class JavadocPostBuildStep < Jenkins::PostBuildStep 5 | 6 | register 'Javadoc', 'Publish Javadoc' 7 | 8 | def dir(path) 9 | control("javadocDir").set path 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/jenkins/plugins/jira.rb: -------------------------------------------------------------------------------- 1 | module Plugins 2 | module JIRA 3 | class GlobalConfig < Jenkins::PageObject 4 | # Add a new JIRA site 5 | # TODO: this code doesn't work when there's already some existing sites configured 6 | def self.add(url,user,password) 7 | path = '/hudson-plugins-jira-JiraProjectProperty' 8 | find(:path,"#{path}/repeatable-add").click 9 | find(:path,"#{path}/sites/url").set(url) 10 | find(:path,"#{path}/sites/userName").set(user) 11 | find(:path,"#{path}/sites/password").set(password) 12 | end 13 | end 14 | end 15 | end -------------------------------------------------------------------------------- /lib/jenkins/plugins/multiple_scms.rb: -------------------------------------------------------------------------------- 1 | module Jenkins 2 | class MultipleScms < Scm 3 | 4 | register 'Multiple SCMs' 5 | 6 | def initialize(*args) 7 | super(*args) 8 | @last = 0 9 | end 10 | 11 | def add(title) 12 | control('hetero-list-add[scmList]').click 13 | 14 | find(:xpath, "//a[text() = '#{title}']").click 15 | 16 | new_path = path 'scmList' 17 | if @last != 0 18 | new_path += "[#{@last}]" 19 | end 20 | 21 | @last += 1 22 | 23 | type = Jenkins::Scm.get title 24 | return type.new(self, new_path) 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/jenkins/plugins/nodelabelparameter.rb: -------------------------------------------------------------------------------- 1 | module Jenkins 2 | module Plugin 3 | module NodeLabel 4 | 5 | class NodeParameter < Jenkins::Parameter 6 | register 'Node' 7 | 8 | def fill_with(value) 9 | select = control('labels') 10 | for node in value.split /,[ ]?/ do 11 | select.select(node) 12 | end 13 | end 14 | 15 | def allow_multiple 16 | control('triggerIfResult[allowMultiSelectionForConcurrentBuilds]').set true 17 | end 18 | end 19 | 20 | class LabelParameter < Jenkins::Parameter 21 | register 'Label' 22 | 23 | def fill_with(value) 24 | control('label').set value 25 | end 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /lib/jenkins/plugins/plot.rb: -------------------------------------------------------------------------------- 1 | module Plugins 2 | module Plot 3 | class PostBuildStep < Jenkins::PostBuildStep 4 | 5 | register 'Plot', 'Plot build data' 6 | 7 | def group=(group) 8 | control('plots/group').set group 9 | end 10 | 11 | def title=(title) 12 | control('plots/title').set title 13 | end 14 | 15 | def source(type, path) 16 | control('plots/series/file').set path 17 | control("plots/series/fileType[#{type}]").set true 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/jenkins/plugins/postbuildscript.rb: -------------------------------------------------------------------------------- 1 | require 'jenkins/post_build_step' 2 | 3 | module Plugins 4 | module PostBuildScript 5 | class Publisher < Jenkins::PostBuildStep 6 | 7 | register 'Post Build Script', 'Execute a set of scripts' 8 | 9 | def self.add(job) 10 | 11 | click_button 'Add post-build action' 12 | 13 | begin 14 | click_link 'Execute a set of scripts' 15 | rescue Capybara::ElementNotFound 16 | # The prefix was stripped in 0.12 17 | click_link '[PostBuildScript] - Execute a set of scripts' 18 | end 19 | 20 | sleep 2 21 | prefix = all(:xpath, "//div[@name='publisher']").last[:path] 22 | 23 | return self.new(job, prefix) 24 | end 25 | 26 | def add_step(title) 27 | Publisher.select_step( 28 | Jenkins::BuildStep.label(title), 29 | control('hetero-list-add[buildStep]') 30 | ) 31 | 32 | prefix = all(:xpath, "//div[@name='buildStep']").last[:path] 33 | 34 | return Jenkins::BuildStep.type(title).new(self, prefix) 35 | end 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /lib/jenkins/plugins/priority_sorter.rb: -------------------------------------------------------------------------------- 1 | module Jenkins 2 | module Plugin 3 | module PrioritySorter 4 | class Global 5 | include PageArea 6 | 7 | def initialize(pageobject) 8 | super(pageobject, '/jenkins-advancedqueue-PrioritySorterConfiguration') 9 | end 10 | 11 | def strategy=(strategy) 12 | control('').select strategy 13 | end 14 | 15 | def priorities=(priorities) 16 | control('strategy/numberOfPriorities').set priorities 17 | end 18 | end 19 | 20 | class JobGroup 21 | include PageArea 22 | 23 | def initialize 24 | page = Page.new 25 | visit page.url 26 | click_button 'Add' 27 | 28 | path = all(:xpath, '//select[@name="view"]').last[:path][0..-6] 29 | super(page, path) 30 | end 31 | 32 | def priority=(priority) 33 | control('priority').select priority 34 | end 35 | 36 | def pattern=(pattern) 37 | control('useJobFilter').check 38 | control('useJobFilter/jobPattern').set pattern 39 | end 40 | 41 | def view=(view) 42 | control('view').set view 43 | end 44 | end 45 | 46 | private 47 | class Page < Jenkins::PageObject 48 | def initialize 49 | super($jenkins.base_url, 'Priority Sorter') 50 | end 51 | 52 | def url 53 | $jenkins.base_url + '/advanced-build-queue' 54 | end 55 | 56 | def add_group 57 | return JobGroup.new 58 | end 59 | end 60 | end 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /lib/jenkins/plugins/scp.rb: -------------------------------------------------------------------------------- 1 | module Plugins 2 | module SCP 3 | class GlobalConfig < Jenkins::PageObject 4 | # Add a new SCP site 5 | # TODO: this code doesn't work when there's already some existing sites configured 6 | def self.add(host,port,remote_root,user,password,privatekey) 7 | path = '/be-certipost-hudson-plugin-SCPRepositoryPublisher' 8 | find(:path,"#{path}/repeatable-add").click 9 | find(:path,"#{path}/site/hostname").set(host) 10 | find(:path,"#{path}/site/port").set(port) 11 | find(:path,"#{path}/site/rootRepositoryPath").set(remote_root) 12 | find(:path,"#{path}/site/username").set(user) 13 | find(:path,"#{path}/site/password").set(password) 14 | find(:path,"#{path}/site/keyfile").set(privatekey) 15 | end 16 | end 17 | 18 | class Publisher < Jenkins::PostBuildStep 19 | register 'Publish artifacts to SCP Repository', 'Publish artifacts to SCP Repository' 20 | 21 | def add(source, destination) 22 | control('repeatable-add').click() 23 | control('entries/sourceFile').set(source) 24 | control('entries/filePath').set(destination) 25 | end 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/jenkins/plugins/subversion.rb: -------------------------------------------------------------------------------- 1 | module Jenkins 2 | class SubversionScm < Scm 3 | 4 | register 'Subversion' 5 | 6 | def url(url) 7 | control('locations/remote').set(url) 8 | end 9 | 10 | def local_dir(dir) 11 | control('locations/local').set(dir) 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/jenkins/plugins/xunit.rb: -------------------------------------------------------------------------------- 1 | module Plugins 2 | module XUnit 3 | class Publisher < Jenkins::PostBuildStep 4 | register 'xUnit', 'Publish xUnit test result report' 5 | 6 | def add_tool(kind) 7 | control('hetero-list-add[tools]').click 8 | click_link kind 9 | xpath = "//div[starts-with(@path, '#{path("tools")}')]" 10 | sleep 0.1 11 | path = all(:xpath, xpath).last[:path] 12 | return Tool.new self, path 13 | end 14 | end 15 | 16 | class Tool 17 | include Jenkins::PageArea 18 | 19 | def pattern=(pattern) 20 | control('pattern').set(pattern) 21 | end 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/jenkins/post_build_step.rb: -------------------------------------------------------------------------------- 1 | require 'jenkins/step' 2 | 3 | module Jenkins 4 | class PostBuildStep 5 | include Jenkins::Step 6 | 7 | def self.add(job, title) 8 | 9 | select_step label(title), find(:path, '/hetero-list-add[publisher]') 10 | 11 | prefix = all(:xpath, "//div[@name='publisher']").last[:path] 12 | 13 | return type(title).new(job, prefix) 14 | end 15 | 16 | @@types = Hash.new 17 | 18 | def self.register(title, label) 19 | raise "#{title} already registered" if @@types.has_key? title 20 | 21 | @@types[title] = {type: self, label: label} 22 | end 23 | 24 | def self.get(title) 25 | return @@types[title] if @@types.has_key? title 26 | 27 | raise "Unknown #{self.name.split('::').last} type #{title}. #{@@types.keys}" 28 | end 29 | end 30 | 31 | class ArtifactArchiver < PostBuildStep 32 | 33 | register 'Artifact Archiver', 'Archive the artifacts' 34 | 35 | def self.add(job) 36 | 37 | click_button 'Add post-build action' 38 | 39 | title = 'Artifact Archiver' 40 | begin 41 | click_link label title 42 | rescue Capybara::ElementNotFound 43 | # When cloudbees-jsync-archiver installed (pending 5.0 and Jenkins 1.532+): 44 | click_link 'Archive artifacts (fast)' 45 | end 46 | 47 | sleep 1 48 | prefix = all(:xpath, "//div[@name='publisher']").last[:path] 49 | 50 | return type(title).new(job, prefix) 51 | end 52 | 53 | def includes(includes) 54 | control("artifacts").set includes 55 | end 56 | 57 | def excludes(excludes) 58 | control("advanced-button").click 59 | control("excludes").set excludes 60 | end 61 | 62 | def latest_only(latest) 63 | control("advanced-button").click 64 | control("latestOnly").set latest 65 | end 66 | end 67 | end 68 | -------------------------------------------------------------------------------- /lib/jenkins/rspec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Defines the main body of spec/spec_helper.rb that glues the test harness with rspec 3 | # 4 | require 'jenkins/env' 5 | require 'jenkins/jenkins' 6 | require 'pry' 7 | 8 | module Jenkins 9 | # Use this method like you use 'describe'. This adds 10 | # a hook around the test to launch Jenkins and put [JenkinsRoot] in @jenkins 11 | def self.rspec(name,&block) 12 | describe name do 13 | around do |test| 14 | # skip scenario and initialization when not applicable 15 | # TODO: pending if scenario.skip_not_applicable 16 | 17 | with_jenkins(@controller_options||{}) do |j| 18 | @jenkins = j 19 | @runner = j.controller 20 | 21 | @base_url = @runner.url 22 | Capybara.app_host = @base_url 23 | 24 | # TODO: scenario.skip_not_applicable $runner 25 | 26 | test.run 27 | end 28 | end 29 | 30 | self.module_eval(&block) 31 | end 32 | end 33 | end 34 | 35 | 36 | module RSpec 37 | module Core 38 | # Extend RSpec DSL 39 | class ExampleGroup 40 | # Run the given block with JenkinsRoot and tear it down in the end 41 | # use this inside the 'it do ... end' block 42 | def with_jenkins(opts,&block) 43 | j = JenkinsControllerFactory.get.create(opts) 44 | begin 45 | j.start 46 | yield Jenkins::JenkinsRoot.new(j) 47 | ensure 48 | j.stop 49 | j.teardown 50 | end 51 | end 52 | end 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /lib/jenkins/scenario_skipper.rb: -------------------------------------------------------------------------------- 1 | module Jenkins 2 | # Determine whether an execution of scenario should be skipped 3 | class ScenarioSkipper 4 | 5 | @@skippers = [] 6 | 7 | def self.register 8 | raise "#{self.class.name} already registered" if @@skippers.include? self 9 | 10 | @@skippers << self.new 11 | end 12 | 13 | def self.should_run?(scenario) 14 | for skipper in @@skippers 15 | if !skipper.should_run scenario 16 | return false 17 | end 18 | end 19 | 20 | return true 21 | end 22 | 23 | def self.should_run_against?(scenario, runner) 24 | for skipper in @@skippers 25 | if !skipper.should_run_against scenario, runner 26 | return false 27 | end 28 | end 29 | 30 | return true 31 | end 32 | 33 | # Determine whether an execution of scenario should be skipped 34 | # 35 | # @param scenario [Cucumber::Ast::Scenario] a scenario to examine 36 | def should_run(scenario) 37 | true 38 | end 39 | 40 | # Called after Jenkins has started. Use `should_run` if running instance is not needed 41 | # 42 | # @param scenario [Cucumber::Ast::Scenario] a scenario to examine 43 | # @param runner [JenkinsController] Jenkins instance (can be nil) 44 | def should_run_against(scenario, runner) 45 | true 46 | end 47 | end 48 | 49 | class SinceSkipper < ScenarioSkipper 50 | register 51 | 52 | def should_run_against(scenario, runner) 53 | tag = scenario.tag('since') 54 | return true if tag.nil? 55 | 56 | required_version = Gem::Version.new(tag.values[0]) 57 | 58 | return runner.jenkins_version >= required_version 59 | end 60 | end 61 | 62 | class NativeCommandSkipper < ScenarioSkipper 63 | register 64 | 65 | def should_run(scenario) 66 | tag = scenario.tag('native') 67 | return true if tag.nil? 68 | 69 | commands = tag.values.join(' ') 70 | system('which ' + commands, :out => '/dev/null') 71 | end 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /lib/jenkins/scm.rb: -------------------------------------------------------------------------------- 1 | require 'jenkins/pagearea' 2 | 3 | module Jenkins 4 | class Scm 5 | include Jenkins::PageArea 6 | 7 | def self.add(job, title) 8 | xpath = "//label[contains(text(),'#{title}')]/input[@name='scm']" 9 | element = find(:xpath, xpath) 10 | element.set(true) 11 | 12 | type = get title 13 | return type.new(job, element[:path]) 14 | end 15 | 16 | @@types = Hash.new 17 | 18 | # Register SCM type 19 | def self.register(title) 20 | raise "#{title} already registered" if @@types.has_key? title 21 | 22 | @@types[title] = self 23 | end 24 | 25 | # Get type by title 26 | def self.get(title) 27 | return @@types[title] if @@types.has_key? title 28 | 29 | raise "Unknown #{self.name.split('::').last} type #{title}. #{@@types.keys}" 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/jenkins/step.rb: -------------------------------------------------------------------------------- 1 | require 'jenkins/pagearea' 2 | 3 | module Jenkins 4 | module Step 5 | include Jenkins::PageArea 6 | 7 | module Static 8 | def label(title) 9 | return get(title)[:label] 10 | end 11 | 12 | def type(title) 13 | return get(title)[:type] 14 | end 15 | 16 | def select_step(step, button) 17 | button.click 18 | 19 | # With enough implementations registered the one we are looking for might 20 | # require scrolling in menu to become visible. This dirty hack stretch 21 | # yui menu so that all the items are visible. 22 | page.execute_script %{ 23 | YAHOO.util.Dom.batch( 24 | document.querySelector(".yui-menu-body-scrolled"), 25 | function (el) { 26 | el.style.height = "auto"; 27 | YAHOO.util.Dom.removeClass(el, "yui-menu-body-scrolled"); 28 | } 29 | ); 30 | } 31 | 32 | click_link step 33 | sleep 1 34 | end 35 | end 36 | 37 | def self.included(receiver) 38 | receiver.extend Jenkins::PageArea 39 | receiver.extend Jenkins::Step::Static 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /lib/jenkins/thread_dump.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Assist diagnosis by responding to SIGQUIT and dump threads like JVM does 3 | # 4 | require 'pp' 5 | 6 | def backtrace_for_all_threads(signame,f) 7 | f.puts "--- got signal #{signame}, dump backtrace for all threads at #{Time.now}" 8 | if Thread.current.respond_to?(:backtrace) 9 | Thread.list.each do |t| 10 | f.puts t.inspect 11 | PP.pp(t.backtrace.delete_if {|frame| frame =~ /^#{File.expand_path(__FILE__)}/}, 12 | f) # remove frames resulting from calling this method 13 | end 14 | else 15 | PP.pp(caller.delete_if {|frame| frame =~ /^#{File.expand_path(__FILE__)}/}, 16 | f) # remove frames resulting from calling this method 17 | end 18 | end 19 | 20 | Signal.trap(3) do 21 | backtrace_for_all_threads("QUIT",STDERR) 22 | end -------------------------------------------------------------------------------- /lib/jenkins/tool_installer.rb: -------------------------------------------------------------------------------- 1 | require 'jenkins/pagearea' 2 | 3 | module Jenkins 4 | class ToolInstaller 5 | include Jenkins::PageArea 6 | 7 | @@types = Hash.new 8 | 9 | # Register Tool installer 10 | def self.register(title) 11 | raise "#{title} already registered" if @@types.has_key? title 12 | 13 | @@types[title] = self 14 | end 15 | 16 | # Get type by title 17 | def self.get(title) 18 | return @@types[title] if @@types.has_key? title 19 | 20 | raise "Unknown #{self.name.split('::').last} type #{title}. #{@@types.keys}" 21 | end 22 | 23 | def name=(name) 24 | control('name').set name 25 | end 26 | 27 | def install_version=(version) 28 | control('properties/hudson-tools-InstallSourceProperty').check 29 | control('properties/hudson-tools-InstallSourceProperty/installers/id').select version 30 | end 31 | 32 | def home=(dir) 33 | control('properties/hudson-tools-InstallSourceProperty').uncheck 34 | control('home').set dir 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/jenkins/util/codemirror.rb: -------------------------------------------------------------------------------- 1 | module Jenkins 2 | module Util 3 | class CodeMirror 4 | include Capybara::DSL 5 | 6 | def initialize(page, textarea) 7 | @page = page 8 | @textarea = find(:path, textarea, :visible => false) 9 | end 10 | 11 | def set_content(content) 12 | @page.execute_script script content 13 | end 14 | 15 | private 16 | # This implementation relies on 'codemirrorObject' attached to the textarea. 17 | # In case it does not exist (plugin creates codemirror enhanced textarea 18 | # in a nonstandard way) it creates new instance as it can not reach 19 | # the original one. This used to work for scriptler. 20 | def script(content) 21 | content = content.gsub "\n", '\n' 22 | xpath = "//*[@path='#{@textarea[:path]}']" 23 | return %{ 24 | textarea = document.evaluate( 25 | "#{xpath}", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null 26 | ).singleNodeValue; 27 | 28 | codemirror = textarea.codemirrorObject; 29 | if (codemirror == null) { 30 | codemirror = CodeMirror.fromTextArea(textarea) 31 | } 32 | codemirror.setValue("#{content}"); 33 | codemirror.focus(); 34 | } 35 | end 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /lib/jenkins/vagrant.rb: -------------------------------------------------------------------------------- 1 | require 'log4r' 2 | require 'vagrant' 3 | require 'vagrant/command' 4 | require 'vagrant/cli' 5 | require 'vagrant/util/platform' 6 | 7 | # Monkey patching Vagrant 8 | module Vagrant 9 | module Communication 10 | # Provides communication with the VM via SSH. 11 | class SSH 12 | # execute the command, echo back its output to console, and return its exit code 13 | def system_ssh(command,opts=nil) 14 | exit_status = execute(command,opts) do |type, data| 15 | # Determine the proper channel to send the output onto depending 16 | # on the type of data we are receiving. 17 | channel = type == :stdout ? :out : :error 18 | 19 | # Print the SSH output as it comes in, but don't prefix it and don't 20 | # force a new line so that the output is properly preserved 21 | @vm.ui.info(data.to_s, 22 | :prefix => false, 23 | :new_line => false, 24 | :channel => channel) 25 | end 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /lib/jenkins/version.rb: -------------------------------------------------------------------------------- 1 | module Jenkins 2 | VERSION = "1.0.0" 3 | 4 | # Root directory of this gem 5 | ROOTDIR = File.dirname(__FILE__)+"/../.." 6 | end -------------------------------------------------------------------------------- /lib/jenkins/view.rb: -------------------------------------------------------------------------------- 1 | require "jenkins/pageobject" 2 | 3 | module Jenkins 4 | class View < PageObject 5 | attr_accessor :timeout 6 | 7 | def url 8 | @base_url + "/view/#{@name}" 9 | end 10 | 11 | def configure_url 12 | @base_url + "/view/#{@name}/configure" 13 | end 14 | 15 | def open 16 | visit(url) 17 | end 18 | 19 | def save 20 | click_button "OK" 21 | end 22 | 23 | def self.create_view(base_url, name, type) 24 | visit("#{@base_url}/newView") 25 | 26 | fill_in "name", :with => name 27 | find(:xpath, "//input[following-sibling::label[child::b[text()='#{type}']]]").set(true) 28 | click_button "OK" 29 | 30 | self.new(base_url, name) 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /lib/jenkins/workspace.rb: -------------------------------------------------------------------------------- 1 | require 'jenkins/pageobject' 2 | 3 | module Jenkins 4 | class Workspace < PageObject 5 | attr_accessor :url 6 | 7 | def initialize(base_url) 8 | @url = base_url + "/ws" 9 | super(url, "#{url}: Workspace") 10 | end 11 | 12 | def open 13 | visit(url) 14 | end 15 | 16 | def wipe_out! 17 | open 18 | begin 19 | click_link 'Wipe Out Current Workspace' 20 | page.driver.browser.switch_to.alert.accept 21 | rescue Capybara::ElementNotFound 22 | click_link 'Wipe Out Workspace' 23 | click_button 'Yes' 24 | end 25 | 26 | end 27 | 28 | def contains(filename) 29 | open 30 | page.has_xpath? "//table[@class='fileList']//a[text()='#{filename}']" 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /resources/htmlpublisher_plugin/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

Published HTML

8 |

hidden

9 | 10 | 11 | -------------------------------------------------------------------------------- /resources/htmlpublisher_plugin/style.css: -------------------------------------------------------------------------------- 1 | p { 2 | display: none; 3 | } 4 | -------------------------------------------------------------------------------- /resources/junit/failure/com.simple.project.AppTest.txt: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | Test set: com.simple.project.AppTest 3 | ------------------------------------------------------------------------------- 4 | Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.014 sec <<< FAILURE! 5 | testApp(com.simple.project.AppTest) Time elapsed: 0.007 sec <<< FAILURE! 6 | junit.framework.AssertionFailedError 7 | at junit.framework.Assert.fail(Assert.java:47) 8 | at junit.framework.Assert.assertTrue(Assert.java:20) 9 | at junit.framework.Assert.assertTrue(Assert.java:27) 10 | at com.simple.project.AppTest.testApp(AppTest.java:36) 11 | 12 | -------------------------------------------------------------------------------- /resources/junit/success/com.simple.project.AppTest.txt: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | Test set: com.simple.project.AppTest 3 | ------------------------------------------------------------------------------- 4 | Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.017 sec 5 | -------------------------------------------------------------------------------- /resources/maven/repositories/multimodule/module_a/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | gid 5 | module_a 6 | 2.0 7 | 8 | -------------------------------------------------------------------------------- /resources/maven/repositories/multimodule/module_b/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | gid 5 | module_b 6 | 3.0 7 | 8 | -------------------------------------------------------------------------------- /resources/maven/repositories/multimodule/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | gid 5 | root 6 | 1.0 7 | pom 8 | 9 | 10 | module_a 11 | module_b 12 | 13 | 14 | -------------------------------------------------------------------------------- /resources/plot_plugin/plot.csv: -------------------------------------------------------------------------------- 1 | recs avg,recs min,recs max,station avg,station min,station max,personalized avg,personalized min,personalized max,autoplay avg,autoplay min,autoplay max,station count,personalized count,autoplay count,threads,host,errors 2 | 236.55357142857147,75.0,2091.0,207.20731707317069,69.0,947.0,436.80000000000007,165.0,594.0,133.39999999999998,117.0,160.0,82,5,20,threads,hostname,0 3 | -------------------------------------------------------------------------------- /resources/pmd_plugin/pmd-warnings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Line with 115 characters exceeds limit of 100 5 | 6 | 7 | 8 | 9 | 10 | Line with 113 characters exceeds limit of 100 11 | 12 | 13 | 14 | 15 | 16 | Line with 127 characters exceeds limit of 100 17 | 18 | 19 | 20 | 21 | 22 | Line with 213 characters exceeds limit of 100 23 | 24 | 25 | 26 | 27 | 28 | Line with 128 characters exceeds limit of 100 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | Line with 225 characters exceeds limit of 100 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /resources/pmd_plugin/pmd.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /resources/scriptler_plugin/hello_parameterized.groovy: -------------------------------------------------------------------------------- 1 | println "Hello " + noun + "!" 2 | -------------------------------------------------------------------------------- /resources/scriptler_plugin/hello_world.groovy: -------------------------------------------------------------------------------- 1 | println "Hello world!" 2 | -------------------------------------------------------------------------------- /resources/violations_plugin/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | gid 5 | example 6 | 42.0 7 | 8 | -------------------------------------------------------------------------------- /spec/ant_plugin.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | Jenkins.rspec "Ant plugin" do 4 | it 'allows users to use Ant in a freestyle project' do 5 | @jenkins.plugin_manager.install_plugin! 'ant' 6 | j = @jenkins.create_job('FreeStyle') 7 | j.configure do 8 | j.add_create_file_step('build.xml',< 10 | 11 | 12 | 13 | 14 | eos 15 | j.add_build_step('Ant').tap do |s| 16 | s.target = 'hello' 17 | end 18 | end 19 | 20 | j.queue_build.should_succeed 21 | end 22 | end -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # meat of the rspec glue code is defined in lib/jenkins/rspec.rb for better reuse in other gems 2 | $:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib') 3 | require 'jenkins/rspec' 4 | -------------------------------------------------------------------------------- /vagrant/centos/Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant::Config.run do |config| 2 | config.vm.box = "jenkins-test-centos-6.0" 3 | config.vm.box_url = "http://boxes.jenkins-ci.org/jenkins-test-centos-6.0.box" 4 | 5 | # port on VM, port on Host 6 | config.vm.forward_port 8080, 8080 7 | 8 | # config.vm.share_folder "shared", "/shared", "#{Dir.pwd}data" 9 | end 10 | -------------------------------------------------------------------------------- /vagrant/opensuse/Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant::Config.run do |config| 2 | config.vm.box = "jenkins-test-opensuse-11.4" 3 | config.vm.box_url = "http://boxes.jenkins-ci.org/jenkins-test-opensuse-11.4.box" 4 | 5 | 6 | # port on VM, port on Host 7 | config.vm.forward_port 8080, 8080 8 | 9 | # config.vm.share_folder "shared", "/shared", "#{Dir.pwd}data" 10 | end 11 | -------------------------------------------------------------------------------- /vagrant/readme.txt: -------------------------------------------------------------------------------- 1 | Each directory contains Vagrantfile for respective vagrant controller. 2 | You can run vagrant commands inside these directories to login to VM, 3 | start/stop/destroy VMs. -------------------------------------------------------------------------------- /vagrant/ubuntu/Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant::Config.run do |config| 2 | # Every Vagrant virtual environment requires a box to build off of. 3 | config.vm.box = "lucid32" 4 | 5 | # port on VM, port on Host 6 | config.vm.forward_port 8080, 8080 7 | 8 | # config.vm.share_folder "shared", "/shared", "#{Dir.pwd}data" 9 | end 10 | -------------------------------------------------------------------------------- /veewee/definitions/jenkins-test-centos-6.0/base.sh: -------------------------------------------------------------------------------- 1 | # Base install 2 | 3 | sed -i "s/^.*requiretty/#Defaults requiretty/" /etc/sudoers 4 | 5 | cat > /etc/yum.repos.d/epel.repo << EOM 6 | [epel] 7 | name=epel 8 | baseurl=http://download.fedoraproject.org/pub/epel/6/\$basearch 9 | enabled=1 10 | gpgcheck=0 11 | EOM 12 | 13 | cat > /etc/yum.repos.d/centos-vault.repo << EOM 14 | [vault] 15 | name=vault 16 | baseurl=http://vault.centos.org/6.0/os/\$basearch 17 | enabled=1 18 | gpgcheck=0 19 | EOM 20 | 21 | yum -y install gcc make gcc-c++ kernel-devel-`uname -r` zlib-devel openssl-devel readline-devel sqlite-devel perl wget java-1.6.0-openjdk 22 | -------------------------------------------------------------------------------- /veewee/definitions/jenkins-test-centos-6.0/chef.sh: -------------------------------------------------------------------------------- 1 | # Install Chef 2 | gem install --no-ri --no-rdoc chef 3 | 4 | -------------------------------------------------------------------------------- /veewee/definitions/jenkins-test-centos-6.0/cleanup.sh: -------------------------------------------------------------------------------- 1 | yum -y erase gtk2 libX11 hicolor-icon-theme avahi freetype bitstream-vera-fonts 2 | yum -y clean all 3 | rm -rf /etc/yum.repos.d/{puppetlabs,epel}.repo 4 | rm -rf VBoxGuestAdditions_*.iso 5 | 6 | -------------------------------------------------------------------------------- /veewee/definitions/jenkins-test-centos-6.0/definition.rb: -------------------------------------------------------------------------------- 1 | Veewee::Session.declare({ 2 | :cpu_count => '1', 3 | :memory_size=> '480', 4 | :disk_size => '10140', 5 | :disk_format => 'VDI', 6 | :hostiocache => 'off', 7 | :os_type_id => 'RedHat_64', 8 | :iso_file => "CentOS-6.0-x86_64-minimal.iso", 9 | :iso_src => "http://vault.centos.org/6.0/isos/x86_64/CentOS-6.0-x86_64-minimal.iso", 10 | :iso_md5 => "b9fff4dad7aad0edaa564d7a251cb971", 11 | :iso_download_timeout => 1000, 12 | :boot_wait => "10", 13 | :boot_cmd_sequence => [ 14 | ' text ks=http://%IP%:%PORT%/ks.cfg' 15 | ], 16 | :kickstart_port => "7122", 17 | :kickstart_timeout => 10000, 18 | :kickstart_file => "ks.cfg", 19 | :ssh_login_timeout => "10000", 20 | :ssh_user => "veewee", 21 | :ssh_password => "veewee", 22 | :ssh_key => "", 23 | :ssh_host_port => "7222", 24 | :ssh_guest_port => "22", 25 | :sudo_cmd => "echo '%p'|sudo -S sh '%f'", 26 | :shutdown_cmd => "/sbin/halt -h -p", 27 | :postinstall_files => [ 28 | "base.sh", 29 | "ruby.sh", 30 | "chef.sh", 31 | "puppet.sh", 32 | "vagrant.sh", 33 | "virtualbox.sh", 34 | #"kvm.sh", 35 | #"vmfusion.sh", 36 | "cleanup.sh", 37 | "zerodisk.sh" 38 | ], 39 | :postinstall_timeout => 10000 40 | }) 41 | -------------------------------------------------------------------------------- /veewee/definitions/jenkins-test-centos-6.0/ks.cfg: -------------------------------------------------------------------------------- 1 | install 2 | cdrom 3 | lang en_US.UTF-8 4 | keyboard us 5 | network --bootproto=dhcp 6 | rootpw --iscrypted $1$damlkd,f$UC/u5pUts5QiU3ow.CSso/ 7 | firewall --enabled --service=ssh 8 | authconfig --enableshadow --passalgo=sha512 9 | selinux --disabled 10 | timezone UTC 11 | bootloader --location=mbr 12 | 13 | text 14 | skipx 15 | zerombr 16 | 17 | clearpart --all --initlabel 18 | autopart 19 | 20 | auth --useshadow --enablemd5 21 | firstboot --disabled 22 | reboot 23 | 24 | %packages --ignoremissing 25 | @core 26 | java-1.6.0-openjdk 27 | bzip2 28 | kernel-devel 29 | kernel-headers 30 | -ipw2100-firmware 31 | -ipw2200-firmware 32 | -ivtv-firmware 33 | %end 34 | 35 | %post 36 | /usr/bin/yum -y install sudo 37 | /usr/sbin/groupadd veewee 38 | /usr/sbin/useradd veewee -g veewee -G wheel 39 | echo "veewee"|passwd --stdin veewee 40 | echo "veewee ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/veewee 41 | chmod 0440 /etc/sudoers.d/veewee 42 | # repomd.xml is out of sync. 43 | rm -rf /var/cache/yum/x86_64/6/epel 44 | echo "MaxAuthTries 20" >> /etc/ssh/sshd_config 45 | /etc/init.d/sshd restart 46 | %end 47 | 48 | -------------------------------------------------------------------------------- /veewee/definitions/jenkins-test-centos-6.0/puppet.sh: -------------------------------------------------------------------------------- 1 | # Install Puppet 2 | 3 | cat > /etc/yum.repos.d/puppetlabs.repo << EOM 4 | [puppetlabs] 5 | name=puppetlabs 6 | baseurl=http://yum.puppetlabs.com/el/6/products/\$basearch 7 | enabled=1 8 | gpgcheck=0 9 | EOM 10 | 11 | yum -y install puppet facter 12 | 13 | -------------------------------------------------------------------------------- /veewee/definitions/jenkins-test-centos-6.0/ruby.sh: -------------------------------------------------------------------------------- 1 | # Install Ruby 2 | yum -y install ruby ruby-devel rubygems 3 | 4 | -------------------------------------------------------------------------------- /veewee/definitions/jenkins-test-centos-6.0/vagrant.sh: -------------------------------------------------------------------------------- 1 | # Vagrant specific 2 | date > /etc/vagrant_box_build_time 3 | 4 | # Add vagrant user 5 | /usr/sbin/groupadd vagrant 6 | /usr/sbin/useradd vagrant -g vagrant -G wheel 7 | echo "vagrant"|passwd --stdin vagrant 8 | echo "vagrant ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/vagrant 9 | chmod 0440 /etc/sudoers.d/vagrant 10 | 11 | # Installing vagrant keys 12 | mkdir -pm 700 /home/vagrant/.ssh 13 | wget --no-check-certificate 'https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub' -O /home/vagrant/.ssh/authorized_keys 14 | chmod 0600 /home/vagrant/.ssh/authorized_keys 15 | chown -R vagrant /home/vagrant/.ssh 16 | 17 | # Customize the message of the day 18 | echo 'Welcome to your Vagrant-built virtual machine.' > /etc/motd 19 | -------------------------------------------------------------------------------- /veewee/definitions/jenkins-test-centos-6.0/virtualbox.sh: -------------------------------------------------------------------------------- 1 | # Installing the virtualbox guest additions 2 | VBOX_VERSION=$(cat /home/veewee/.vbox_version) 3 | cd /tmp 4 | mount -o loop /home/veewee/VBoxGuestAdditions_$VBOX_VERSION.iso /mnt 5 | sh /mnt/VBoxLinuxAdditions.run 6 | umount /mnt 7 | rm -rf /home/veewee/VBoxGuestAdditions_*.iso 8 | 9 | -------------------------------------------------------------------------------- /veewee/definitions/jenkins-test-centos-6.0/zerodisk.sh: -------------------------------------------------------------------------------- 1 | # Zero out the free space to save space in the final image: 2 | dd if=/dev/zero of=/EMPTY bs=1M 3 | rm -f /EMPTY 4 | -------------------------------------------------------------------------------- /veewee/definitions/jenkins-test-opensuse-11.4/definition.rb: -------------------------------------------------------------------------------- 1 | Veewee::Session.declare({ 2 | :os_type_id => 'OpenSUSE_64', :cpu_count => '1', :memory_size=> '512', 3 | :disk_size => '20480', :disk_format => 'VDI', :hostiocache => 'off', 4 | :iso_file => "openSUSE-11.4-NET-x86_64.iso", 5 | :iso_src => "http://download.opensuse.org/distribution/11.4/iso/openSUSE-11.4-NET-x86_64.iso", 6 | #:iso_src => "http://ftp.belnet.be/mirror/ftp.opensuse.org/distribution/11.4/iso/openSUSE-11.4-NET-x86_64.iso", 7 | :iso_md5 => "bb0dc0124d5d2e3292ec96717132b136", 8 | :iso_download_timeout => "1000", 9 | :boot_wait => "10", :boot_cmd_sequence => [ 10 | '', 11 | 'linux netdevice=eth0 netsetup=dhcp', 12 | ' install=http://download.opensuse.org/distribution/11.4/repo/oss/ insecure=1', 13 | ' lang=en_US autoyast=http://%IP%:%PORT%/autoinst_en.xml', 14 | ' textmode=1', 15 | '' 16 | ], 17 | :kickstart_port => "7122", :kickstart_timeout => "10000", 18 | :kickstart_file => ["autoinst_en.xml", "autoinst_en.xml"], 19 | :ssh_login_timeout => "10000", :ssh_user => "vagrant", :ssh_password => "vagrant", :ssh_key => "", 20 | :ssh_host_port => "7222", :ssh_guest_port => "22", 21 | :sudo_cmd => "echo '%p'|sudo -S sh '%f'", 22 | :shutdown_cmd => "shutdown -h -P now", 23 | :postinstall_files => ["postinstall.sh"], :postinstall_timeout => "10000" 24 | }) 25 | -------------------------------------------------------------------------------- /veewee/definitions/jenkins-test-opensuse-11.4/postinstall.sh: -------------------------------------------------------------------------------- 1 | # 2 | # postinstall.sh 3 | # 4 | 5 | date > /etc/vagrant_box_build_time 6 | 7 | # install vagrant key 8 | echo -e "\ninstall vagrant key ..." 9 | mkdir -m 0700 /home/vagrant/.ssh 10 | cd /home/vagrant/.ssh 11 | wget --no-check-certificate -O authorized_keys https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub 12 | chmod 0600 /home/vagrant/.ssh/authorized_keys 13 | chown -R vagrant.users /home/vagrant/.ssh 14 | 15 | # update sudoers 16 | echo -e "\nupdate sudoers ..." 17 | echo -e "\n# added by veewee/postinstall.sh" >> /etc/sudoers 18 | echo -e "vagrant ALL=(ALL) NOPASSWD: ALL\n" >> /etc/sudoers 19 | 20 | # speed-up remote logins 21 | echo -e "\nspeed-up remote logins ..." 22 | echo -e "\n# added by veewee/postinstall.sh" >> /etc/ssh/sshd_config 23 | echo -e "UseDNS no\n" >> /etc/ssh/sshd_config 24 | 25 | # install chef and puppet 26 | echo -e "\ninstall chef and puppet ..." 27 | gem install chef --no-ri --no-rdoc 28 | gem install puppet --no-ri --no-rdoc 29 | 30 | # remove zypper locks, preventing installation of additional packages, 31 | # present because of the autoinst 32 | echo -e "\nremove zypper package locks ..." 33 | rm -f /etc/zypp/locks 34 | 35 | # install the virtualbox guest additions 36 | echo -e "\ninstall the virtualbox guest additions ..." 37 | zypper --non-interactive remove `rpm -qa virtualbox-guest-*` 38 | VBOX_VERSION=$(cat /home/vagrant/.vbox_version) 39 | cd /tmp 40 | wget http://download.virtualbox.org/virtualbox/$VBOX_VERSION/VBoxGuestAdditions_$VBOX_VERSION.iso 41 | #wget http://192.168.178.10/VBoxGuestAdditions_$VBOX_VERSION.iso 42 | mount -o loop VBoxGuestAdditions_$VBOX_VERSION.iso /mnt 43 | sh /mnt/VBoxLinuxAdditions.run 44 | umount /mnt 45 | rm -f VBoxGuestAdditions_$VBOX_VERSION.iso 46 | 47 | # other baseline used by Jenkins (somehow they don't install well from autoionst_en.xml 48 | zypper --non-interactive install java-1_6_0-openjdk-devel ant 49 | 50 | echo -e "\nall done.\n" 51 | exit 52 | -------------------------------------------------------------------------------- /veewee/readme.txt: -------------------------------------------------------------------------------- 1 | Definitions for boxes that are used for testing. --------------------------------------------------------------------------------