├── .git-blame-ignore-revs ├── .github ├── release-drafter.yml ├── renovate.json └── workflows │ ├── cd.yml │ └── verify-gradle-wrapper.yaml ├── .gitignore ├── .mvn ├── extensions.xml ├── jvm.config └── maven.config ├── Jenkinsfile ├── Jenkinsfile.infra.ci.jenkins.io ├── README.md ├── ath-container.sh ├── build-image.sh ├── ci.sh ├── core-commit.sh ├── docker-compose.yml ├── dockerinject.groovy ├── docs ├── AGENT.md ├── BROWSER.md ├── CONTRIBUTING.md ├── CONTROLLER.md ├── DOCKER.md ├── EC2-CONFIG.md ├── EXERCISEDPLUGINSREPORTER.md ├── EXTERNAL.md ├── FIXTURES.md ├── GUICE.md ├── INVESTIGATION.md ├── JUNIT.md ├── MACHINE-CONFIG.md ├── MACHINE.md ├── MATCHERS.md ├── MIXIN.md ├── PAGE-OBJECTS.md ├── PRELAUNCH.md ├── SINGLE-TEST.md ├── SUPPORT-BUNDLE.md ├── SUT-VERSIONS.md ├── USING-A-HTTP-PROXY.md ├── WALKTHROUGH.md ├── WIRING.md └── img │ ├── debuging-ath-containerized-from-idea.png │ └── exporting_docker_host_steps.png ├── etc └── templates │ └── assertions_entry_point_class_template.txt ├── grab-latest-rc.sh ├── jut-server.sh ├── pom.xml ├── single-plugin.groovy ├── src ├── main │ ├── java │ │ └── org │ │ │ └── jenkinsci │ │ │ └── test │ │ │ └── acceptance │ │ │ ├── AbstractPipelineTest.java │ │ │ ├── ByFactory.java │ │ │ ├── Config.java │ │ │ ├── FallbackConfig.java │ │ │ ├── Matcher.java │ │ │ ├── Matchers.java │ │ │ ├── controller │ │ │ ├── ExistingJenkinsController.java │ │ │ ├── IJenkinsController.java │ │ │ ├── JBossController.java │ │ │ ├── JenkinsController.java │ │ │ ├── JenkinsControllerFactory.java │ │ │ ├── JenkinsLogWatcher.java │ │ │ ├── LocalController.java │ │ │ ├── TomcatController.java │ │ │ ├── WinstoneController.java │ │ │ └── WinstoneDockerController.java │ │ │ ├── docker │ │ │ ├── DockerContainerHolder.java │ │ │ ├── DockerModule.java │ │ │ └── fixtures │ │ │ │ ├── ArtifactoryContainer.java │ │ │ │ ├── FtpdContainer.java │ │ │ │ ├── GitContainer.java │ │ │ │ ├── GitLabContainer.java │ │ │ │ ├── IPasswordDockerContainer.java │ │ │ │ ├── JavaGitContainer.java │ │ │ │ ├── JiraContainer.java │ │ │ │ ├── LdapContainer.java │ │ │ │ ├── MailhogContainer.java │ │ │ │ ├── SMBContainer.java │ │ │ │ ├── SshAgentContainer.java │ │ │ │ ├── SvnContainer.java │ │ │ │ ├── Tomcat10Container.java │ │ │ │ └── XvncSlaveContainer.java │ │ │ ├── guice │ │ │ ├── AdditionalBinderDsl.java │ │ │ ├── AutoCleaned.java │ │ │ ├── Cleaner.java │ │ │ ├── SubWorld.java │ │ │ ├── TestCleaner.java │ │ │ ├── TestLifecycle.java │ │ │ ├── TestName.java │ │ │ ├── TestScope.java │ │ │ ├── TestScopeModule.java │ │ │ ├── World.java │ │ │ └── WorldCleaner.java │ │ │ ├── junit │ │ │ ├── AbstractJUnitTest.java │ │ │ ├── CspRule.java │ │ │ ├── DiagnosticRule.java │ │ │ ├── DockerTest.java │ │ │ ├── FailureDiagnostics.java │ │ │ ├── FilterRule.java │ │ │ ├── GlobalRule.java │ │ │ ├── JUnitProgressReporter.java │ │ │ ├── JenkinsAcceptanceTestRule.java │ │ │ ├── Native.java │ │ │ ├── PropertyBindingModule.java │ │ │ ├── Resource.java │ │ │ ├── RuleAnnotation.java │ │ │ ├── RuleFailedException.java │ │ │ ├── Since.java │ │ │ ├── SmokeTest.java │ │ │ ├── TestActivation.java │ │ │ ├── Wait.java │ │ │ ├── WithCredentials.java │ │ │ ├── WithDocker.java │ │ │ ├── WithInstallWizard.java │ │ │ ├── WithJavaOptions.java │ │ │ ├── WithOS.java │ │ │ ├── WithPlugins.java │ │ │ └── package-info.java │ │ │ ├── log │ │ │ ├── LogListenable.java │ │ │ ├── LogListener.java │ │ │ ├── LogPrinter.java │ │ │ ├── LogReader.java │ │ │ ├── LogSplitter.java │ │ │ ├── LogWatcher.java │ │ │ └── NullPrinter.java │ │ │ ├── machine │ │ │ └── JenkinsProvider.java │ │ │ ├── plugins │ │ │ ├── active_directory │ │ │ │ ├── ActiveDirectoryEnv.java │ │ │ │ └── ActiveDirectorySecurityRealm.java │ │ │ ├── ant │ │ │ │ ├── AntBuildStep.java │ │ │ │ └── AntInstallation.java │ │ │ ├── artifactory │ │ │ │ ├── ArtifactoryGlobalConfig.java │ │ │ │ ├── ArtifactoryGradleConfiguratior.java │ │ │ │ └── ArtifactoryPublisher.java │ │ │ ├── audit_trail │ │ │ │ ├── AuditTrailGlobalConfiguration.java │ │ │ │ └── AuditTrailLogger.java │ │ │ ├── authorize_project │ │ │ │ ├── BuildAccessControl.java │ │ │ │ └── ProjectDefaultBuildAccessControl.java │ │ │ ├── build_timeout │ │ │ │ └── BuildTimeout.java │ │ │ ├── compress_artifacts │ │ │ │ └── CompressingArtifactManager.java │ │ │ ├── config_file_provider │ │ │ │ ├── ConfigFileProvider.java │ │ │ │ ├── CustomConfig.java │ │ │ │ ├── MavenSettingsConfig.java │ │ │ │ ├── ProvidedFile.java │ │ │ │ └── ServerCredentialMapping.java │ │ │ ├── configuration_as_code │ │ │ │ └── JcascManage.java │ │ │ ├── copyartifact │ │ │ │ └── CopyArtifactBuildStep.java │ │ │ ├── credentials │ │ │ │ ├── AbstractCredentialsTest.java │ │ │ │ ├── BaseStandardCredentials.java │ │ │ │ ├── Credential.java │ │ │ │ ├── CredentialsPage.java │ │ │ │ ├── Domain.java │ │ │ │ ├── DomainPage.java │ │ │ │ ├── FileCredentials.java │ │ │ │ ├── ManagedCredentials.java │ │ │ │ ├── StringCredentials.java │ │ │ │ └── UserPwdCredential.java │ │ │ ├── credentialsbinding │ │ │ │ ├── CredentialsBinding.java │ │ │ │ ├── ManagedCredentialsBinding.java │ │ │ │ ├── SecretFileCredentialsBinding.java │ │ │ │ └── SecretStringCredentialsBinding.java │ │ │ ├── csp │ │ │ │ └── ContentSecurityPolicyReport.java │ │ │ ├── dashboard_view │ │ │ │ ├── AbstractDashboardViewPortlet.java │ │ │ │ ├── BuildStatisticsPortlet.java │ │ │ │ ├── DashboardView.java │ │ │ │ ├── JobsGridPortlet.java │ │ │ │ ├── LatestBuildsPortlet.java │ │ │ │ ├── TestStatisticsChartPortlet.java │ │ │ │ ├── UnstableJobsPortlet.java │ │ │ │ ├── controls │ │ │ │ │ ├── ColumnsArea.java │ │ │ │ │ ├── DashboardPortlets.java │ │ │ │ │ ├── JobFiltersArea.java │ │ │ │ │ └── MainArea.java │ │ │ │ └── read │ │ │ │ │ ├── BreadCrumbs.java │ │ │ │ │ ├── BuildExecutorStatus.java │ │ │ │ │ ├── MainPanel.java │ │ │ │ │ └── ProjectStatusStdJobList.java │ │ │ ├── deploy │ │ │ │ └── DeployPublisher.java │ │ │ ├── description_setter │ │ │ │ └── BuildDescriptionSetter.java │ │ │ ├── disk_usage │ │ │ │ ├── DiskUsage.java │ │ │ │ └── DiskUsageGlobalConfig.java │ │ │ ├── docker_build_step │ │ │ │ ├── DockerBuildStep.java │ │ │ │ ├── DockerCommand.java │ │ │ │ └── GlobalDockerConfig.java │ │ │ ├── email_ext │ │ │ │ ├── EmailExtPublisher.java │ │ │ │ └── GlobalConfig.java │ │ │ ├── envinject │ │ │ │ ├── EnvInjectAction.java │ │ │ │ ├── EnvInjectConfig.java │ │ │ │ └── EnvInjectStep.java │ │ │ ├── external_workspace_manager │ │ │ │ ├── ExternalGlobalConfig.java │ │ │ │ └── ExternalNodeConfig.java │ │ │ ├── extra_columns │ │ │ │ └── LastConsoleColumn.java │ │ │ ├── gerrit_trigger │ │ │ │ ├── GerritTriggerJob.java │ │ │ │ ├── GerritTriggerNewServer.java │ │ │ │ └── GerritTriggerServer.java │ │ │ ├── git │ │ │ │ ├── GitLabScm.java │ │ │ │ ├── GitRepo.java │ │ │ │ ├── GitScm.java │ │ │ │ ├── GitblitScm.java │ │ │ │ ├── PhabricatorScm.java │ │ │ │ └── ViewgitScm.java │ │ │ ├── git_client │ │ │ │ ├── JGitInstallation.java │ │ │ │ └── ssh_host_key_verification │ │ │ │ │ ├── AcceptFirstConnectionStrategy.java │ │ │ │ │ ├── KnownHostsFileStrategy.java │ │ │ │ │ ├── ManuallyProvidedKeysStrategy.java │ │ │ │ │ ├── NoVerificationStrategy.java │ │ │ │ │ └── SshHostKeyVerificationStrategy.java │ │ │ ├── gitlab_plugin │ │ │ │ ├── GitLabBranchSource.java │ │ │ │ ├── GitLabOrganizationFolder.java │ │ │ │ ├── GitLabPersonalAccessTokenCredential.java │ │ │ │ └── GitLabServerConfig.java │ │ │ ├── gradle │ │ │ │ ├── GradleInstallation.java │ │ │ │ ├── GradleStep.java │ │ │ │ ├── GradleTask.java │ │ │ │ └── GradleWrapper.java │ │ │ ├── groovy │ │ │ │ ├── GroovyInstallation.java │ │ │ │ ├── GroovyStep.java │ │ │ │ └── SystemGroovyStep.java │ │ │ ├── groovy_postbuild │ │ │ │ └── GroovyPostBuildStep.java │ │ │ ├── html_publisher │ │ │ │ ├── HtmlPublisher.java │ │ │ │ └── HtmlReport.java │ │ │ ├── javadoc │ │ │ │ └── JavadocPublisher.java │ │ │ ├── jira │ │ │ │ ├── JiraGlobalConfig.java │ │ │ │ └── JiraUpdater.java │ │ │ ├── job_config_history │ │ │ │ └── JobConfigHistory.java │ │ │ ├── job_dsl │ │ │ │ ├── JobDslBuildStep.java │ │ │ │ ├── JobDslLookupStrategy.java │ │ │ │ ├── JobDslRemovedConfigFilesAction.java │ │ │ │ ├── JobDslRemovedJobAction.java │ │ │ │ └── JobDslRemovedViewAction.java │ │ │ ├── ldap │ │ │ │ ├── LdapDetails.java │ │ │ │ ├── LdapEnv.java │ │ │ │ ├── LdapEnvironmentVariable.java │ │ │ │ ├── LdapGroupMembershipStrategy.java │ │ │ │ ├── ParseUserAttributeLdapGroupMembershipStrategy.java │ │ │ │ └── SearchForGroupsLdapGroupMembershipStrategy.java │ │ │ ├── logparser │ │ │ │ ├── LogParserGlobalConfig.java │ │ │ │ ├── LogParserOutputPage.java │ │ │ │ └── LogParserPublisher.java │ │ │ ├── mail_watcher │ │ │ │ └── OnlineStatusNotification.java │ │ │ ├── mailer │ │ │ │ ├── Mailer.java │ │ │ │ └── MailerGlobalConfig.java │ │ │ ├── matrix_auth │ │ │ │ ├── MatrixAuthorizationStrategy.java │ │ │ │ ├── MatrixRow.java │ │ │ │ ├── ProjectBasedMatrixAuthorizationStrategy.java │ │ │ │ └── ProjectMatrixProperty.java │ │ │ ├── maven │ │ │ │ ├── MavenBuild.java │ │ │ │ ├── MavenBuildStep.java │ │ │ │ ├── MavenInstallation.java │ │ │ │ ├── MavenModule.java │ │ │ │ ├── MavenModuleBuild.java │ │ │ │ ├── MavenModuleSet.java │ │ │ │ └── MavenProjectConfig.java │ │ │ ├── mock_security_realm │ │ │ │ └── MockSecurityRealm.java │ │ │ ├── msbuild │ │ │ │ ├── MSBuildInstallation.java │ │ │ │ └── MSBuildStep.java │ │ │ ├── mstestrunner │ │ │ │ └── MSTestRunnerBuildStep.java │ │ │ ├── nested_view │ │ │ │ └── NestedView.java │ │ │ ├── nodelabelparameter │ │ │ │ ├── LabelParameter.java │ │ │ │ └── NodeParameter.java │ │ │ ├── parameterized_trigger │ │ │ │ ├── BuildParameters.java │ │ │ │ ├── BuildTriggerConfig.java │ │ │ │ ├── FileBuildParameters.java │ │ │ │ ├── ParameterizedTrigger.java │ │ │ │ ├── TriggerCallBuildStep.java │ │ │ │ └── TriggerConfig.java │ │ │ ├── post_build_script │ │ │ │ └── PostBuildScript.java │ │ │ ├── priority_sorter │ │ │ │ └── PriorityConfig.java │ │ │ ├── project_description_setter │ │ │ │ └── ProjectDescriptionSetter.java │ │ │ ├── rvm │ │ │ │ └── Rvm.java │ │ │ ├── script_security │ │ │ │ ├── PendingScript.java │ │ │ │ ├── PendingSignature.java │ │ │ │ └── ScriptApproval.java │ │ │ ├── scriptler │ │ │ │ ├── Script.java │ │ │ │ ├── ScriptResult.java │ │ │ │ └── Scriptler.java │ │ │ ├── ssh_credentials │ │ │ │ ├── SshCredentialDialog.java │ │ │ │ └── SshPrivateKeyCredential.java │ │ │ ├── ssh_slaves │ │ │ │ ├── SshSlaveConnector.java │ │ │ │ └── SshSlaveLauncher.java │ │ │ ├── stageview │ │ │ │ ├── StageView.java │ │ │ │ ├── StageViewBuild.java │ │ │ │ ├── StageViewHeadline.java │ │ │ │ └── StageViewStage.java │ │ │ ├── subversion │ │ │ │ ├── SubversionPluginTestException.java │ │ │ │ ├── SubversionScm.java │ │ │ │ ├── SubversionSvmAdvanced.java │ │ │ │ ├── SvnRepositoryBrowser.java │ │ │ │ └── SvnRepositoryBrowserWebSvn.java │ │ │ ├── textfinder │ │ │ │ └── TextFinderPublisher.java │ │ │ ├── timestamper │ │ │ │ └── TimstamperGlobalConfig.java │ │ │ ├── workflow_multibranch │ │ │ │ ├── BranchSource.java │ │ │ │ ├── GitBranchSource.java │ │ │ │ └── GithubBranchSource.java │ │ │ ├── workflow_shared_library │ │ │ │ ├── WorkflowGithubSharedLibrary.java │ │ │ │ ├── WorkflowSharedLibrary.java │ │ │ │ └── WorkflowSharedLibraryGlobalConfig.java │ │ │ ├── ws_cleanup │ │ │ │ └── WsCleanup.java │ │ │ ├── xunit │ │ │ │ └── XUnitPublisher.java │ │ │ └── xvnc │ │ │ │ ├── XvncGlobalJobConfig.java │ │ │ │ └── XvncJobConfig.java │ │ │ ├── po │ │ │ ├── AbstractListViewColumn.java │ │ │ ├── AbstractStep.java │ │ │ ├── Action.java │ │ │ ├── ActionPageObject.java │ │ │ ├── AggregateDownstreamTestResults.java │ │ │ ├── Artifact.java │ │ │ ├── ArtifactArchiver.java │ │ │ ├── ArtifactManagement.java │ │ │ ├── AuthorizationStrategy.java │ │ │ ├── Axis.java │ │ │ ├── BatchCommandBuildStep.java │ │ │ ├── Build.java │ │ │ ├── BuildHistory.java │ │ │ ├── BuildStep.java │ │ │ ├── BuildTrigger.java │ │ │ ├── BuildWithParameters.java │ │ │ ├── BuildWrapper.java │ │ │ ├── CapybaraPortingLayer.java │ │ │ ├── CapybaraPortingLayerImpl.java │ │ │ ├── Changes.java │ │ │ ├── Cloud.java │ │ │ ├── CodeMirror.java │ │ │ ├── CommandSlaveLauncher.java │ │ │ ├── ComputerConnector.java │ │ │ ├── ComputerLauncher.java │ │ │ ├── ConfigurablePageObject.java │ │ │ ├── Container.java │ │ │ ├── ContainerPageObject.java │ │ │ ├── Control.java │ │ │ ├── CopyArchivedArtifactsBuildStep.java │ │ │ ├── Describable.java │ │ │ ├── DumbSlave.java │ │ │ ├── Fingerprint.java │ │ │ ├── Folder.java │ │ │ ├── FormValidation.java │ │ │ ├── FreeStyleJob.java │ │ │ ├── FreeStyleMultiBranchJob.java │ │ │ ├── GlobalPluginConfiguration.java │ │ │ ├── GlobalSecurityConfig.java │ │ │ ├── GlobalToolConfig.java │ │ │ ├── JUnitPublisher.java │ │ │ ├── JdkInstallation.java │ │ │ ├── Jenkins.java │ │ │ ├── JenkinsConfig.java │ │ │ ├── JenkinsDatabaseSecurityRealm.java │ │ │ ├── JenkinsLogger.java │ │ │ ├── Job.java │ │ │ ├── JobsMixIn.java │ │ │ ├── LabelAxis.java │ │ │ ├── LabelExpressionAxis.java │ │ │ ├── LdapSecurityRealm.java │ │ │ ├── ListView.java │ │ │ ├── ListViewColumn.java │ │ │ ├── LoggedInAuthorizationStrategy.java │ │ │ ├── Login.java │ │ │ ├── Logout.java │ │ │ ├── MatrixBuild.java │ │ │ ├── MatrixConfiguration.java │ │ │ ├── MatrixProject.java │ │ │ ├── MatrixRun.java │ │ │ ├── MixIn.java │ │ │ ├── Node.java │ │ │ ├── OicAuthConfigurationMode.java │ │ │ ├── OicAuthSecurityRealm.java │ │ │ ├── PageArea.java │ │ │ ├── PageAreaImpl.java │ │ │ ├── PageObject.java │ │ │ ├── Parameter.java │ │ │ ├── PasswordParameter.java │ │ │ ├── Plugin.java │ │ │ ├── PluginManager.java │ │ │ ├── PluginPageObject.java │ │ │ ├── PostBuildStep.java │ │ │ ├── Scm.java │ │ │ ├── ScmPolling.java │ │ │ ├── SecurityRealm.java │ │ │ ├── ServletSecurityRealm.java │ │ │ ├── ShellBuildStep.java │ │ │ ├── Slave.java │ │ │ ├── SlavesMixIn.java │ │ │ ├── SnippetGenerator.java │ │ │ ├── Step.java │ │ │ ├── StringParameter.java │ │ │ ├── TextAxis.java │ │ │ ├── TextParameter.java │ │ │ ├── TimerTrigger.java │ │ │ ├── ToolInstallation.java │ │ │ ├── ToolInstallationPageObject.java │ │ │ ├── TopLevelItem.java │ │ │ ├── Trigger.java │ │ │ ├── UpdateCenter.java │ │ │ ├── UpstreamJobTrigger.java │ │ │ ├── User.java │ │ │ ├── View.java │ │ │ ├── ViewsMixIn.java │ │ │ ├── WhoAmI.java │ │ │ ├── WizardCreateAdminUser.java │ │ │ ├── WizardCustomizeJenkins.java │ │ │ ├── WizardLogin.java │ │ │ ├── WorkflowJob.java │ │ │ ├── WorkflowMultiBranchJob.java │ │ │ └── Workspace.java │ │ │ ├── recorder │ │ │ ├── HarRecorder.java │ │ │ ├── JUnitScreenRecorder.java │ │ │ ├── SupportBundle.java │ │ │ └── TestRecorderRule.java │ │ │ ├── selenium │ │ │ ├── Scroller.java │ │ │ └── UselessFileDetectorReplacement.java │ │ │ ├── server │ │ │ ├── ChannelStream.java │ │ │ ├── JenkinsControllerPoolProcess.java │ │ │ └── PooledJenkinsController.java │ │ │ ├── slave │ │ │ ├── LocalSlaveController.java │ │ │ ├── LocalSlaveProvider.java │ │ │ ├── SlaveController.java │ │ │ └── SlaveProvider.java │ │ │ ├── update_center │ │ │ ├── CachedUpdateCenterMetadataLoader.java │ │ │ ├── Dependency.java │ │ │ ├── DownloadOverrideUpdateCenterMetadataDecorator.java │ │ │ ├── LocalOverrideUpdateCenterMetadataDecoratorImpl.java │ │ │ ├── MockUpdateCenter.java │ │ │ ├── PluginMetadata.java │ │ │ ├── PluginSpec.java │ │ │ ├── UpdateCenterMetadata.java │ │ │ ├── UpdateCenterMetadataDecorator.java │ │ │ └── UpdateCenterMetadataProvider.java │ │ │ └── utils │ │ │ ├── AccessTokenGenerator.java │ │ │ ├── ElasticTime.java │ │ │ ├── GNUCLibrary.java │ │ │ ├── HttpUtils.java │ │ │ ├── IOUtil.java │ │ │ ├── MavenLocalRepository.java │ │ │ ├── PipelineTestUtils.java │ │ │ ├── SHA1Sum.java │ │ │ ├── SauceLabsConnection.java │ │ │ ├── SupportBundleRequest.java │ │ │ ├── SystemEnvironmentVariables.java │ │ │ ├── aether │ │ │ ├── AetherModule.java │ │ │ ├── ArtifactResolverUtil.java │ │ │ └── ConsoleTransferListener.java │ │ │ ├── groovy │ │ │ ├── ClosureScript.java │ │ │ └── InteractiveConsole.java │ │ │ ├── keycloack │ │ │ └── KeycloakUtils.java │ │ │ ├── mail │ │ │ └── MailhogProvider.java │ │ │ ├── pluginTests │ │ │ └── SecurityDisabler.java │ │ │ └── pluginreporter │ │ │ ├── ConsoleExercisedPluginReporter.java │ │ │ ├── ExercisedPluginsReporter.java │ │ │ └── TextFileExercisedPluginReporter.java │ ├── resources │ │ ├── ath-container │ │ │ ├── Dockerfile │ │ │ ├── run.sh │ │ │ └── set-java.sh │ │ ├── log4j.properties │ │ └── org │ │ │ └── jenkinsci │ │ │ └── test │ │ │ └── acceptance │ │ │ ├── docker │ │ │ └── fixtures │ │ │ │ ├── ArtifactoryContainer │ │ │ │ └── Dockerfile │ │ │ │ ├── FtpdContainer │ │ │ │ └── Dockerfile │ │ │ │ ├── GitContainer │ │ │ │ ├── Dockerfile │ │ │ │ ├── unsafe │ │ │ │ └── unsafe.pub │ │ │ │ ├── GitLabContainer │ │ │ │ ├── Dockerfile │ │ │ │ └── create_user.rb │ │ │ │ ├── JavaGitContainer │ │ │ │ ├── Dockerfile │ │ │ │ ├── unsafe │ │ │ │ └── unsafe.pub │ │ │ │ ├── JiraContainer │ │ │ │ └── Dockerfile │ │ │ │ ├── LdapContainer │ │ │ │ ├── Dockerfile │ │ │ │ └── config │ │ │ │ │ ├── base.ldif │ │ │ │ │ ├── cn=config.ldif │ │ │ │ │ ├── cn=config │ │ │ │ │ ├── cn=module{0}.ldif │ │ │ │ │ ├── cn=schema.ldif │ │ │ │ │ ├── cn=schema │ │ │ │ │ │ ├── cn={0}core.ldif │ │ │ │ │ │ ├── cn={1}cosine.ldif │ │ │ │ │ │ ├── cn={2}nis.ldif │ │ │ │ │ │ └── cn={3}inetorgperson.ldif │ │ │ │ │ ├── olcBackend={0}mdb.ldif │ │ │ │ │ ├── olcDatabase={-1}frontend.ldif │ │ │ │ │ ├── olcDatabase={0}config.ldif │ │ │ │ │ └── olcDatabase={1}mdb.ldif │ │ │ │ │ └── slapd.sh │ │ │ │ ├── MailhogContainer │ │ │ │ └── Dockerfile │ │ │ │ ├── SMBContainer │ │ │ │ └── Dockerfile │ │ │ │ ├── SshAgentContainer │ │ │ │ ├── Dockerfile │ │ │ │ ├── ed25519.pass │ │ │ │ ├── ed25519.priv │ │ │ │ └── ed25519.pub │ │ │ │ ├── SvnContainer │ │ │ │ ├── Dockerfile │ │ │ │ ├── config │ │ │ │ │ ├── dav_svn.conf │ │ │ │ │ ├── passwd │ │ │ │ │ ├── passwd.htpasswd │ │ │ │ │ ├── supervisord.conf │ │ │ │ │ ├── svnserve.conf │ │ │ │ │ └── viewvc.conf │ │ │ │ └── svnRepo │ │ │ │ │ ├── simpleProject │ │ │ │ │ └── testTwo.txt │ │ │ │ │ └── testOne.txt │ │ │ │ ├── Tomcat10Container │ │ │ │ └── Dockerfile │ │ │ │ └── XvncSlaveContainer │ │ │ │ └── Dockerfile │ │ │ ├── machine │ │ │ └── autoterminate.sh │ │ │ ├── plugins │ │ │ └── ant │ │ │ │ └── fake-ant.sh │ │ │ └── selenium │ │ │ ├── disable-sticky-elements.js │ │ │ └── scroller.js │ └── tool_installers │ │ └── updates │ │ ├── hudson.plugins.gradle.GradleInstaller │ │ ├── hudson.plugins.groovy.GroovyInstaller │ │ ├── hudson.tasks.Ant.AntInstaller │ │ ├── hudson.tasks.Maven.MavenInstaller │ │ └── hudson.tools.JDKInstaller └── test │ ├── java │ ├── UnixDomainSocketTestServer.java │ ├── core │ │ ├── ArtifactsTest.java │ │ ├── BuildHistoryTest.java │ │ ├── CreateItemTest.java │ │ ├── CredentialsTest.java │ │ ├── FormValidationTest.java │ │ ├── FreestyleJobTest.java │ │ ├── InstallWizardTest.java │ │ ├── JdkTest.java │ │ ├── JenkinsDatabaseSecurityRealmTest.java │ │ ├── PluginManagerTest.java │ │ ├── PublisherOrderTest.java │ │ ├── ScriptTest.java │ │ ├── SlaveTest.java │ │ ├── TriggerRemoteBuildsTest.java │ │ └── ViewTest.java │ ├── org │ │ └── jenkinsci │ │ │ └── test │ │ │ └── acceptance │ │ │ ├── ByFactoryTest.java │ │ │ ├── junit │ │ │ ├── WithJavaOptionsTest.java │ │ │ └── WithPluginsTest.java │ │ │ ├── po │ │ │ ├── PluginManagerTest.java │ │ │ └── SnippetGeneratorTest.java │ │ │ ├── recorder │ │ │ ├── HarRecorderTest.java │ │ │ └── TestRecorderRuleTest.java │ │ │ └── update_center │ │ │ └── UpdateCenterMetadataTest.java │ └── plugins │ │ ├── AbstractJobRelatedTest.java │ │ ├── ActiveDirectoryTest.java │ │ ├── AntPluginTest.java │ │ ├── AntisamyMarkupFormatterTest.java │ │ ├── ArtifactoryPluginTest.java │ │ ├── AuditTrailPluginTest.java │ │ ├── AuthorizeProjectTest.java │ │ ├── BuildTimeoutPluginTest.java │ │ ├── CompressArtifactsPluginTest.java │ │ ├── ConfigFileProviderTest.java │ │ ├── ConfigurationAsCodeTest.java │ │ ├── CopyArtifactPluginTest.java │ │ ├── CredentialsBindingTest.java │ │ ├── DashboardViewPluginTest.java │ │ ├── DeclarativeAssistantMigrationTest.java │ │ ├── DeclarativePipelineTest.java │ │ ├── DeployPluginTest.java │ │ ├── DescriptionSetterPluginTest.java │ │ ├── DiskUsagePluginTest.java │ │ ├── DisplayUrlApiTest.java │ │ ├── DockerBuildStepTest.java │ │ ├── EmailExtPluginTest.java │ │ ├── EnvInjectPluginTest.java │ │ ├── ExternalWorkspaceManagerPluginTest.java │ │ ├── ExtraColumnsPluginTest.java │ │ ├── FavoriteTest.java │ │ ├── FolderPluginTest.java │ │ ├── GerritTriggerTest.java │ │ ├── GitLabPluginTest.java │ │ ├── GitPluginTest.java │ │ ├── GradlePluginTest.java │ │ ├── GroovyPluginTest.java │ │ ├── HtmlPublisherPluginTest.java │ │ ├── JUnitPluginTest.java │ │ ├── JavadocPluginTest.java │ │ ├── JiraPluginTest.java │ │ ├── JobConfigHistoryPluginTest.java │ │ ├── JobDslPluginTest.java │ │ ├── LdapPluginTest.java │ │ ├── LogParserTest.java │ │ ├── MSBuildPluginTest.java │ │ ├── MSTestRunnerPluginTest.java │ │ ├── MailWatcherPluginTest.java │ │ ├── MailerPluginTest.java │ │ ├── MatrixAuthPluginTest.java │ │ ├── MatrixPluginTest.java │ │ ├── MavenPluginTest.java │ │ ├── MetricsTest.java │ │ ├── NestedViewPluginTest.java │ │ ├── NodeLabelParameterPluginTest.java │ │ ├── OicAuthPluginTest.java │ │ ├── ParameterizedTriggerTest.java │ │ ├── PipelineTest.java │ │ ├── PlainCredentialsBindingTest.java │ │ ├── PostBuildScriptPluginTest.java │ │ ├── PrioritySorterPluginTest.java │ │ ├── ProjectDescriptionSetterPluginTest.java │ │ ├── SSHCredentialsTest.java │ │ ├── ScriptSecurityPluginTest.java │ │ ├── ScriptlerPluginTest.java │ │ ├── SecureRequesterWhitelistTest.java │ │ ├── SshSlavesPluginTest.java │ │ ├── StageViewTest.java │ │ ├── SubversionPluginTest.java │ │ ├── SupportCorePluginTest.java │ │ ├── TimestamperPluginTest.java │ │ ├── WorkflowMultibranchTest.java │ │ ├── WorkflowPluginTest.java │ │ ├── WsCleanupPluginTest.java │ │ ├── XUnitPluginTest.java │ │ └── XvncPluginTest.java │ └── resources │ ├── artifactory_plugin │ ├── multimodule │ │ ├── module_a │ │ │ └── pom.xml │ │ ├── module_b │ │ │ └── pom.xml │ │ └── pom.xml │ └── quickstart │ │ ├── build.gradle │ │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── src │ │ ├── main │ │ ├── java │ │ │ └── org │ │ │ │ └── gradle │ │ │ │ └── Person.java │ │ └── resources │ │ │ └── org │ │ │ └── gradle │ │ │ └── resource.xml │ │ └── test │ │ ├── java │ │ └── org │ │ │ └── gradle │ │ │ └── PersonTest.java │ │ └── resources │ │ └── org │ │ └── gradle │ │ └── test-resource.xml │ ├── configuration_as_code │ └── trivial.yaml │ ├── credentialsbinding │ ├── secretFile │ ├── secretFileScript │ ├── secretFileScriptWindows │ ├── secretTextScript │ ├── secretTextScriptWindows │ ├── secretZip.zip │ ├── secretZipFileScript │ ├── secretZipFileScriptWindows │ ├── sshUserPrivateKeyScript │ ├── sshUserPrivateKeyScriptWindows │ ├── usernameSplitPasswordScript │ ├── usernameSplitPasswordScriptWindows │ ├── usernameTogetherPasswordScript │ └── usernameTogetherPasswordScriptWindows │ ├── deploy_plugin │ └── build-war.sh │ ├── docker_build_step │ └── context.dir │ │ └── Dockerfile │ ├── gradle_plugin │ ├── pipeline_test_multiple_tasks.txt │ ├── script.gradle │ └── scriptNoPlugins.gradle │ ├── htmlpublisher_plugin │ ├── home.html │ └── style.css │ ├── job_dsl_plugin │ ├── CreateFolder.groovy │ ├── CreateJobInFolder.groovy │ ├── MyUtilities.groovy │ └── Utility.jar │ ├── 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 │ ├── logparser_plugin │ ├── console-outputs │ │ ├── output-JENKINS33085 │ │ └── sample-log │ └── rules │ │ ├── log-parser-rule-markings │ │ ├── log-parser-rules-JENKINS33085 │ │ └── log-parser-rules-sample │ ├── maven_plugin │ └── multimodule │ │ ├── module_a │ │ └── pom.xml │ │ ├── module_b │ │ └── pom.xml │ │ └── pom.xml │ ├── msbuild_plugin │ ├── projProject │ │ ├── HelloWorld.cs │ │ └── project.proj │ └── slnProject │ │ ├── HelloWorld.cs │ │ ├── project.proj │ │ └── project.sln │ ├── org │ └── jenkinsci │ │ └── test │ │ └── acceptance │ │ └── po │ │ └── ant-1.0.hpi │ ├── pipelines │ └── hello-world │ │ └── Jenkinsfile │ ├── plaincredentialsbinding │ └── secretFile │ ├── plugins │ └── ant │ │ ├── custom-build-file.xml │ │ └── echo-helloworld.xml │ ├── publish_over_ssh_plugin │ └── lorem-ipsum.txt │ ├── scriptler_plugin │ ├── hello_parameterized.groovy │ └── hello_world.groovy │ ├── stageview_plugin │ ├── multi_job.txt │ ├── multi_job_aborted.txt │ ├── multi_job_fail.txt │ ├── multi_job_irregularnames.txt │ ├── multi_job_unstable.txt │ └── single_job.txt │ └── textfinder_plugin │ ├── textfinder-result_failed.log │ ├── textfinder-result_success.log │ └── textfinder-result_warning.log ├── vars.cmd └── vars.sh /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # .git-blame-ignore-revs 2 | # Format repository with Spotless (#1707) 3 | 224beaaf72d33daedd167b0123b6741008dc539a 4 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | _extends: .github 2 | -------------------------------------------------------------------------------- /.github/workflows/cd.yml: -------------------------------------------------------------------------------- 1 | # Note: additional setup is required, see https://www.jenkins.io/redirect/continuous-delivery-of-plugins 2 | 3 | name: cd 4 | on: 5 | workflow_dispatch: 6 | check_run: 7 | types: 8 | - completed 9 | 10 | jobs: 11 | maven-cd: 12 | uses: jenkins-infra/github-reusable-workflows/.github/workflows/maven-cd.yml@v1 13 | secrets: 14 | MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }} 15 | MAVEN_TOKEN: ${{ secrets.MAVEN_TOKEN }} 16 | -------------------------------------------------------------------------------- /.github/workflows/verify-gradle-wrapper.yaml: -------------------------------------------------------------------------------- 1 | name: Validate Gradle wrapper 2 | on: [pull_request, push] 3 | jobs: 4 | build_pr: 5 | if: github.repository_owner == 'jenkinsci' 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: Checkout Repository 9 | uses: actions/checkout@v4 10 | - name: Validate Gradle Wrapper 11 | uses: gradle/wrapper-validation-action@v3 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | jenkins*.war 2 | /*.log 3 | .DS_Store 4 | *.swp 5 | *.swn 6 | *~ 7 | .vagrant 8 | iso 9 | *.box 10 | workspace/ 11 | path-element.hpi 12 | slave.jar 13 | temp_dir_* 14 | .buildpath 15 | .project 16 | target 17 | .classpath 18 | .settings/ 19 | jenkins*home/ 20 | .idea/ 21 | *.iml 22 | *.iws 23 | *.ipr 24 | jenkins-plugins/ 25 | .jenkins_test/ 26 | .history 27 | .vscode 28 | -------------------------------------------------------------------------------- /.mvn/extensions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | io.jenkins.tools.incrementals 4 | git-changelist-maven-extension 5 | 1.8 6 | 7 | 8 | -------------------------------------------------------------------------------- /.mvn/jvm.config: -------------------------------------------------------------------------------- 1 | -Xmx512m -XX:+HeapDumpOnOutOfMemoryError -XX:+TieredCompilation -XX:TieredStopAtLevel=1 2 | -------------------------------------------------------------------------------- /.mvn/maven.config: -------------------------------------------------------------------------------- 1 | -Pconsume-incrementals 2 | -Pmight-produce-incrementals 3 | -Dchangelist.format=%d.v%s 4 | -------------------------------------------------------------------------------- /Jenkinsfile.infra.ci.jenkins.io: -------------------------------------------------------------------------------- 1 | // This pipeline runs on infra.ci.jenkins.io (private) to build, test and deploy the Docker image 2 | buildDockerAndPublishImage('ath', [ 3 | automaticSemanticVersioning: false, 4 | gitCredentials: 'jenkinsci-ath-ghapp', // Only available in infra.ci.jenkins.io 5 | dockerfile: 'src/main/resources/ath-container/Dockerfile', 6 | imageDir: 'src/main/resources/ath-container/', 7 | registryNamespace: 'jenkins', 8 | ]) 9 | -------------------------------------------------------------------------------- /ath-container.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -uo pipefail 3 | 4 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" 5 | 6 | # Obtain the group ID to grant to access the Docker socket 7 | if [[ -z ${DOCKER_GID:-} ]]; then 8 | DOCKER_GID=$(docker run --rm -v /var/run/docker.sock:/var/run/docker.sock:Z ubuntu:noble stat -c %g /var/run/docker.sock) || exit 1 9 | export DOCKER_GID 10 | fi 11 | 12 | "${DIR}/build-image.sh" || exit 1 13 | 14 | trap 'docker-compose kill && docker-compose down' EXIT 15 | 16 | docker-compose run --name mvn --rm -P -v "${HOME}/.m2/repository:/home/ath-user/.m2/repository:Z" mvn bash -c 'set-java.sh 17; bash' 17 | status=$? 18 | 19 | exit $status 20 | -------------------------------------------------------------------------------- /build-image.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -uo pipefail 3 | 4 | uid=$(id -u) || exit 1 5 | gid=$(id -g) || exit 1 6 | 7 | # high chance of uid / group already existing in the container 8 | # known to happen on macOS 9 | if ((uid < 1000)); then 10 | uid=1001 11 | fi 12 | 13 | if ((gid < 1000)); then 14 | gid=1001 15 | fi 16 | 17 | # Obtain the group ID to grant to access the Docker socket 18 | if [[ -z ${DOCKER_GID:-} ]]; then 19 | DOCKER_GID=$(docker run --rm -v /var/run/docker.sock:/var/run/docker.sock:Z ubuntu:noble stat -c %g /var/run/docker.sock) || exit 1 20 | export DOCKER_GID 21 | fi 22 | 23 | docker-compose pull || exit 1 24 | docker-compose build --build-arg=uid="$uid" --build-arg=gid="$gid" || exit 1 25 | 26 | exit 0 27 | -------------------------------------------------------------------------------- /ci.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -uo pipefail 3 | 4 | jdk="$1" 5 | browser="$2" 6 | jenkinsVersion="$3" 7 | 8 | # Obtain the group ID to grant to access the Docker socket 9 | if [[ -z ${DOCKER_GID:-} ]]; then 10 | DOCKER_GID=$(docker run --rm -v /var/run/docker.sock:/var/run/docker.sock:Z ubuntu:noble stat -c %g /var/run/docker.sock) || exit 1 11 | export DOCKER_GID 12 | fi 13 | 14 | trap 'docker-compose kill && docker-compose down' EXIT 15 | 16 | docker-compose run -e "MAVEN_ARGS=${MAVEN_ARGS}" --name mvn -T --rm -v "${MAVEN_SETTINGS}:${MAVEN_SETTINGS}:Z" mvn bash -s <<-INSIDE 17 | set-java.sh ${jdk} 18 | 19 | # Ensure that Jenkins node setup does not influence the container Java setup 20 | unset JAVA_HOME 21 | 22 | java -version 23 | mvn -v 24 | 25 | run.sh remote-webdriver-${browser} ${jenkinsVersion} -Dmaven.test.failure.ignore=true -Dcsp.rule -DforkCount=1 -B 26 | INSIDE 27 | status=$? 28 | 29 | if [[ -d target/surefire-reports ]]; then 30 | find target/surefire-reports -type f -name 'TEST-*.xml' -print0 | 31 | xargs -0 sed -i 's!\[\[ATTACHMENT|/home/ath-user/sources/target\(/[^]]*\)\]\]![[ATTACHMENT|'"$PWD"'/target\1]]!g' 32 | else 33 | echo 'No test results to be saved' 34 | fi 35 | 36 | exit $status 37 | -------------------------------------------------------------------------------- /core-commit.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | # 5 | # Extract the core commit from the WAR. 6 | # 7 | # TODO handle transitive dependencies like Stapler, Remoting, etc. 8 | # 9 | 10 | war= 11 | if [[ -f target/jenkins-war.war ]]; then 12 | war=target/jenkins-war.war 13 | elif [[ -f jenkins.war ]]; then 14 | war=jenkins.war 15 | else 16 | echo 'Failed to locate WAR' >&2 17 | exit 1 18 | fi 19 | 20 | jar xf "${war}" META-INF/MANIFEST.MF 21 | core_commit=$(awk '/Implementation-Build:/ {print $2}' META-INF/MANIFEST.MF) 22 | rm -f META-INF/MANIFEST.MF 23 | rm -df META-INF 24 | echo "${core_commit}" 25 | -------------------------------------------------------------------------------- /docs/EXERCISEDPLUGINSREPORTER.md: -------------------------------------------------------------------------------- 1 | # Exercised Plugins Report 2 | It is possible to create an **Exercised Plugins** Report by specifying the `EXERCISEDPLUGINREPORTER` environment variable. 3 | 4 | ## Reporter Types 5 | The following types are available: 6 | 7 | * `console` (default) 8 | * `textfile` 9 | 10 | ## Console Reporter 11 | The Console Reporter simply logs the plugin and its version using the default logger. 12 | 13 | Here is an example: 14 | 15 | Plugin ldap/1.20.2 is installed 16 | 17 | ## Text File Reporter 18 | The Text File Reporter will create a properties file in the `target` folder containing a list of plugin names and their versions prefixed by the test name. 19 | 20 | Here is an example: 21 | 22 | plugins.LdapPluginTest\:\:ldap = 1.10.2 23 | plugins.ActiveDirectoryTest\:\:active-directory = 1.38 24 | 25 | This Reporter type can be very useful when you want to be able to see which plugins and their versions were tested with a particular version of Jenkins Core. 26 | 27 | Note: The output file is re-created at the start of each test suite run. 28 | 29 | -------------------------------------------------------------------------------- /docs/INVESTIGATION.md: -------------------------------------------------------------------------------- 1 | # Investigating a failed test 2 | 3 | ## Interactive investigation 4 | 5 | As an alternative to setting a breakpoint, that would stop the test suite and keep Jenkins and browser running for manual investigation. 6 | There is an environment variable `INTERACTIVE=true` that, when provided, will pause the suite whenever a test fails/throws exception. 7 | 8 | You can also add a call to `InteractiveConsole.execute(this)` in the code to stop the execution and debug in interactive groovy console. 9 | 10 | ## Diagnostic information 11 | 12 | Test harness keeps track of test diagnostic information in `/target/diagnostics/` directory. 13 | For every reported file there is a [JUnit Attachments](https://wiki.jenkins-ci.org/display/JENKINS/JUnit+Attachments+Plugin) marker line 14 | printed in order to attach the diagnostic information to the test result when run in Jenkins. 15 | 16 | All executed tests are screen recorded by default, but only videos of failing tests are persited to the `target` directory. 17 | By default, each video file is named with the fully qualified test class name, minus sign (-) and the test method name. 18 | 19 | You can configure what is persisted by using an environment variable or a Java system property called `RECORDER`. 20 | Possible values are: 21 | 22 | * off 23 | * failuresOnly 24 | * always 25 | 26 | The Java system property takes precedence over environment variable. 27 | -------------------------------------------------------------------------------- /docs/MACHINE-CONFIG.md: -------------------------------------------------------------------------------- 1 | # Machine configuration 2 | 3 | You can launch pools of Machines each pool targeted to a Jenkins master or slave. 4 | Here you will create two subworlds, one for master and another one for slave. 5 | See [Wiring](WIRING.md) for details on SubWorld and wiring different pieces. 6 | 7 | ## How to configure 8 | 9 | As defined in [Wiring](WIRING.md), all the configuration parameters are Guice Named parameters. 10 | You should provide configuration in a groovy script. 11 | 12 | ## Ec2Provider configuration 13 | 14 | See [EC2 Configuration](EC2-CONFIG.md). 15 | -------------------------------------------------------------------------------- /docs/MATCHERS.md: -------------------------------------------------------------------------------- 1 | # Using Hamcrest matchers 2 | 3 | Using hamcrest matchers is a preferred way to writing assertions. 4 | See [Matchers](https://github.com/jenkinsci/acceptance-test-harness/blob/master/src/main/java/org/jenkinsci/test/acceptance/Matchers.java) 5 | class for an inspiration of how those can look like. 6 | Note the convenience (typesafe) [Matcher](https://github.com/jenkinsci/acceptance-test-harness/blob/master/src/main/java/org/jenkinsci/test/acceptance/Matcher.java) 7 | superclass we use to avoid unnecessary verbosity: 8 | 9 | public static Matcher hasContent(final Pattern pattern) { 10 | return new Matcher("Text matching %s", pattern) { 11 | @Override 12 | protected boolean matchesSafely(WebDriver item) { 13 | return pattern.matcher(pageText(item)).find(); 14 | } 15 | 16 | @Override 17 | protected void describeMismatchSafely(WebDriver item, Description mismatchDescription) { 18 | mismatchDescription.appendText("was ") 19 | .appendValue(item.getCurrentUrl()) 20 | .appendText("\n") 21 | .appendValue(pageText(item)); 22 | } 23 | 24 | private String pageText(WebDriver item) { 25 | return item.findElement(by.xpath("/html")).getText(); 26 | } 27 | }; 28 | } 29 | 30 | General purpose matchers should be available as static methods of the `Matchers` class. 31 | Plugin specific matchers should be defined in JUnit class or in dedicated `*Matcher` class. 32 | -------------------------------------------------------------------------------- /docs/MIXIN.md: -------------------------------------------------------------------------------- 1 | # Mix-in Page Objects 2 | Sometimes, different Jenkins model objects have common traits. 3 | For example, both Jenkins root object and views act as a container of jobs, and they offer a common set of operations, like creating/deleting a job, 4 | starting a build. 5 | 6 | In situations like this we want their corresponding page objects to share a common set of methods. 7 | To promote this, the test harness defines them in a separate class that extends from a marker type called `MixIn`. 8 | 9 | Mix-in page objects are just normal page objects that have the exact same URL as some other page objects. 10 | The common convention is for the "primary" page object to keep them in its public final field like this: 11 | 12 | 13 | public class View extends ContainerPageObject { 14 | public final JobsMixIn jobs = new JobsMixIn(this); 15 | ... 16 | } 17 | 18 | And the calling clients can use this like: 19 | 20 | View view = ...; 21 | FreeStyleProject f = view.jobs.create(); 22 | 23 | -------------------------------------------------------------------------------- /docs/SINGLE-TEST.md: -------------------------------------------------------------------------------- 1 | # Specifying tests to run 2 | 3 | There are several profiles that might be handy for specifying tests to run: 4 | 5 | - `-PrunSmokeTests` - only the essential tests to execute the most fundamental use cases. 6 | - `-PrunDockerTests` - only tests that require docker. 7 | - `-PskipCucumberTests` - skip tests implemented in Cucumber. 8 | - `-PtestOnlyPlugins` - only tests that require plugins specified in the `TEST_ONLY_PLUGINS` environment variable (comma separated artifact ids). 9 | 10 | ## JUnit 11 | To run a single JUnit test from the command line, specify the name of the test with the `-Dtest=` option: 12 | 13 | mvn -Dtest=AntPluginTest#autoInstallAnt test 14 | 15 | It need not specify a fully qualified class name. 16 | See [Maven surefire plugin](http://maven.apache.org/surefire/maven-surefire-plugin/examples/single-test.html) for 17 | more details about how to specify a group of tests. 18 | -------------------------------------------------------------------------------- /docs/SUPPORT-BUNDLE.md: -------------------------------------------------------------------------------- 1 | # Support bundle 2 | 3 | If [support-core](https://github.com/jenkinsci/support-core-plugin) plugin is installed during the test execution, a support bundle will be captured and attached to the test scenario. 4 | This behaviour is executed only in CI environment, and is disabled when running a test locally. 5 | 6 | The behaviour can be overridden if necessary by setting the environment variable `CAPTURE_SUPPORT_BUNDLE=true` or `CAPTURE_SUPPORT_BUNDLE=false` depending on the desired behaviour. 7 | -------------------------------------------------------------------------------- /docs/USING-A-HTTP-PROXY.md: -------------------------------------------------------------------------------- 1 | # Running with a http proxy 2 | If your environment requires a HTTP proxy, then you must configure your setup as follows: 3 | 4 | ## Maven settings 5 | Ensure that your Maven user settings file contains the proxy information: 6 | 7 | ```xml 8 | 9 | 10 | true 11 | http 12 | www-proxy.mycompany.com 13 | 8080 14 | 15 | 16 | 127.0.0.1|localhost|*.mycompany.com 17 | 18 | 19 | ``` 20 | 21 | See [Maven Guide to Proxies](http://maven.apache.org/guides/mini/guide-proxies.html) for more details. 22 | 23 | ## Command line arguments 24 | The following arguments are needed on the command line in order for the tests to install plugins: 25 | 26 | mvn -Dtest=WarningsPluginTest -Dhttp.proxyHost=www-proxy.mycompany.com -Dhttp.proxyPort=8080 -Dhttps.proxyHost=www-proxy.mycompany.com -Dhttps.proxyPort=8080 -Dhttp.nonProxyHosts=*.mycompany.com test 27 | 28 | TODO: be able to tell the Browser spawned during the tests to use the proxy information specified via command line parameters. 29 | -------------------------------------------------------------------------------- /docs/img/debuging-ath-containerized-from-idea.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/acceptance-test-harness/ca87b2b59e5aaecfa38fc78dff83083ad465f379/docs/img/debuging-ath-containerized-from-idea.png -------------------------------------------------------------------------------- /docs/img/exporting_docker_host_steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/acceptance-test-harness/ca87b2b59e5aaecfa38fc78dff83083ad465f379/docs/img/exporting_docker_host_steps.png -------------------------------------------------------------------------------- /etc/templates/assertions_entry_point_class_template.txt: -------------------------------------------------------------------------------- 1 | package ${package}; 2 | 3 | /** 4 | * Entry point for assertions of different data types. Each method in this class is a static factory for the 5 | * type-specific assertion objects. 6 | */ 7 | @javax.annotation.Generated(value="assertj-assertions-generator") 8 | public class Assertions extends org.assertj.core.api.Assertions { 9 | ${all_assertions_entry_points} 10 | /** 11 | * Creates a new {@link Assertions}. 12 | */ 13 | protected Assertions() { 14 | // empty 15 | } 16 | } -------------------------------------------------------------------------------- /grab-latest-rc.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eux 3 | curl -L https://get.jenkins.io/war-rc/latest/jenkins.war >jenkins.war 4 | -------------------------------------------------------------------------------- /jut-server.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | DIR="$(cd "$(dirname "$0")" && pwd)" 3 | CMD="$DIR/target/appassembler/bin/jut-server" 4 | if [[ ! -s $CMD ]]; then 5 | mvn package -DskipTests -f "$DIR/pom.xml" 6 | fi 7 | sh "$CMD" "$@" 8 | -------------------------------------------------------------------------------- /single-plugin.groovy: -------------------------------------------------------------------------------- 1 | // Run tests that requires plugins enumerated in TEST_ONLY_PLUGINS variable. 2 | // 3 | // 'TEST_ONLY_PLUGINS=git,envinject' run all tests that require git or envinject 4 | // using WithPlugins annotations 5 | 6 | import org.junit.runner.Description; 7 | import org.junit.runners.model.Statement; 8 | 9 | import org.jenkinsci.test.acceptance.junit.FilterRule.Filter; 10 | import org.jenkinsci.test.acceptance.junit.WithPlugins; 11 | import org.jenkinsci.test.acceptance.update_center.PluginSpec; 12 | 13 | import java.lang.annotation.Annotation; 14 | 15 | bind Filter toInstance new FilterImpl(); 16 | 17 | class FilterImpl extends Filter { 18 | public String whySkip(Statement base, Description desc) { 19 | for (annot in getAnnotations(desc, WithPlugins.class)) { 20 | for (value in annot.value()) { 21 | if (testOnlyPlugins().contains(new PluginSpec(value).name)) { 22 | return null; 23 | } 24 | } 25 | } 26 | 27 | return "Running only tests for plugins: ${testOnlyPlugins()}"; 28 | } 29 | 30 | private Collection testOnlyPlugins() { 31 | return (System.getenv("TEST_ONLY_PLUGINS") ?: "").split(",").each { it.trim() }; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/controller/IJenkinsController.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.controller; 2 | 3 | import java.io.Closeable; 4 | import java.io.IOException; 5 | import java.net.URL; 6 | 7 | /** 8 | * Remoting interface for {@link JenkinsController}. 9 | * 10 | * @author Kohsuke Kawaguchi 11 | */ 12 | public interface IJenkinsController extends Closeable { 13 | URL getUrl(); 14 | 15 | void start() throws IOException; 16 | 17 | void stop() throws IOException; 18 | /** 19 | * Populates the Jenkins Home with the specified ZIP template. 20 | * Jenkins will not be restarted, so if the content would require a restart you have to do this yourself. 21 | * @param template The template (ZIP format). 22 | * @param clean if {@code true} then the home will be wiped clean before the template is applied. If false then 23 | * the template will simply overwrite the existing (if any) home. 24 | */ 25 | void populateJenkinsHome(byte[] template, boolean clean) throws IOException; 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/controller/JenkinsControllerFactory.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.controller; 2 | 3 | import com.cloudbees.sdk.extensibility.ExtensionPoint; 4 | 5 | /** 6 | * Extension point for instantiating {@link JenkinsController} from command-line options / environments. 7 | * 8 | * @author Kohsuke Kawaguchi 9 | */ 10 | @ExtensionPoint 11 | public interface JenkinsControllerFactory { 12 | /** 13 | * Unique short name that distinguishes this controller from others. 14 | *

15 | * User can select the factory by specifying its ID to the "TYPE" environment variable. 16 | */ 17 | String getId(); 18 | 19 | JenkinsController create(); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/docker/DockerModule.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.docker; 2 | 3 | import com.cloudbees.sdk.extensibility.Extension; 4 | import com.cloudbees.sdk.extensibility.ExtensionModule; 5 | import com.google.inject.AbstractModule; 6 | 7 | /** 8 | * @author Kohsuke Kawaguchi 9 | */ 10 | @Extension 11 | public class DockerModule extends AbstractModule implements ExtensionModule { 12 | @Override 13 | protected void configure() { 14 | requestStaticInjection(Docker.class); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/docker/fixtures/ArtifactoryContainer.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.docker.fixtures; 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URL; 5 | import org.jenkinsci.test.acceptance.docker.DockerContainer; 6 | import org.jenkinsci.test.acceptance.docker.DockerFixture; 7 | 8 | /** 9 | * Runs Artifactory OSS container 10 | */ 11 | @DockerFixture(id = "artifactory", ports = 8081) 12 | public class ArtifactoryContainer extends DockerContainer { 13 | 14 | public URL getURL() { 15 | try { 16 | return new URL("http://" + ipBound(8081) + ":" + port(8081) + "/artifactory"); 17 | } catch (MalformedURLException ex) { 18 | throw new AssertionError(ex); 19 | } 20 | } 21 | 22 | /** 23 | * Rest Api to verify Artifactory is up and running 24 | */ 25 | public URL getPingURL() throws MalformedURLException { 26 | return new URL("http://" + ipBound(8081) + ":" + port(8081) + "/artifactory/api/system/ping"); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/docker/fixtures/IPasswordDockerContainer.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.docker.fixtures; 2 | 3 | /** 4 | * gets username and password for a service on a docker container 5 | * 6 | * @author Tobias Meyer 7 | */ 8 | public interface IPasswordDockerContainer { 9 | /** 10 | * Gets the passsword for a service on the docker server 11 | * 12 | * @return password 13 | */ 14 | String getPassword(); 15 | /** 16 | * Gets the username for a service on the docker server 17 | * 18 | * @return username 19 | */ 20 | String getUsername(); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/docker/fixtures/JavaGitContainer.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.docker.fixtures; 2 | 3 | import org.jenkinsci.test.acceptance.docker.DockerFixture; 4 | 5 | @DockerFixture(id = "javagit", ports = 22) 6 | public class JavaGitContainer extends GitContainer { 7 | /** Local path. */ 8 | @Override 9 | public String getRepoUrl() { 10 | return "file:///" + REPO_DIR; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/docker/fixtures/SMBContainer.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.docker.fixtures; 2 | 3 | import org.jenkinsci.test.acceptance.docker.DockerContainer; 4 | import org.jenkinsci.test.acceptance.docker.DockerFixture; 5 | 6 | /** 7 | * Represents a server with SMB. 8 | * 9 | * @author Tobias Meyer 10 | */ 11 | @DockerFixture( 12 | id = "smb", 13 | ports = {445, 139, 135}) 14 | public class SMBContainer extends DockerContainer implements IPasswordDockerContainer { 15 | private final String username = "test"; 16 | 17 | private final String password = "test"; 18 | 19 | /** 20 | * Gets the samba password of the samba user on the docker server 21 | * 22 | * @return Samba password 23 | */ 24 | @Override 25 | public String getPassword() { 26 | return password; 27 | } 28 | 29 | /** 30 | * Gets the username of the samba user on the docker server 31 | * 32 | * @return Samba username 33 | */ 34 | @Override 35 | public String getUsername() { 36 | return username; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/docker/fixtures/Tomcat10Container.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.docker.fixtures; 2 | 3 | import java.io.IOException; 4 | import java.net.URL; 5 | import org.jenkinsci.test.acceptance.docker.DockerContainer; 6 | import org.jenkinsci.test.acceptance.docker.DockerFixture; 7 | 8 | /** 9 | * Runs stock Tomcat 7 container. 10 | * 11 | * @author Kohsuke Kawaguchi 12 | */ 13 | @DockerFixture(id = "tomcat10", ports = 8080) 14 | public class Tomcat10Container extends DockerContainer { 15 | /** 16 | * URL of Tomcat. 17 | */ 18 | public URL getUrl() throws IOException { 19 | return new URL("http://" + ipBound(8080) + ":" + port(8080)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/guice/AutoCleaned.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.guice; 2 | 3 | import java.io.Closeable; 4 | 5 | /** 6 | * Marks instances that want to run some shutdown action 7 | * at the end of their scope. 8 | *

9 | * When a test scope exits, all the existing instances that implement this interface 10 | * gets its {@link #close()} method invoked. 11 | * 12 | *

13 | * Currently this only works with {@link TestScope}. 14 | * 15 | * @see TestCleaner 16 | * @author Kohsuke Kawaguchi 17 | */ 18 | public interface AutoCleaned extends Closeable {} 19 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/guice/SubWorld.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.guice; 2 | 3 | import com.google.inject.Injector; 4 | import com.google.inject.Provider; 5 | 6 | /** 7 | * Represents a parallel Guice {@link Injector} inside {@link World} 8 | * so that components can be selectively bound to {@link World}. 9 | * 10 | *

11 | * See WIRING.md 12 | * 13 | * @author Kohsuke Kawaguchi 14 | */ 15 | public class SubWorld { 16 | /*package*/ Injector injector; 17 | /*package*/ String name; 18 | 19 | /*package*/ SubWorld() {} 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public Injector getInjector() { 26 | return injector; 27 | } 28 | 29 | /** 30 | * This is a part of the DSL construct that allows people to say: 31 | * 32 | *

33 |      * subworld "masters" {
34 |      *     ...
35 |      *     bind Foo to ...
36 |      * }
37 |      *
38 |      * bind Foo toProvider masters[Foo]  // export Foo from the "masters" subworld to the parent
39 |      * 
40 | */ 41 | public Provider getAt(Class t) { 42 | return injector.getProvider(t); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/guice/TestCleaner.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.guice; 2 | 3 | import com.google.inject.Inject; 4 | import java.util.List; 5 | 6 | /** 7 | * {@link Cleaner} at the end of each {@link TestScope}. 8 | *

9 | * Oftentimes marking your class with {@link AutoCleaned} gets the job done. 10 | * 11 | * @author Kohsuke Kawaguchi 12 | */ 13 | @TestScope 14 | public class TestCleaner extends Cleaner { 15 | @Inject 16 | TestLifecycle lifecycle; 17 | 18 | @Override 19 | public List performCleanUp() { 20 | List errors = super.performCleanUp(); 21 | for (Object o : lifecycle.getInstances()) { 22 | if (o instanceof AutoCleaned) { 23 | try { 24 | ((AutoCleaned) o).close(); 25 | } catch (Throwable t) { 26 | System.out.println(o + " clean up failed"); 27 | t.printStackTrace(); 28 | errors.add(t); 29 | } 30 | } 31 | } 32 | return errors; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/guice/TestName.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.guice; 2 | 3 | import jakarta.inject.Provider; 4 | 5 | /** 6 | * Keeps track of the current test name. 7 | * 8 | * @author Kohsuke Kawaguchi 9 | */ 10 | @TestScope 11 | public class TestName implements Provider { 12 | /*package*/ String testName; 13 | 14 | public TestName() {} 15 | 16 | public TestName(String testName) { 17 | this.testName = testName; 18 | } 19 | 20 | @Override 21 | public String get() { 22 | return testName; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/guice/TestScope.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.guice; 2 | 3 | import com.google.inject.ScopeAnnotation; 4 | import java.lang.annotation.Documented; 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Inherited; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.RetentionPolicy; 9 | import java.lang.annotation.Target; 10 | 11 | /** 12 | * Indicates that instances of this component are scoped to each test case. 13 | *

14 | * {@link TestScope} is tied to a thread that executes a test, in anticipation of multi-threaded 15 | * concurrent test executions. See {@link World} 16 | * 17 | * @author Kohsuke Kawaguchi 18 | */ 19 | @Retention(RetentionPolicy.RUNTIME) 20 | @Target({ElementType.TYPE, ElementType.METHOD}) 21 | @Inherited 22 | @Documented 23 | @ScopeAnnotation 24 | public @interface TestScope {} 25 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/guice/TestScopeModule.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.guice; 2 | 3 | import com.cloudbees.sdk.extensibility.Extension; 4 | import com.cloudbees.sdk.extensibility.ExtensionModule; 5 | import com.google.inject.AbstractModule; 6 | 7 | /** 8 | * Defines {@link TestScope} and exposes {@link TestLifecycle} to clean-up test-scoped instances. 9 | * 10 | * @author Kohsuke Kawaguchi 11 | */ 12 | @Extension 13 | public class TestScopeModule extends AbstractModule implements ExtensionModule { 14 | @Override 15 | protected void configure() { 16 | TestLifecycle tl = new TestLifecycle(); 17 | bindScope(TestScope.class, tl); 18 | bind(TestLifecycle.class).toInstance(tl); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/guice/WorldCleaner.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.guice; 2 | 3 | import jakarta.inject.Singleton; 4 | 5 | /** 6 | * {@link Cleaner} at the end of {@link Singleton}. 7 | * 8 | * @author Kohsuke Kawaguchi 9 | */ 10 | @Singleton 11 | public class WorldCleaner extends Cleaner {} 12 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/junit/DockerTest.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.junit; 2 | 3 | /** 4 | * Marker interface to identify a Docker test. Used to get categories working properly with {@link WithDocker}. 5 | * 6 | * @author Andrew Bayer 7 | */ 8 | public interface DockerTest { 9 | // marker interface 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/junit/GlobalRule.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.junit; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | import org.junit.rules.TestRule; 9 | import org.jvnet.hudson.annotation_indexer.Indexed; 10 | 11 | /** 12 | * {@link TestRule} to be applied on all tests globally. 13 | *

14 | * Annotate {@link TestRule} to have it run for every test. 15 | * See {@link RuleAnnotation} optional rule registration. 16 | * 17 | * @author ogondza 18 | */ 19 | @Retention(RetentionPolicy.RUNTIME) 20 | @Target(ElementType.TYPE) 21 | @Documented 22 | @Indexed 23 | public @interface GlobalRule { 24 | 25 | /** 26 | * Optional ordering among rules. 27 | *

28 | * Annotation with {@code priority >= 0} are guaranteed to be run after 29 | * Jenkins is up. Negative priorities are run before startup on best effort 30 | * basis. (It might not happen before for ExistingJenkinsController, 31 | * PooledJenkinsController and possibly others). 32 | *

33 | * Annotations that skips execution are encouraged to run before Jenkins is 34 | * booted up to save time. Note, that these implementations can not inject 35 | * Jenkins for obvious reasons. 36 | */ 37 | int priority() default 0; 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/junit/RuleFailedException.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.junit; 2 | 3 | import org.junit.rules.TestRule; 4 | 5 | /** 6 | * This is a service exception that wraps the TestRule failure to all traceability back to failing test rules. 7 | */ 8 | public class RuleFailedException extends RuntimeException { 9 | private static final long serialVersionUID = 183080398115494371L; 10 | 11 | private final String failedRule; 12 | 13 | public RuleFailedException(Throwable throwable, TestRule failingRule) { 14 | super(throwable); 15 | failedRule = failingRule.getClass().getName(); 16 | } 17 | 18 | @Override 19 | public String getMessage() { 20 | return "TestRule " + failedRule + " failed: " + super.getMessage(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/junit/SmokeTest.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.junit; 2 | 3 | /** 4 | * Marker interface to identify a smoke test. A smoke test is a test that basically uses one important aspect of the 5 | * acceptance testing framework. Run these smoke tests in order to get a first impression if a framework change did not 6 | * break anything. The overall number of smoke tests should be less than 10. 7 | * 8 | * @author Ullrich Hafner 9 | */ 10 | public interface SmokeTest { 11 | // marker interface 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/junit/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Glue to write acceptance tests in JUnit. 3 | */ 4 | package org.jenkinsci.test.acceptance.junit; 5 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/log/LogListenable.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.log; 2 | 3 | import org.jenkinsci.test.acceptance.controller.JenkinsController; 4 | 5 | /** 6 | * Produces line-by-line log. 7 | *

8 | * Among other things, optionally implemented by {@link JenkinsController} that provides access 9 | * to the console output. 10 | * 11 | * @author Kohsuke Kawaguchi 12 | */ 13 | public interface LogListenable { 14 | void addLogListener(LogListener l); 15 | 16 | void removeLogListener(LogListener l); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/log/LogListener.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.log; 2 | 3 | import hudson.remoting.Asynchronous; 4 | import java.io.IOException; 5 | 6 | /** 7 | * Receives line-by-line logs from {@link LogListenable}. 8 | * 9 | * @see LogListenable 10 | * @author Kohsuke Kawaguchi 11 | */ 12 | public interface LogListener { 13 | /** 14 | * Receives log output from Jenkins process one line at a time, in the order. 15 | */ 16 | @Asynchronous 17 | void processLine(String line) throws IOException; 18 | 19 | /** 20 | * Indicates the EOF. 21 | * 22 | * @param t 23 | * if the termination of log source is unexpected, indicate the cause of the problem. 24 | */ 25 | @Asynchronous 26 | void processClose(Exception t); 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/log/LogPrinter.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.log; 2 | 3 | import java.io.IOException; 4 | 5 | /** 6 | * Prints out the received log with a prefix. 7 | * 8 | * @author Kohsuke Kawaguchi 9 | */ 10 | public class LogPrinter implements LogListener { 11 | private final String prefix; 12 | 13 | public LogPrinter(String id) { 14 | this.prefix = id == null ? "" : id + "|"; 15 | } 16 | 17 | @Override 18 | public void processLine(String line) throws IOException { 19 | System.out.println(prefix + line); 20 | } 21 | 22 | @Override 23 | public void processClose(Exception t) {} 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/log/LogSplitter.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.log; 2 | 3 | import java.io.IOException; 4 | import java.util.List; 5 | import java.util.concurrent.CopyOnWriteArrayList; 6 | 7 | /** 8 | * Receives logs from {@link LogListener} and distributes them to other {@link LogListener}s. 9 | * 10 | * @author Kohsuke Kawaguchi 11 | */ 12 | public class LogSplitter implements LogListenable, LogListener { 13 | private final List listeners = new CopyOnWriteArrayList<>(); 14 | 15 | @Override 16 | public void addLogListener(LogListener l) { 17 | listeners.add(l); 18 | } 19 | 20 | @Override 21 | public void removeLogListener(LogListener l) { 22 | listeners.remove(l); 23 | } 24 | 25 | public List getListeners() { 26 | return listeners; 27 | } 28 | 29 | @Override 30 | public void processLine(String line) throws IOException { 31 | for (LogListener l : listeners) { 32 | l.processLine(line); 33 | } 34 | } 35 | 36 | @Override 37 | public void processClose(Exception t) { 38 | for (LogListener l : listeners) { 39 | l.processClose(t); 40 | } 41 | } 42 | 43 | public void clear() { 44 | listeners.clear(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/log/NullPrinter.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.log; 2 | 3 | import java.io.IOException; 4 | 5 | /** 6 | * Does not print anything. 7 | * 8 | * @author Ullrich Hafner 9 | */ 10 | public class NullPrinter implements LogListener { 11 | @Override 12 | public void processLine(final String line) throws IOException { 13 | // nothing to print 14 | } 15 | 16 | @Override 17 | public void processClose(final Exception t) { 18 | // nothing to print 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/machine/JenkinsProvider.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.machine; 2 | 3 | import com.google.inject.Provider; 4 | import org.jenkinsci.test.acceptance.controller.JenkinsController; 5 | 6 | @Deprecated 7 | public abstract class JenkinsProvider implements Provider {} 8 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/ant/AntBuildStep.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.ant; 2 | 3 | import org.jenkinsci.test.acceptance.po.AbstractStep; 4 | import org.jenkinsci.test.acceptance.po.BuildStep; 5 | import org.jenkinsci.test.acceptance.po.Control; 6 | import org.jenkinsci.test.acceptance.po.Describable; 7 | import org.jenkinsci.test.acceptance.po.Job; 8 | 9 | /** 10 | * Ant job configuration UI. 11 | * 12 | * @author Kohsuke Kawaguchi 13 | */ 14 | @Describable("Invoke Ant") 15 | public class AntBuildStep extends AbstractStep implements BuildStep { 16 | public final Control targets = control("targets"); 17 | public final Control antName = control("antName"); 18 | 19 | public AntBuildStep(Job parent, String path) { 20 | super(parent, path); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/audit_trail/AuditTrailGlobalConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.audit_trail; 2 | 3 | import org.jenkinsci.test.acceptance.po.Control; 4 | import org.jenkinsci.test.acceptance.po.JenkinsConfig; 5 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 6 | 7 | /** 8 | * Global configuration section of the audit-trail plugin. 9 | * 10 | * @author Kohsuke Kawaguchi 11 | */ 12 | public class AuditTrailGlobalConfiguration extends PageAreaImpl { 13 | 14 | public final Control addLogger = control("hetero-list-add[loggers]"); 15 | 16 | public AuditTrailGlobalConfiguration(JenkinsConfig context) { 17 | super(context, "/hudson-plugins-audit_trail-AuditTrailPlugin"); 18 | } 19 | 20 | // TODO 21 | // public LoggerPageObject addLogger() { 22 | // addLogger.selectDropdownMenu("Log file"); 23 | // .... 24 | // } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/authorize_project/BuildAccessControl.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.authorize_project; 2 | 3 | import org.jenkinsci.test.acceptance.po.GlobalSecurityConfig; 4 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 5 | 6 | /** 7 | * Base type for {@link PageAreaImpl} for Build Access Control. 8 | */ 9 | public class BuildAccessControl extends PageAreaImpl { 10 | 11 | public BuildAccessControl(GlobalSecurityConfig security, String path) { 12 | super(security, path); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/authorize_project/ProjectDefaultBuildAccessControl.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.authorize_project; 2 | 3 | import org.jenkinsci.test.acceptance.po.Control; 4 | import org.jenkinsci.test.acceptance.po.Describable; 5 | import org.jenkinsci.test.acceptance.po.GlobalSecurityConfig; 6 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 7 | 8 | /** 9 | * Base type for {@link PageAreaImpl} for Project Default Build Access Control. 10 | */ 11 | @Describable("Project default Build Authorization") 12 | public class ProjectDefaultBuildAccessControl extends BuildAccessControl { 13 | 14 | public final Control strategy = 15 | control(by.path("/jenkins-security-QueueItemAuthenticatorConfiguration/authenticators/")); 16 | public final Control userId = control(by.name("_.userid")); 17 | 18 | public ProjectDefaultBuildAccessControl(GlobalSecurityConfig security, String path) { 19 | super(security, path); 20 | } 21 | 22 | public ProjectDefaultBuildAccessControl runAsSpecificUser(final String user) { 23 | strategy.select("Run as Specific User"); 24 | userId.waitFor(); 25 | userId.sendKeys(user); 26 | return this; 27 | } 28 | 29 | /** 30 | * Run a build as the user who triggered it. 31 | * @return The Project Default Build Access Control. 32 | */ 33 | public ProjectDefaultBuildAccessControl runAsUserWhoTriggered() { 34 | strategy.select("Run as User who Triggered Build"); 35 | return this; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/config_file_provider/CustomConfig.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.config_file_provider; 2 | 3 | import org.jenkinsci.test.acceptance.po.CodeMirror; 4 | import org.jenkinsci.test.acceptance.po.Describable; 5 | 6 | /** 7 | * Class for custom config files. 8 | */ 9 | @Describable("Custom file") 10 | public class CustomConfig extends ProvidedFile { 11 | 12 | public CustomConfig(ConfigFileProvider context, String id) { 13 | super(context, id); 14 | } 15 | 16 | /** 17 | * @param customContent the content to set 18 | */ 19 | @Override 20 | public void content(String customContent) { 21 | new CodeMirror(this, "/config/content").set(customContent); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/config_file_provider/MavenSettingsConfig.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.config_file_provider; 2 | 3 | import org.jenkinsci.test.acceptance.po.CodeMirror; 4 | import org.jenkinsci.test.acceptance.po.Control; 5 | import org.jenkinsci.test.acceptance.po.Describable; 6 | 7 | /** 8 | * Class for Maven Settings files. 9 | */ 10 | @Describable("Maven settings.xml") 11 | public class MavenSettingsConfig extends ProvidedFile { 12 | 13 | public final Control replaceAll = control("/config/isReplaceAll"); 14 | 15 | public MavenSettingsConfig(ConfigFileProvider context, String id) { 16 | super(context, id); 17 | } 18 | 19 | @Override 20 | public void content(String mvnSettings) { 21 | new CodeMirror(this, "/config/content").set(mvnSettings); 22 | } 23 | 24 | public void replaceAll(final boolean replaceAll) { 25 | this.replaceAll.check(replaceAll); 26 | } 27 | 28 | public ServerCredentialMapping addServerCredentialMapping() { 29 | final String path = createPageArea("/config/serverCredentialMappings", () -> control("/config/repeatable-add") 30 | .click()); 31 | 32 | return new ServerCredentialMapping(this, path); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/config_file_provider/ServerCredentialMapping.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.config_file_provider; 2 | 3 | import org.jenkinsci.test.acceptance.po.Control; 4 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 5 | 6 | /** 7 | * Class for Server Credentials in Maven Settings files. 8 | */ 9 | public class ServerCredentialMapping extends PageAreaImpl { 10 | 11 | public final Control serverId = control("serverId"); 12 | public final Control credentialsId = control("credentialsId"); 13 | 14 | public ServerCredentialMapping(final MavenSettingsConfig mvnSettingsConfig, String path) { 15 | super(mvnSettingsConfig, path); 16 | } 17 | 18 | public void serverId(final String id) { 19 | this.serverId.sendKeys(id); 20 | } 21 | 22 | public void credentialsId(final String credId) { 23 | this.credentialsId.select(credId); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/credentials/Domain.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.credentials; 2 | 3 | import org.jenkinsci.test.acceptance.po.Control; 4 | import org.jenkinsci.test.acceptance.po.Describable; 5 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 6 | 7 | @Describable("Credential Domain") 8 | public class Domain extends PageAreaImpl { 9 | 10 | public final Control name = control(by.name("_.name")); 11 | public final Control description = control(by.name("description")); 12 | 13 | public final Control addCredentialButton = control("/hetero-list-add[credentials]"); 14 | public final Control addSpecificationButton = control("/domain/hetero-list-add[specifications]"); 15 | 16 | public Domain(ManagedCredentials context, String path) { 17 | super(context, path); 18 | } // TO REMOVE 19 | 20 | public Domain(DomainPage context, String path) { 21 | super(context, path); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/credentials/FileCredentials.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.credentials; 2 | 3 | import org.jenkinsci.test.acceptance.po.Control; 4 | import org.jenkinsci.test.acceptance.po.Describable; 5 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 6 | import org.jenkinsci.test.acceptance.po.PageObject; 7 | 8 | @Describable("Secret file") 9 | public class FileCredentials extends BaseStandardCredentials { 10 | 11 | public Control file = control("file"); 12 | 13 | public FileCredentials(PageObject context, String path) { 14 | super(context, path); 15 | } 16 | 17 | public FileCredentials(PageAreaImpl area, String relativePath) { 18 | super(area, relativePath); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/credentials/StringCredentials.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.credentials; 2 | 3 | import org.jenkinsci.test.acceptance.po.Control; 4 | import org.jenkinsci.test.acceptance.po.Describable; 5 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 6 | import org.jenkinsci.test.acceptance.po.PageObject; 7 | 8 | @Describable("Secret text") 9 | public class StringCredentials extends BaseStandardCredentials { 10 | 11 | public Control secret = control("secret"); 12 | 13 | public StringCredentials(PageObject context, String path) { 14 | super(context, path); 15 | } 16 | 17 | public StringCredentials(PageAreaImpl area, String relativePath) { 18 | super(area, relativePath); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/credentials/UserPwdCredential.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.credentials; 2 | 3 | import org.jenkinsci.test.acceptance.po.Control; 4 | import org.jenkinsci.test.acceptance.po.Describable; 5 | import org.jenkinsci.test.acceptance.po.PageArea; 6 | import org.jenkinsci.test.acceptance.po.PageObject; 7 | 8 | /** 9 | * @author Kohsuke Kawaguchi 10 | */ 11 | @Describable("Username with password") 12 | public class UserPwdCredential extends BaseStandardCredentials { 13 | public final Control username = control(by.name("_.username")); 14 | public final Control password = control(by.name("_.password")); 15 | 16 | public UserPwdCredential(PageObject context, String path) { 17 | super(context, path); 18 | } 19 | 20 | public UserPwdCredential(PageArea area, String relativePath) { 21 | super(area, relativePath); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/credentialsbinding/CredentialsBinding.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.credentialsbinding; 2 | 3 | import org.jenkinsci.test.acceptance.po.ContainerPageObject; 4 | import org.jenkinsci.test.acceptance.po.Control; 5 | import org.jenkinsci.test.acceptance.po.PageArea; 6 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 7 | import org.openqa.selenium.NoSuchElementException; 8 | 9 | /** 10 | * Represents a credential binding in the job configuration page. 11 | */ 12 | public class CredentialsBinding extends PageAreaImpl { 13 | 14 | public Control credentialId = control("credentialId"); 15 | public Control variable = control("variable"); 16 | 17 | public CredentialsBinding(PageArea area, String path) { 18 | super(area, path); 19 | } 20 | 21 | public CredentialsBinding(ContainerPageObject po, String path) { 22 | super(po, path); 23 | } 24 | 25 | /** 26 | * Checks whether there are credentials in the credentials drop down 27 | * 28 | * @return true if there are no credentials, false otherwise 29 | */ 30 | public boolean noCredentials() { 31 | try { 32 | credentialId.resolve().findElement(by.tagName("option")); 33 | return false; 34 | } catch (NoSuchElementException ex) { 35 | return true; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/credentialsbinding/ManagedCredentialsBinding.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.credentialsbinding; 2 | 3 | import org.jenkinsci.test.acceptance.po.ContainerPageObject; 4 | 5 | public class ManagedCredentialsBinding extends ContainerPageObject { 6 | 7 | public ManagedCredentialsBinding(ContainerPageObject po) { 8 | super(po, po.url("configure/")); 9 | } 10 | 11 | /** 12 | * Adds a credential binding of the type passed as parameter 13 | * 14 | */ 15 | public T addCredentialBinding(final Class type) { 16 | String path = createPageArea( 17 | "/org-jenkinsci-plugins-credentialsbinding-impl-SecretBuildWrapper/bindings", () -> control( 18 | by.path( 19 | "/org-jenkinsci-plugins-credentialsbinding-impl-SecretBuildWrapper/hetero-list-add[bindings]")) 20 | .selectDropdownMenu(type)); 21 | return newInstance(type, this, path); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/credentialsbinding/SecretFileCredentialsBinding.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.credentialsbinding; 2 | 3 | import org.jenkinsci.test.acceptance.po.ContainerPageObject; 4 | import org.jenkinsci.test.acceptance.po.Describable; 5 | 6 | @Describable("Secret file") 7 | public class SecretFileCredentialsBinding extends CredentialsBinding { 8 | 9 | public SecretFileCredentialsBinding(ContainerPageObject po, String path) { 10 | super(po, path); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/credentialsbinding/SecretStringCredentialsBinding.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.credentialsbinding; 2 | 3 | import org.jenkinsci.test.acceptance.po.ContainerPageObject; 4 | import org.jenkinsci.test.acceptance.po.Describable; 5 | 6 | @Describable("Secret text") 7 | public class SecretStringCredentialsBinding extends CredentialsBinding { 8 | 9 | public SecretStringCredentialsBinding(ContainerPageObject po, String path) { 10 | super(po, path); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/dashboard_view/AbstractDashboardViewPortlet.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.dashboard_view; 2 | 3 | import org.jenkinsci.test.acceptance.po.Control; 4 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 5 | 6 | /** 7 | * A portlet that is shown in the {@link DashboardView}. 8 | * 9 | * @author Fabian Trampusch 10 | */ 11 | public class AbstractDashboardViewPortlet extends PageAreaImpl { 12 | private Control name = control("name"); 13 | 14 | protected AbstractDashboardViewPortlet(DashboardView parent, String path) { 15 | super(parent, path); 16 | } 17 | 18 | /** 19 | * Deletes the portlet, i.e. removes it from the dashboard. 20 | */ 21 | public void delete() { 22 | control("repeatable-delete").click(); 23 | } 24 | 25 | /** 26 | * Sets the name of the portlet. 27 | * 28 | * @param name the name of the portlet 29 | */ 30 | public void setName(String name) { 31 | this.name.set(name); 32 | } 33 | 34 | /** 35 | * Returns the name of the portlet. 36 | * 37 | * @return the name of the portlet 38 | */ 39 | public String getName() { 40 | return this.name.resolve().getAttribute("value"); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/dashboard_view/read/BreadCrumbs.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.dashboard_view.read; 2 | 3 | import java.util.List; 4 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 5 | import org.jenkinsci.test.acceptance.po.PageObject; 6 | import org.openqa.selenium.By; 7 | import org.openqa.selenium.WebElement; 8 | 9 | /** 10 | * Provides a simple area for reading the breadcrumbs on the page. 11 | * 12 | * @author Peter Müller 13 | */ 14 | public class BreadCrumbs extends PageAreaImpl { 15 | 16 | /** 17 | * The path to the breadcrumbs list. 18 | */ 19 | final By nameCrumb = By.xpath("//ol[@id=\"breadcrumbs\"] | //ul[@id=\"breadcrumbs\"]"); 20 | 21 | /** 22 | * Create a new object for reading the breadcrumbs in the dashboard view. 23 | */ 24 | public BreadCrumbs(PageObject context, String path) { 25 | super(context, path); 26 | } 27 | 28 | /** 29 | * Get the text of the breadcrumbs from left to right. 30 | * 31 | * @return List of text in each breadcrumb. 32 | */ 33 | public List getBreadCrumbs() { 34 | final WebElement webElement = find(nameCrumb); 35 | final String[] crumbs = webElement.getText().split("\n"); 36 | return List.of(crumbs); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/dashboard_view/read/MainPanel.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.dashboard_view.read; 2 | 3 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 4 | import org.jenkinsci.test.acceptance.po.PageObject; 5 | import org.openqa.selenium.By; 6 | 7 | /** 8 | * Provides a simple readonly area for the main panel. 9 | * 10 | * @author Peter Müller 11 | */ 12 | public class MainPanel extends PageAreaImpl { 13 | 14 | final By tabName = By.xpath("//div[@id=\"main-panel\"]//div[@class=\"tab active\"]/a"); 15 | final By descriptionPath = 16 | By.xpath("//div[@id=\"main-panel\"]/div[@id=\"view-message\"]/div[@id=\"description\"]/div[1]"); 17 | 18 | public MainPanel(PageObject context, String path) { 19 | super(context, path); 20 | } 21 | 22 | /** 23 | * Get the current active tab name. 24 | * 25 | * @return the name of the currently open tab 26 | */ 27 | public String getTabName() { 28 | return find(tabName).getText(); 29 | } 30 | 31 | /** 32 | * Get the description of the dashboard. 33 | * 34 | * @return the description of the dashboard 35 | */ 36 | public String getDescription() { 37 | return find(descriptionPath).getText(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/deploy/DeployPublisher.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.deploy; 2 | 3 | import org.jenkinsci.test.acceptance.po.AbstractStep; 4 | import org.jenkinsci.test.acceptance.po.Control; 5 | import org.jenkinsci.test.acceptance.po.Describable; 6 | import org.jenkinsci.test.acceptance.po.Job; 7 | import org.jenkinsci.test.acceptance.po.PostBuildStep; 8 | import org.openqa.selenium.NoSuchElementException; 9 | 10 | /** 11 | * @author Kohsuke Kawaguchi 12 | */ 13 | @Describable("Deploy war/ear to a container") 14 | public class DeployPublisher extends AbstractStep implements PostBuildStep { 15 | public DeployPublisher(Job parent, String path) { 16 | super(parent, path); 17 | } 18 | 19 | public final Control war = control("war"); 20 | public final Control contextPath = control("contextPath"); 21 | public final Control url = control("adapters/url"); 22 | 23 | public void setCredentials(String credentials) { 24 | control("adapters/credentialsId").select(credentials); 25 | } 26 | 27 | public void useContainer(String... container) { 28 | RuntimeException last = new RuntimeException("No container names provided"); 29 | for (String c : container) { 30 | try { 31 | control("hetero-list-add[adapters]").selectDropdownMenu(c); 32 | return; 33 | } catch (NoSuchElementException ex) { 34 | last = ex; 35 | } 36 | } 37 | throw last; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/description_setter/BuildDescriptionSetter.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.description_setter; 2 | 3 | import org.jenkinsci.test.acceptance.po.AbstractStep; 4 | import org.jenkinsci.test.acceptance.po.Control; 5 | import org.jenkinsci.test.acceptance.po.Describable; 6 | import org.jenkinsci.test.acceptance.po.Job; 7 | import org.jenkinsci.test.acceptance.po.PostBuildStep; 8 | 9 | /** 10 | * @author Kohsuke Kawaguchi 11 | */ 12 | @Describable("Set build description") 13 | public class BuildDescriptionSetter extends AbstractStep implements PostBuildStep { 14 | public BuildDescriptionSetter(Job parent, String path) { 15 | super(parent, path); 16 | } 17 | 18 | public final Control description = control("description"); 19 | public final Control regexp = control("regexp"); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/email_ext/EmailExtPublisher.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.email_ext; 2 | 3 | import org.jenkinsci.test.acceptance.po.AbstractStep; 4 | import org.jenkinsci.test.acceptance.po.Control; 5 | import org.jenkinsci.test.acceptance.po.Describable; 6 | import org.jenkinsci.test.acceptance.po.Job; 7 | import org.jenkinsci.test.acceptance.po.PostBuildStep; 8 | 9 | /** 10 | * @author Kohsuke Kawaguchi 11 | */ 12 | @Describable("Editable Email Notification") 13 | public class EmailExtPublisher extends AbstractStep implements PostBuildStep { 14 | public final Control subject = control("project_default_subject"); 15 | private final Control recipient = control("project_recipient_list", "recipientlist_recipients"); 16 | public final Control body = control("project_default_content"); 17 | 18 | private boolean advacedOpened; 19 | 20 | public EmailExtPublisher(Job parent, String path) { 21 | super(parent, path); 22 | } 23 | 24 | public void setRecipient(String r) { 25 | recipient.set(r); 26 | 27 | ensureAdvancedOpened(); 28 | control("project_triggers/hetero-list-add[recipientProviders]").selectDropdownMenu("Recipient List"); 29 | } 30 | 31 | public void ensureAdvancedOpened() { 32 | if (!advacedOpened) { 33 | control("advanced-button").click(); 34 | advacedOpened = true; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/external_workspace_manager/ExternalGlobalConfig.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.external_workspace_manager; 2 | 3 | import org.jenkinsci.test.acceptance.po.JenkinsConfig; 4 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 5 | 6 | /** 7 | * Helper class for interacting with External Workspace Manager Plugin global config page. 8 | * 9 | * @author Alexandru Somai 10 | */ 11 | public class ExternalGlobalConfig extends PageAreaImpl { 12 | 13 | public ExternalGlobalConfig(JenkinsConfig context) { 14 | super(context, "/org-jenkinsci-plugins-ewm-steps-ExwsAllocateStep"); 15 | } 16 | 17 | public void addDiskPool( 18 | String diskPoolId, String diskOneId, String diskTwoId, String mountToDiskOne, String mountToDiskTwo) { 19 | // add disk pool 20 | control("repeatable-add").click(); 21 | control("diskPools/diskPoolId").set(diskPoolId); 22 | 23 | // add first disk 24 | control("diskPools/repeatable-add").click(); 25 | control("diskPools/disks/diskId").set(diskOneId); 26 | control("diskPools/disks/masterMountPoint").set(mountToDiskOne); 27 | 28 | // add second disk 29 | control("diskPools/repeatable-add").click(); 30 | control("diskPools/disks[1]/diskId").set(diskTwoId); 31 | control("diskPools/disks[1]/masterMountPoint").set(mountToDiskTwo); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/external_workspace_manager/ExternalNodeConfig.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.external_workspace_manager; 2 | 3 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 4 | import org.jenkinsci.test.acceptance.po.Slave; 5 | 6 | /** 7 | * Helper class for interacting with External Workspace Manager Plugin node config page. 8 | * 9 | * @author Alexandru Somai 10 | */ 11 | public class ExternalNodeConfig extends PageAreaImpl { 12 | 13 | public ExternalNodeConfig(Slave context) { 14 | super(context, "/nodeProperties/org-jenkinsci-plugins-ewm-nodes-ExternalWorkspaceProperty"); 15 | } 16 | 17 | public void setConfig(String diskPoolId, String diskOneId, String diskTwoId, String fakeMountingPoint) { 18 | // set disk pool 19 | control(by.checkbox("External Workspace")).click(); 20 | control("repeatable-add").click(); 21 | control("nodeDiskPools/diskPoolRefId").set(diskPoolId); 22 | 23 | // add first disk 24 | control("nodeDiskPools/repeatable-add").click(); 25 | control("nodeDiskPools/nodeDisks/diskRefId").set(diskOneId); 26 | control("nodeDiskPools/nodeDisks/nodeMountPoint").set(fakeMountingPoint); 27 | 28 | // add second disk 29 | control("nodeDiskPools/repeatable-add").click(); 30 | control("nodeDiskPools/nodeDisks[1]/diskRefId").set(diskTwoId); 31 | control("nodeDiskPools/nodeDisks[1]/nodeMountPoint").set(fakeMountingPoint); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/extra_columns/LastConsoleColumn.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.extra_columns; 2 | 3 | import org.jenkinsci.test.acceptance.po.AbstractListViewColumn; 4 | import org.jenkinsci.test.acceptance.po.Describable; 5 | import org.jenkinsci.test.acceptance.po.ListView; 6 | 7 | /** 8 | * Column for the last console output. 9 | * 10 | * @author Ullrich Hafner 11 | */ 12 | @Describable("Last/Current Build Console Output") 13 | public class LastConsoleColumn extends AbstractListViewColumn { 14 | public LastConsoleColumn(ListView parent, String path) { 15 | super(parent, path); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/git_client/JGitInstallation.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.git_client; 2 | 3 | import java.util.regex.Pattern; 4 | import org.jenkinsci.test.acceptance.po.ConfigurablePageObject; 5 | import org.jenkinsci.test.acceptance.po.Control; 6 | import org.jenkinsci.test.acceptance.po.Jenkins; 7 | import org.jenkinsci.test.acceptance.po.ToolInstallation; 8 | import org.jenkinsci.test.acceptance.po.ToolInstallationPageObject; 9 | 10 | @ToolInstallationPageObject(name = "Git", installer = "hudson.tools.ZipExtractionInstaller") 11 | public class JGitInstallation extends ToolInstallation { 12 | 13 | public JGitInstallation(Jenkins jenkins, String path) { 14 | super(jenkins, path); 15 | } 16 | 17 | public static JGitInstallation addJGit(Jenkins jenkins) { 18 | ConfigurablePageObject toolsPage = ToolInstallation.ensureConfigPage(jenkins); 19 | 20 | final String name = JGitInstallation.class 21 | .getAnnotation(ToolInstallationPageObject.class) 22 | .name(); 23 | final Control button = toolsPage.control(by.button("Add " + name)); 24 | 25 | String pathPrefix = 26 | button.resolve().getAttribute("path").replaceAll(Pattern.quote("hetero-list-add[tool]"), "tool"); 27 | return ToolInstallation.addTool( 28 | jenkins, JGitInstallation.class, pathPrefix, () -> button.selectDropdownMenu("JGit")); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/git_client/ssh_host_key_verification/AcceptFirstConnectionStrategy.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.git_client.ssh_host_key_verification; 2 | 3 | import org.jenkinsci.test.acceptance.po.Describable; 4 | 5 | @Describable("org.jenkinsci.plugins.gitclient.verifier.AcceptFirstConnectionStrategy") 6 | public class AcceptFirstConnectionStrategy extends SshHostKeyVerificationStrategy { 7 | @Override 8 | public String id() { 9 | return "0"; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/git_client/ssh_host_key_verification/KnownHostsFileStrategy.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.git_client.ssh_host_key_verification; 2 | 3 | import org.jenkinsci.test.acceptance.po.Describable; 4 | 5 | @Describable("org.jenkinsci.plugins.gitclient.verifier.KnownHostsFileVerificationStrategy") 6 | public class KnownHostsFileStrategy extends SshHostKeyVerificationStrategy { 7 | @Override 8 | public String id() { 9 | return "1"; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/git_client/ssh_host_key_verification/ManuallyProvidedKeysStrategy.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.git_client.ssh_host_key_verification; 2 | 3 | import org.jenkinsci.test.acceptance.po.Describable; 4 | 5 | @Describable("org.jenkinsci.plugins.gitclient.verifier.ManuallyProvidedKeyVerificationStrategy") 6 | public class ManuallyProvidedKeysStrategy extends SshHostKeyVerificationStrategy { 7 | @Override 8 | public String id() { 9 | return "2"; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/git_client/ssh_host_key_verification/NoVerificationStrategy.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.git_client.ssh_host_key_verification; 2 | 3 | import org.jenkinsci.test.acceptance.po.Describable; 4 | 5 | @Describable("org.jenkinsci.plugins.gitclient.verifier.NoHostKeyVerificationStrategy") 6 | public class NoVerificationStrategy extends SshHostKeyVerificationStrategy { 7 | @Override 8 | public String id() { 9 | return "3"; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/git_client/ssh_host_key_verification/SshHostKeyVerificationStrategy.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.git_client.ssh_host_key_verification; 2 | 3 | public abstract class SshHostKeyVerificationStrategy { 4 | 5 | public abstract String id(); 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/gitlab_plugin/GitLabBranchSource.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.gitlab_plugin; 2 | 3 | import org.jenkinsci.test.acceptance.plugins.workflow_multibranch.BranchSource; 4 | import org.jenkinsci.test.acceptance.plugins.workflow_shared_library.WorkflowSharedLibrary; 5 | import org.jenkinsci.test.acceptance.po.Describable; 6 | import org.jenkinsci.test.acceptance.po.WorkflowMultiBranchJob; 7 | 8 | @Describable("GitLab Project") 9 | public class GitLabBranchSource extends BranchSource { 10 | 11 | public GitLabBranchSource(WorkflowMultiBranchJob job, String path) { 12 | super(job, path); 13 | } 14 | 15 | public GitLabBranchSource(WorkflowSharedLibrary sharedLibrary, String path) { 16 | super(sharedLibrary, path); 17 | } 18 | 19 | public void setOwner(String owner) { 20 | find(by.path("/sources/source/projectOwner")).sendKeys(owner); 21 | } 22 | 23 | public void setProject(String owner, String project) { 24 | find(by.path("/sources/source/projectPath")).click(); 25 | waitFor(by.option(owner + "/" + project)).click(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/gitlab_plugin/GitLabOrganizationFolder.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.gitlab_plugin; 2 | 3 | import com.google.inject.Injector; 4 | import java.net.URL; 5 | import java.time.Duration; 6 | import org.jenkinsci.test.acceptance.po.Describable; 7 | import org.jenkinsci.test.acceptance.po.Folder; 8 | 9 | @Describable("jenkins.branch.OrganizationFolder") 10 | public class GitLabOrganizationFolder extends Folder { 11 | public GitLabOrganizationFolder(Injector injector, URL url, String name) { 12 | super(injector, url, name); 13 | } 14 | 15 | public void create(String owner) { 16 | control(by.path("/hetero-list-add[navigators]")).click(); 17 | find(by.partialLinkText("GitLab Group")).click(); 18 | find(by.path("/navigators/projectOwner")).sendKeys(owner); 19 | } 20 | 21 | @Override 22 | public URL getConfigUrl() { 23 | return null; 24 | } 25 | 26 | public String getCheckLog() { 27 | return driver.getPageSource(); 28 | } 29 | 30 | public GitLabOrganizationFolder waitForCheckFinished(final int timeout) { 31 | waitFor() 32 | .withTimeout(Duration.ofSeconds(timeout)) 33 | .until(() -> GitLabOrganizationFolder.this.getCheckLog().contains("Finished: ")); 34 | 35 | return this; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/gitlab_plugin/GitLabPersonalAccessTokenCredential.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.gitlab_plugin; 2 | 3 | import static org.jenkinsci.test.acceptance.Matchers.hasContent; 4 | 5 | import org.jenkinsci.test.acceptance.plugins.credentials.BaseStandardCredentials; 6 | import org.jenkinsci.test.acceptance.po.Control; 7 | import org.jenkinsci.test.acceptance.po.Describable; 8 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 9 | import org.jenkinsci.test.acceptance.po.PageObject; 10 | 11 | @Describable("GitLab Personal Access Token") 12 | public class GitLabPersonalAccessTokenCredential extends BaseStandardCredentials { 13 | 14 | private Control token = control(by.path("/credentials/token")); 15 | 16 | public GitLabPersonalAccessTokenCredential(PageObject context, String path) { 17 | super(context, path); 18 | } 19 | 20 | public GitLabPersonalAccessTokenCredential(PageAreaImpl area, String relativePath) { 21 | super(area, relativePath); 22 | } 23 | 24 | public void setToken(String gitLabToken) { 25 | token.set(gitLabToken); 26 | } 27 | 28 | public void create() { 29 | control(by.path("/Submit")).click(); 30 | waitFor(driver, hasContent("Global credentials"), 2); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/gitlab_plugin/GitLabServerConfig.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.gitlab_plugin; 2 | 3 | import static org.jenkinsci.test.acceptance.Matchers.hasContent; 4 | 5 | import jakarta.inject.Inject; 6 | import org.jenkinsci.test.acceptance.po.Control; 7 | import org.jenkinsci.test.acceptance.po.Jenkins; 8 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 9 | 10 | public class GitLabServerConfig extends PageAreaImpl { 11 | 12 | private Control serverName = control("servers/name"); 13 | private Control serverUrl = control("servers/serverUrl"); 14 | 15 | @Inject 16 | public GitLabServerConfig(Jenkins jenkins) { 17 | super(jenkins, "/io-jenkins-plugins-gitlabserverconfig-servers-GitLabServers"); 18 | } 19 | 20 | public void configureServer(String url) { 21 | serverName.set("servername"); 22 | serverUrl.set(url); 23 | 24 | waitFor(by.option("GitLab Personal Access Token")).click(); 25 | 26 | find(by.path("/io-jenkins-plugins-gitlabserverconfig-servers-GitLabServers/servers/validate-button")) 27 | .click(); 28 | 29 | waitFor(driver, hasContent("Credentials verified for user"), 10); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/gradle/GradleTask.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.gradle; 2 | 3 | public enum GradleTask { 4 | HELLO("hello", "Hello world!"), 5 | FIRST("firstTask", "First!"), 6 | SECOND("secondTask", "Second!"), 7 | JOB_PARAM_AS_PROJECT_PROPERTIES("jobParametersAsProjectProperties"), 8 | JOB_PARAM_AS_SYSTEM_PROPERTIES("jobParametersAsSystemProperties"); 9 | 10 | private String name; 11 | private String println; 12 | 13 | GradleTask(final String name) { 14 | this.name = name; 15 | } 16 | 17 | GradleTask(final String name, final String println) { 18 | this.name = name; 19 | this.println = println; 20 | } 21 | 22 | public String getName() { 23 | return name; 24 | } 25 | 26 | public String getPrintln() { 27 | return println; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/javadoc/JavadocPublisher.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.javadoc; 2 | 3 | import org.jenkinsci.test.acceptance.po.AbstractStep; 4 | import org.jenkinsci.test.acceptance.po.Control; 5 | import org.jenkinsci.test.acceptance.po.Describable; 6 | import org.jenkinsci.test.acceptance.po.Job; 7 | import org.jenkinsci.test.acceptance.po.PostBuildStep; 8 | 9 | /** 10 | * @author Kohsuke Kawaguchi 11 | */ 12 | @Describable("Publish Javadoc") 13 | public class JavadocPublisher extends AbstractStep implements PostBuildStep { 14 | public final Control javadocDir = control("javadocDir"); 15 | public final Control keepAll = control("keepAll"); 16 | 17 | public JavadocPublisher(Job parent, String path) { 18 | super(parent, path); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/jira/JiraGlobalConfig.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.jira; 2 | 3 | import jakarta.inject.Inject; 4 | import java.net.URL; 5 | import org.jenkinsci.test.acceptance.po.Jenkins; 6 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 7 | 8 | /** 9 | * @author Kohsuke Kawaguchi 10 | */ 11 | public class JiraGlobalConfig extends PageAreaImpl { 12 | 13 | @Inject 14 | public JiraGlobalConfig(Jenkins jenkins) { 15 | super(jenkins, "/hudson-plugins-jira-JiraGlobalConfiguration"); 16 | } 17 | 18 | // TODO: make this work properly when the site exists already 19 | public void addSite(URL url, String credentialsId) { 20 | control("repeatable-add").click(); 21 | control("sites/url").set(url); 22 | control("sites/credentialsId").select(credentialsId); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/jira/JiraUpdater.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.jira; 2 | 3 | import org.jenkinsci.test.acceptance.po.AbstractStep; 4 | import org.jenkinsci.test.acceptance.po.Describable; 5 | import org.jenkinsci.test.acceptance.po.Job; 6 | import org.jenkinsci.test.acceptance.po.PostBuildStep; 7 | 8 | /** 9 | * @author Kohsuke Kawaguchi 10 | */ 11 | @Describable({"JIRA: Update relevant issues", "Jira: Update relevant issues"}) 12 | public class JiraUpdater extends AbstractStep implements PostBuildStep { 13 | public JiraUpdater(Job parent, String path) { 14 | super(parent, path); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/job_dsl/JobDslLookupStrategy.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.job_dsl; 2 | 3 | /** 4 | * Contexts to use for relative job names. 5 | * 6 | * @author Maximilian Oeckler 7 | */ 8 | public enum JobDslLookupStrategy { 9 | JENKINS_ROOT, 10 | SEED_JOB 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/job_dsl/JobDslRemovedConfigFilesAction.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.job_dsl; 2 | 3 | /** 4 | * Actions what to do when a previously generated config file is not referenced anymore. 5 | * 6 | * @author Maximilian Oeckler 7 | */ 8 | public enum JobDslRemovedConfigFilesAction { 9 | IGNORE, 10 | DELETE 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/job_dsl/JobDslRemovedJobAction.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.job_dsl; 2 | 3 | /** 4 | * Actions what to do when a previously generated job is not referenced anymore. 5 | * 6 | * @author Maximilian Oeckler 7 | */ 8 | public enum JobDslRemovedJobAction { 9 | IGNORE, 10 | DISABLE, 11 | DELETE 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/job_dsl/JobDslRemovedViewAction.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.job_dsl; 2 | 3 | /** 4 | * Actions what to do when a previously generated view is not referenced anymore. 5 | * 6 | * @author Maximilian Oeckler 7 | */ 8 | public enum JobDslRemovedViewAction { 9 | IGNORE, 10 | DELETE 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/ldap/LdapEnvironmentVariable.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.ldap; 2 | 3 | /** 4 | * Represents an environment variable for the LDAP plugin. 5 | */ 6 | public class LdapEnvironmentVariable { 7 | 8 | public static final String READ_TIMEOUT = "com.sun.jndi.ldap.read.timeout"; 9 | public static final String CONNECT_TIMEOUT = "com.sun.jndi.ldap.connect.timeout"; 10 | 11 | private String name; 12 | private String value; 13 | 14 | public LdapEnvironmentVariable(String name, String value) { 15 | this.name = name; 16 | this.value = value; 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | 23 | public void setName(String name) { 24 | this.name = name; 25 | } 26 | 27 | public String getValue() { 28 | return value; 29 | } 30 | 31 | public void setValue(String value) { 32 | this.value = value; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/ldap/LdapGroupMembershipStrategy.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.ldap; 2 | 3 | import org.jenkinsci.test.acceptance.po.GlobalSecurityConfig; 4 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 5 | 6 | /** 7 | * Use @Describable to register an implementation. 8 | * 9 | * @author Michael Prankl 10 | * @since ldap version 1.10 11 | */ 12 | public abstract class LdapGroupMembershipStrategy extends PageAreaImpl { 13 | 14 | protected LdapGroupMembershipStrategy(GlobalSecurityConfig context, String path) { 15 | super(context, path); 16 | } 17 | 18 | public abstract void configure(String strategyParam); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/ldap/ParseUserAttributeLdapGroupMembershipStrategy.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.ldap; 2 | 3 | import org.jenkinsci.test.acceptance.po.Control; 4 | import org.jenkinsci.test.acceptance.po.Describable; 5 | import org.jenkinsci.test.acceptance.po.GlobalSecurityConfig; 6 | 7 | /** 8 | * @author Michael Prankl 9 | */ 10 | @Describable("Parse user attribute for list of groups") 11 | public class ParseUserAttributeLdapGroupMembershipStrategy extends LdapGroupMembershipStrategy { 12 | 13 | private Control groupMembershipAttribute = control("attribute"); 14 | 15 | public ParseUserAttributeLdapGroupMembershipStrategy(GlobalSecurityConfig context, String path) { 16 | super(context, path); 17 | } 18 | 19 | @Override 20 | public void configure(String strategyParam) { 21 | if (strategyParam != null) { 22 | groupMembershipAttribute.set(strategyParam); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/ldap/SearchForGroupsLdapGroupMembershipStrategy.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.ldap; 2 | 3 | import org.jenkinsci.test.acceptance.po.Control; 4 | import org.jenkinsci.test.acceptance.po.Describable; 5 | import org.jenkinsci.test.acceptance.po.GlobalSecurityConfig; 6 | 7 | /** 8 | * @author Michael Prankl 9 | */ 10 | @Describable({"Search for groups containing user", "Search for LDAP groups containing user"}) 11 | public class SearchForGroupsLdapGroupMembershipStrategy extends LdapGroupMembershipStrategy { 12 | 13 | private Control groupMembershipFilter = control("filter"); 14 | 15 | public SearchForGroupsLdapGroupMembershipStrategy(GlobalSecurityConfig context, String path) { 16 | super(context, path); 17 | } 18 | 19 | @Override 20 | public void configure(String strategyParam) { 21 | if (strategyParam != null) { 22 | groupMembershipFilter.set(strategyParam); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/mailer/Mailer.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.mailer; 2 | 3 | import org.jenkinsci.test.acceptance.po.AbstractStep; 4 | import org.jenkinsci.test.acceptance.po.Control; 5 | import org.jenkinsci.test.acceptance.po.Describable; 6 | import org.jenkinsci.test.acceptance.po.Job; 7 | import org.jenkinsci.test.acceptance.po.PostBuildStep; 8 | 9 | /** 10 | * @author Kohsuke Kawaguchi 11 | */ 12 | @Describable("E-mail Notification") 13 | public class Mailer extends AbstractStep implements PostBuildStep { 14 | public final Control recipients = control("recipients", "mailer_recipients"); 15 | 16 | public Mailer(Job parent, String path) { 17 | super(parent, path); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/matrix_auth/MatrixAuthorizationStrategy.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.matrix_auth; 2 | 3 | import org.jenkinsci.test.acceptance.po.AuthorizationStrategy; 4 | import org.jenkinsci.test.acceptance.po.Control; 5 | import org.jenkinsci.test.acceptance.po.Describable; 6 | import org.jenkinsci.test.acceptance.po.GlobalSecurityConfig; 7 | 8 | /** 9 | * @author Kohsuke Kawaguchi 10 | */ 11 | @Describable("Matrix-based security") 12 | public class MatrixAuthorizationStrategy extends AuthorizationStrategy { 13 | private final Control table = control("/data"); 14 | 15 | public MatrixAuthorizationStrategy(GlobalSecurityConfig context, String path) { 16 | super(context, path); 17 | } 18 | 19 | /** 20 | * Adds a new user to this matrix. 21 | */ 22 | public MatrixRow addUser(String name) { 23 | runThenHandleInputDialog( 24 | () -> this.table 25 | .resolve() 26 | .findElement( 27 | by.xpath( 28 | "../div/span/span/button[text()='Add user\u2026'] | ../div/button[text()='Add user\u2026']")) 29 | .click(), 30 | name, 31 | "OK"); 32 | return getUser(name); 33 | } 34 | 35 | /** 36 | * Picks up the existing user in the table. 37 | */ 38 | public MatrixRow getUser(String name) { 39 | return new MatrixRow(this, "data/USER:" + name); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/matrix_auth/ProjectBasedMatrixAuthorizationStrategy.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.matrix_auth; 2 | 3 | import org.jenkinsci.test.acceptance.po.Describable; 4 | import org.jenkinsci.test.acceptance.po.GlobalSecurityConfig; 5 | 6 | /** 7 | * @author Kohsuke Kawaguchi 8 | */ 9 | @Describable("Project-based Matrix Authorization Strategy") 10 | public class ProjectBasedMatrixAuthorizationStrategy extends MatrixAuthorizationStrategy { 11 | public ProjectBasedMatrixAuthorizationStrategy(GlobalSecurityConfig context, String path) { 12 | super(context, path); 13 | } 14 | 15 | /** 16 | * Add and authorize given user admin role under "Project-based Matrix Authorization Strategy" 17 | * 18 | * @param user user to be added and authorized as admin 19 | * @param security page object 20 | * @return security page object 21 | */ 22 | public static GlobalSecurityConfig authorizeUserAsAdmin(String user, GlobalSecurityConfig security) { 23 | ProjectBasedMatrixAuthorizationStrategy auth; 24 | auth = security.useAuthorizationStrategy(ProjectBasedMatrixAuthorizationStrategy.class); 25 | MatrixRow userAuth = auth.addUser(user); 26 | userAuth.admin(); 27 | return security; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/mock_security_realm/MockSecurityRealm.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.mock_security_realm; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import org.jenkinsci.test.acceptance.po.Control; 5 | import org.jenkinsci.test.acceptance.po.Describable; 6 | import org.jenkinsci.test.acceptance.po.GlobalSecurityConfig; 7 | import org.jenkinsci.test.acceptance.po.SecurityRealm; 8 | 9 | /** 10 | * @author Kohsuke Kawaguchi 11 | */ 12 | @Describable("Mock Security Realm") 13 | public class MockSecurityRealm extends SecurityRealm { 14 | private final Control data = control("data"); 15 | 16 | public MockSecurityRealm(GlobalSecurityConfig context, String path) { 17 | super(context, path); 18 | } 19 | 20 | /** 21 | * Sets up the data. 22 | * 23 | * @param accounts 24 | * Each account should be an user name optionally followed by group names. 25 | * The password is always the same as the user name. 26 | */ 27 | public void configure(String... accounts) { 28 | data.set(StringUtils.join(accounts, "\n")); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/msbuild/MSBuildInstallation.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.msbuild; 2 | 3 | import org.jenkinsci.test.acceptance.po.Jenkins; 4 | import org.jenkinsci.test.acceptance.po.ToolInstallation; 5 | import org.jenkinsci.test.acceptance.po.ToolInstallationPageObject; 6 | 7 | @ToolInstallationPageObject(installer = "", name = "MSBuild") 8 | public class MSBuildInstallation extends ToolInstallation { 9 | 10 | public MSBuildInstallation(Jenkins context, String path) { 11 | super(context, path); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/msbuild/MSBuildStep.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.msbuild; 2 | 3 | import org.jenkinsci.test.acceptance.po.AbstractStep; 4 | import org.jenkinsci.test.acceptance.po.BuildStep; 5 | import org.jenkinsci.test.acceptance.po.Control; 6 | import org.jenkinsci.test.acceptance.po.Describable; 7 | import org.jenkinsci.test.acceptance.po.Job; 8 | 9 | @Describable("Build a Visual Studio project or solution using MSBuild") 10 | public class MSBuildStep extends AbstractStep implements BuildStep { 11 | 12 | private final Control msBuildName = control("msBuildName"); 13 | private final Control msBuildFile = control("msBuildFile"); 14 | private final Control cmdLineArgs = control("cmdLineArgs"); 15 | 16 | public MSBuildStep(Job parent, String path) { 17 | super(parent, path); 18 | } 19 | 20 | public MSBuildStep setMSBuildName(String buildName) { 21 | msBuildName.select(buildName); 22 | return this; 23 | } 24 | 25 | public MSBuildStep setMSBuildFile(String buildFile) { 26 | msBuildFile.set(buildFile); 27 | return this; 28 | } 29 | 30 | public MSBuildStep setCmdLineArgs(String cmdArgs) { 31 | cmdLineArgs.set(cmdArgs); 32 | return this; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/nested_view/NestedView.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.nested_view; 2 | 3 | import com.google.inject.Injector; 4 | import java.net.URL; 5 | import org.jenkinsci.test.acceptance.po.Describable; 6 | import org.jenkinsci.test.acceptance.po.View; 7 | import org.jenkinsci.test.acceptance.po.ViewsMixIn; 8 | 9 | /** 10 | * @author Kohsuke Kawaguchi 11 | */ 12 | @Describable("Nested View") 13 | public class NestedView extends View { 14 | public final ViewsMixIn views = new ViewsMixIn(this); 15 | 16 | public NestedView(Injector injector, URL url) { 17 | super(injector, url); 18 | } 19 | 20 | public void setDefaultView(String name) { 21 | configure(); 22 | find(by.input("defaultView")).findElement(by.option(name)).click(); 23 | save(); 24 | } 25 | 26 | public void assertActiveView(String name) { 27 | find(by.xpath("//*[contains(@class, 'active') and (text()='%1$s' or a/text()='%1$s')]", name)); 28 | } 29 | 30 | public void assertInactiveView(String name) { 31 | find(by.xpath("//*[contains(@class, 'inactive') or not(contains(@class, 'active'))]/a[text()='%s']", name)); 32 | } 33 | 34 | public ViewsMixIn getViews() { 35 | return views; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/nodelabelparameter/LabelParameter.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.nodelabelparameter; 2 | 3 | import org.jenkinsci.test.acceptance.po.Control; 4 | import org.jenkinsci.test.acceptance.po.Describable; 5 | import org.jenkinsci.test.acceptance.po.Job; 6 | import org.jenkinsci.test.acceptance.po.Parameter; 7 | 8 | /** 9 | * @author Kohsuke Kawaguchi 10 | */ 11 | @Describable("Label") 12 | public class LabelParameter extends Parameter { 13 | public LabelParameter(Job job, String path) { 14 | super(job, path); 15 | } 16 | 17 | @Override 18 | public void fillWith(Object v) { 19 | Control control = control("value"); 20 | // TODO in some cases the LabelParameter is simple text entry, in others it is a drop down 21 | control.set(v.toString()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/parameterized_trigger/BuildTriggerConfig.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.parameterized_trigger; 2 | 3 | import org.jenkinsci.test.acceptance.po.Control; 4 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 5 | 6 | /** 7 | * Configuration section of a trigger/call build step. 8 | * 9 | * @author Ullrich Hafner 10 | */ 11 | public class BuildTriggerConfig extends PageAreaImpl { 12 | public final Control projects = control("projects"); 13 | public final Control block = control("block"); 14 | 15 | public BuildTriggerConfig(TriggerCallBuildStep parent, String relativePath) { 16 | super(parent, relativePath); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/parameterized_trigger/ParameterizedTrigger.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.parameterized_trigger; 2 | 3 | import org.jenkinsci.test.acceptance.po.AbstractStep; 4 | import org.jenkinsci.test.acceptance.po.Describable; 5 | import org.jenkinsci.test.acceptance.po.Job; 6 | import org.jenkinsci.test.acceptance.po.PostBuildStep; 7 | 8 | /** 9 | * @author Kohsuke Kawaguchi 10 | */ 11 | @Describable("Trigger parameterized build on other projects") 12 | public class ParameterizedTrigger extends AbstractStep implements PostBuildStep { 13 | 14 | public ParameterizedTrigger(Job parent, String path) { 15 | super(parent, path); 16 | } 17 | 18 | public TriggerConfig getTriggerConfig(int index) { 19 | return new TriggerConfig(this, getPath("configs", index)); 20 | } 21 | 22 | /** 23 | * Adds a new trigger setting. 24 | *

25 | * Note that newly added trigger has one entry in there by default. 26 | */ 27 | public TriggerConfig addTriggerConfig() { 28 | String path = createPageArea("configs", () -> clickButton("Add trigger...")); 29 | return new TriggerConfig(this, path); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/parameterized_trigger/TriggerCallBuildStep.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.parameterized_trigger; 2 | 3 | import org.jenkinsci.test.acceptance.po.AbstractStep; 4 | import org.jenkinsci.test.acceptance.po.BuildStep; 5 | import org.jenkinsci.test.acceptance.po.Describable; 6 | import org.jenkinsci.test.acceptance.po.Job; 7 | 8 | /** 9 | * Trigger/call build step of the parameterized trigger plug-in. Starts downstream projects. 10 | * 11 | * @author Ullrich Hafner 12 | */ 13 | @Describable("Trigger/call builds on other projects") 14 | public class TriggerCallBuildStep extends AbstractStep implements BuildStep { 15 | public TriggerCallBuildStep(Job parent, String path) { 16 | super(parent, path); 17 | } 18 | 19 | public BuildTriggerConfig getBuildTriggerConfig(int index) { 20 | return new BuildTriggerConfig(this, getPath("configs", index)); 21 | } 22 | 23 | /** 24 | * Adds a new trigger setting. 25 | *

26 | * Note that newly added trigger has one entry in there by default. 27 | */ 28 | public BuildTriggerConfig addTriggerConfig() { 29 | String path = createPageArea("configs", () -> clickButton("Add trigger...")); 30 | return new BuildTriggerConfig(this, path); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/parameterized_trigger/TriggerConfig.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.parameterized_trigger; 2 | 3 | import org.jenkinsci.test.acceptance.po.Control; 4 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 5 | 6 | /** 7 | * @author Kohsuke Kawaguchi 8 | */ 9 | public class TriggerConfig extends PageAreaImpl { 10 | public final Control projects = control("projects"); 11 | public final Control block = control("block"); 12 | 13 | public TriggerConfig(ParameterizedTrigger parent, String relativePath) { 14 | super(parent, relativePath); 15 | } 16 | 17 | public Ret addParameter(final Class type) { 18 | String path = createPageArea( 19 | "configs", () -> control("hetero-list-add[configs]").selectDropdownMenu(type)); 20 | return newInstance(type, this, path); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/project_description_setter/ProjectDescriptionSetter.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.project_description_setter; 2 | 3 | import org.jenkinsci.test.acceptance.po.BuildWrapper; 4 | import org.jenkinsci.test.acceptance.po.Control; 5 | import org.jenkinsci.test.acceptance.po.Job; 6 | 7 | /** 8 | * @author Kohsuke Kawaguchi 9 | */ 10 | public class ProjectDescriptionSetter extends BuildWrapper { 11 | public final Control filename = control("projectDescriptionFilename"); 12 | 13 | public ProjectDescriptionSetter(Job context) { 14 | super(context, "/org-jenkinsCi-plugins-projectDescriptionSetter-DescriptionSetterWrapper"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/script_security/PendingScript.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.script_security; 2 | 3 | import com.google.inject.Injector; 4 | import org.jenkinsci.test.acceptance.po.CapybaraPortingLayerImpl; 5 | import org.openqa.selenium.WebElement; 6 | 7 | /** 8 | * @author Kohsuke Kawaguchi 9 | */ 10 | public class PendingScript extends CapybaraPortingLayerImpl { 11 | public final WebElement block; 12 | 13 | public PendingScript(Injector injector, WebElement block) { 14 | super(injector); 15 | this.block = block; 16 | } 17 | 18 | public void approve() { 19 | block.findElement(by.button("Approve")).click(); 20 | } 21 | 22 | public void deny() { 23 | block.findElement(by.button("Deny")).click(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/ssh_slaves/SshSlaveConnector.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.ssh_slaves; 2 | 3 | import org.jenkinsci.test.acceptance.plugins.ssh_credentials.SshCredentialDialog; 4 | import org.jenkinsci.test.acceptance.po.ComputerConnector; 5 | import org.jenkinsci.test.acceptance.po.Control; 6 | import org.jenkinsci.test.acceptance.po.Describable; 7 | import org.jenkinsci.test.acceptance.po.PageObject; 8 | 9 | /** 10 | * @author Kohsuke Kawaguchi 11 | */ 12 | @Describable("Launch slave agents on Unix machines via SSH") 13 | public class SshSlaveConnector extends ComputerConnector { 14 | public final Control credentialsId = control("credentialsId"); 15 | 16 | public SshSlaveConnector(PageObject context, String path) { 17 | super(context, path); 18 | } 19 | 20 | public SshCredentialDialog addCredential() { 21 | self().findElement(by.button("Add")).click(); 22 | 23 | return new SshCredentialDialog(getPage(), "/credentials"); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/stageview/StageViewHeadline.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.stageview; 2 | 3 | import org.openqa.selenium.WebElement; 4 | 5 | /** 6 | * Representation of the headlines in the Stageview. The actual names of the stages. 7 | * @author Boris Dippolter 8 | */ 9 | public class StageViewHeadline { 10 | 11 | /** 12 | * Webelement locator for this current headline 13 | */ 14 | private WebElement webElement; 15 | 16 | /** 17 | * The actual headline in the box. Sanitized. 18 | */ 19 | private String name; 20 | 21 | /** 22 | * Constructor fot Headline 23 | * 24 | * @param webElement the parent element 25 | */ 26 | public StageViewHeadline(WebElement webElement) { 27 | this.webElement = webElement; 28 | this.name = webElement.getText().replace("\n", ""); 29 | } 30 | 31 | /** 32 | * Name of the headline 33 | * @return name 34 | */ 35 | public String getName() { 36 | return name; 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return "-- Headline: " + this.name; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/stageview/StageViewStage.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.stageview; 2 | 3 | import org.openqa.selenium.WebElement; 4 | 5 | /** 6 | * Single element of a job. The actual stage within a job. 7 | * @author Boris Dippolter 8 | */ 9 | public class StageViewStage { 10 | 11 | /** 12 | * Web element locator for this current headline 13 | */ 14 | private WebElement webElement; 15 | 16 | /** 17 | * full name of the current stage 18 | */ 19 | private String name; 20 | 21 | public StageViewStage(WebElement webElement) { 22 | this.webElement = webElement; 23 | this.name = webElement.getText().replace("\n", ""); 24 | } 25 | 26 | /** 27 | * Name of the stage 28 | * @return name as String 29 | */ 30 | public String getName() { 31 | return name; 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | return "-- Stage: " + this.name; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/subversion/SubversionSvmAdvanced.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.subversion; 2 | 3 | import java.net.URL; 4 | import org.jenkinsci.test.acceptance.po.Control; 5 | import org.jenkinsci.test.acceptance.po.PageObject; 6 | 7 | /** 8 | * PageObject for the Subversion "advanced" section. 9 | * 10 | * @author Matthias Karl 11 | */ 12 | public class SubversionSvmAdvanced extends PageObject { 13 | public final Control excludedRegions = control(by.input("_.excludedRegions")); 14 | 15 | public SubversionSvmAdvanced(PageObject context, URL url) { 16 | super(context, url); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/subversion/SvnRepositoryBrowser.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.subversion; 2 | 3 | import java.net.URL; 4 | import org.jenkinsci.test.acceptance.po.PageObject; 5 | import org.jenkinsci.test.acceptance.po.Scm; 6 | 7 | /** 8 | * Superclass for the different repository browser accessable in the svn plugin 9 | * 10 | * @author Matthias Karl 11 | */ 12 | public class SvnRepositoryBrowser extends PageObject { 13 | 14 | public SvnRepositoryBrowser(Scm area, URL path) { 15 | super(area.getPage(), path); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/subversion/SvnRepositoryBrowserWebSvn.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.subversion; 2 | 3 | import java.net.URL; 4 | import org.jenkinsci.test.acceptance.po.Control; 5 | import org.jenkinsci.test.acceptance.po.Describable; 6 | import org.jenkinsci.test.acceptance.po.Scm; 7 | 8 | /** 9 | * PageArea for the WebSvn repository browser 10 | * 11 | * @author Matthias Karl 12 | */ 13 | @Describable("WebSVN") 14 | public class SvnRepositoryBrowserWebSvn extends SvnRepositoryBrowser { 15 | 16 | public Control url = control("/scm[1]/browser/url"); 17 | 18 | public SvnRepositoryBrowserWebSvn(Scm area, URL path) { 19 | super(area, path); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/textfinder/TextFinderPublisher.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.textfinder; 2 | 3 | import org.jenkinsci.test.acceptance.po.AbstractStep; 4 | import org.jenkinsci.test.acceptance.po.Describable; 5 | import org.jenkinsci.test.acceptance.po.Job; 6 | import org.jenkinsci.test.acceptance.po.PostBuildStep; 7 | import org.openqa.selenium.WebElement; 8 | 9 | /** 10 | * This class provides the ability to add a Jenkins Text Finder post build step 11 | * to the job. 12 | *

13 | * It provides access to the particular web elements to configure the post build step. 14 | *

15 | * This post build step requires installation of the text-finder plugin. 16 | * 17 | * @author Martin Ende 18 | */ 19 | @Describable("Jenkins Text Finder") 20 | public class TextFinderPublisher extends AbstractStep implements PostBuildStep { 21 | 22 | public final WebElement filePath = find(by.xpath("//input[@name='_.fileSet']")); 23 | public final WebElement regEx = find(by.xpath("//input[@name='_.regexp']")); 24 | public final WebElement succeedIfFound = find(by.xpath("//input[@name='_.succeedIfFound']")); 25 | public final WebElement unstableIfFound = find(by.xpath("//input[@name='_.unstableIfFound']")); 26 | 27 | public TextFinderPublisher(Job parent, String path) { 28 | super(parent, path); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/timestamper/TimstamperGlobalConfig.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.timestamper; 2 | 3 | import org.jenkinsci.test.acceptance.po.Control; 4 | import org.jenkinsci.test.acceptance.po.Jenkins; 5 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 6 | 7 | /** 8 | * @author Kohsuke Kawaguchi 9 | */ 10 | public class TimstamperGlobalConfig extends PageAreaImpl { 11 | public final Control systemTimeFormat = control("systemTimeFormat"); 12 | public final Control elapsedTimeFormat = control("elapsedTimeFormat"); 13 | 14 | public TimstamperGlobalConfig(Jenkins jenkins) { 15 | super(jenkins, "/hudson-plugins-timestamper-TimestamperConfig"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/workflow_multibranch/BranchSource.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.workflow_multibranch; 2 | 3 | import org.jenkinsci.test.acceptance.plugins.workflow_shared_library.WorkflowSharedLibrary; 4 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 5 | import org.jenkinsci.test.acceptance.po.WorkflowMultiBranchJob; 6 | 7 | /** 8 | * Base type for {@link PageAreaImpl} for Branch Source. 9 | */ 10 | public class BranchSource extends PageAreaImpl { 11 | 12 | public BranchSource(WorkflowMultiBranchJob job, String path) { 13 | super(job, path); 14 | } 15 | 16 | public BranchSource(WorkflowSharedLibrary sharedLibrary, String path) { 17 | super(sharedLibrary, path); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/workflow_multibranch/GitBranchSource.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.workflow_multibranch; 2 | 3 | import org.jenkinsci.test.acceptance.po.Control; 4 | import org.jenkinsci.test.acceptance.po.Describable; 5 | import org.jenkinsci.test.acceptance.po.WorkflowMultiBranchJob; 6 | import org.openqa.selenium.By; 7 | import org.openqa.selenium.support.ui.Select; 8 | 9 | /** 10 | * Git Branch Source for the pipeline multi-branch plugin. 11 | * 12 | * @author Ullrich Hafner 13 | */ 14 | @Describable("Git") 15 | // TODO: Remove duplicates with GitScm 16 | public class GitBranchSource extends BranchSource { 17 | private final Control remote = control("remote"); 18 | 19 | public GitBranchSource(WorkflowMultiBranchJob job, String path) { 20 | super(job, path); 21 | } 22 | 23 | public GitBranchSource setRemote(final String remoteUrl) { 24 | this.remote.set(remoteUrl); 25 | 26 | return this; 27 | } 28 | 29 | public GitBranchSource setCredentials(final String name) { 30 | Select select = new Select(control(By.className("credentials-select")).resolve()); 31 | select.selectByVisibleText(name); 32 | 33 | return this; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/workflow_shared_library/WorkflowGithubSharedLibrary.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.workflow_shared_library; 2 | 3 | import org.jenkinsci.test.acceptance.plugins.workflow_multibranch.GithubBranchSource; 4 | import org.jenkinsci.test.acceptance.po.Control; 5 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 6 | 7 | /** 8 | * Base type for {@link PageAreaImpl} for Pipeline Shared Library using Github as SCM. 9 | */ 10 | public class WorkflowGithubSharedLibrary extends WorkflowSharedLibrary { 11 | 12 | public final Control modernScm = control("/"); 13 | public final Control githubSourceCodeManagement = control("/retriever"); 14 | 15 | public WorkflowGithubSharedLibrary(WorkflowSharedLibraryGlobalConfig config, String path) { 16 | super(config, path); 17 | } 18 | 19 | @Override 20 | public GithubBranchSource selectSCM() { 21 | modernScm.select("0"); 22 | githubSourceCodeManagement.select("1"); 23 | 24 | return new GithubBranchSource(this, this.getPath() + "/retriever/scm"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/workflow_shared_library/WorkflowSharedLibrary.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.workflow_shared_library; 2 | 3 | import org.jenkinsci.test.acceptance.plugins.workflow_multibranch.BranchSource; 4 | import org.jenkinsci.test.acceptance.po.Control; 5 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 6 | 7 | /** 8 | * Base type for {@link PageAreaImpl} for Pipeline Shared Library. 9 | */ 10 | public abstract class WorkflowSharedLibrary extends PageAreaImpl { 11 | 12 | public final Control name = control("name"); 13 | 14 | public WorkflowSharedLibrary(WorkflowSharedLibraryGlobalConfig config, String path) { 15 | super(config, path); 16 | } 17 | 18 | public abstract T selectSCM(); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/workflow_shared_library/WorkflowSharedLibraryGlobalConfig.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.workflow_shared_library; 2 | 3 | import org.jenkinsci.test.acceptance.po.Jenkins; 4 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 5 | 6 | /** 7 | * Global config page for Pipeline Shared Libraries plugin. 8 | */ 9 | public class WorkflowSharedLibraryGlobalConfig extends PageAreaImpl { 10 | 11 | private static final String GLOBAL_LIBRARIES_PATH = "/org-jenkinsci-plugins-workflow-libs-GlobalLibraries"; 12 | 13 | public WorkflowSharedLibraryGlobalConfig(final Jenkins jenkins) { 14 | super(jenkins, GLOBAL_LIBRARIES_PATH); 15 | } 16 | 17 | public T addSharedLibrary(final Class type) { 18 | final String path = 19 | createPageArea("libraries", () -> control(by.path(GLOBAL_LIBRARIES_PATH + "/repeatable-add")) 20 | .click()); 21 | 22 | return newInstance(type, this, path); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/plugins/xunit/XUnitPublisher.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.plugins.xunit; 2 | 3 | import org.jenkinsci.test.acceptance.po.AbstractStep; 4 | import org.jenkinsci.test.acceptance.po.Control; 5 | import org.jenkinsci.test.acceptance.po.Describable; 6 | import org.jenkinsci.test.acceptance.po.Job; 7 | import org.jenkinsci.test.acceptance.po.PageAreaImpl; 8 | import org.jenkinsci.test.acceptance.po.PageObject; 9 | import org.jenkinsci.test.acceptance.po.PostBuildStep; 10 | 11 | /** 12 | * @author Kohsuke Kawaguchi 13 | */ 14 | @Describable("Publish xUnit test result report") 15 | public class XUnitPublisher extends AbstractStep implements PostBuildStep { 16 | public final Control addButton = control("hetero-list-add[tools]"); 17 | 18 | public XUnitPublisher(Job parent, String path) { 19 | super(parent, path); 20 | } 21 | 22 | public Tool addTool(final String kind) { 23 | String path = createPageArea("tools", () -> addButton.selectDropdownMenu(kind)); 24 | return newInstance(Tool.class, getPage(), path); 25 | } 26 | 27 | public static class Tool extends PageAreaImpl { 28 | public final Control pattern = control("pattern"); 29 | 30 | public Tool(PageObject parent, String path) { 31 | super(parent, path); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/AbstractListViewColumn.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * Abstract base class for configuring dash board columns. 5 | * 6 | * @author Fabian Trampusch 7 | */ 8 | public class AbstractListViewColumn extends PageAreaImpl implements ListViewColumn { 9 | 10 | protected AbstractListViewColumn(ListView parent, String path) { 11 | super(parent, path); 12 | } 13 | 14 | /** 15 | * Deletes the column, i.e. removes it from the view. 16 | */ 17 | public void delete() { 18 | control("repeatable-delete").click(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/AbstractStep.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * Common part of {@link BuildStep} and {@link PostBuildStep} 5 | * 6 | * @author Kohsuke Kawaguchi 7 | */ 8 | public abstract class AbstractStep extends PageAreaImpl implements Step { 9 | public final Job parent; 10 | 11 | public AbstractStep(Job parent, String path) { 12 | super(parent, path); 13 | this.parent = parent; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/AggregateDownstreamTestResults.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | @Describable("Aggregate downstream test results") 4 | public class AggregateDownstreamTestResults extends AbstractStep implements PostBuildStep { 5 | 6 | public final Control specify = control("specify"); 7 | public final Control jobs = control("specify/jobs"); 8 | public final Control includeFailedBuilds = control("specify/includeFailedBuilds"); 9 | 10 | public AggregateDownstreamTestResults(Job parent, String path) { 11 | super(parent, path); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/ArtifactArchiver.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * @author Kohsuke Kawaguchi 5 | */ 6 | @Describable("Archive the artifacts") 7 | public class ArtifactArchiver extends AbstractStep implements PostBuildStep { 8 | public ArtifactArchiver(Job parent, String path) { 9 | super(parent, path); 10 | } 11 | 12 | public ArtifactArchiver includes(String value) { 13 | control("artifacts").set(value); 14 | return this; 15 | } 16 | 17 | public ArtifactArchiver excludes(String value) { 18 | control("advanced-button").click(); 19 | control("excludes").set(value); 20 | return this; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/AuthorizationStrategy.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * Base type for {@link PageArea} for Authorization Strategy. 5 | *

6 | * Use {@link Describable} annotation to register an implementation. 7 | * 8 | * @see GlobalSecurityConfig#useAuthorizationStrategy(Class) 9 | */ 10 | public abstract class AuthorizationStrategy extends PageAreaImpl { 11 | protected AuthorizationStrategy(GlobalSecurityConfig context, String path) { 12 | super(context, path); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/Axis.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * Page area for matrix axis. 5 | *

6 | * Use {@link Describable} annotation to register an implementation. 7 | * 8 | * @author Kohsuke Kawaguchi 9 | * @see MatrixProject#addAxis(Class) 10 | */ 11 | public abstract class Axis extends PageAreaImpl { 12 | public final Control name = control("name"); 13 | 14 | protected Axis(PageObject context, String path) { 15 | super(context, path); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/BatchCommandBuildStep.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | import org.openqa.selenium.NoSuchElementException; 4 | 5 | /** 6 | * BuildStep page object for a Windows Batch Command. 7 | */ 8 | @Describable("Execute Windows batch command") 9 | public class BatchCommandBuildStep extends AbstractStep implements BuildStep { 10 | 11 | public BatchCommandBuildStep(Job parent, String path) { 12 | super(parent, path); 13 | } 14 | 15 | public void command(String command) { 16 | try { 17 | control("command").set(command); 18 | } catch (NoSuchElementException e) { 19 | new CodeMirror(this, "command").set(command); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/BuildStep.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * Job build step. 5 | *

6 | * Use {@link Describable} annotation to register an implementation. 7 | * 8 | * @author christian.fritz 9 | */ 10 | public interface BuildStep extends Step {} 11 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/BuildTrigger.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * Trigger other projects at the end of a build 5 | * 6 | * @author Kohsuke Kawaguchi 7 | */ 8 | @Describable("Build other projects") 9 | public class BuildTrigger extends AbstractStep implements PostBuildStep { 10 | public final Control childProjects = control("childProjects"); 11 | 12 | public final Control thresholdSuccess = control("threshold[SUCCESS]"); 13 | public final Control thresholdFailure = control("threshold[FAILURE]"); 14 | 15 | public BuildTrigger(Job parent, String path) { 16 | super(parent, path); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/BuildWrapper.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * @author Kohsuke Kawaguchi 5 | */ 6 | public abstract class BuildWrapper extends PageAreaImpl { 7 | /** 8 | * @param path p Each BuildWrapper occupies a unique path that is supplied by the subtype. 9 | */ 10 | protected BuildWrapper(Job context, String path) { 11 | super(context, path); 12 | } 13 | 14 | /** 15 | * Checkbox that activates this build wrapper. 16 | */ 17 | public final Control enable = control(""); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/Changes.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | import java.net.URL; 4 | import org.openqa.selenium.NoSuchElementException; 5 | 6 | /** 7 | * @author Matthias Karl 8 | */ 9 | public class Changes extends PageObject { 10 | 11 | protected Changes(PageObject context, URL url) { 12 | super(context, url); 13 | } 14 | 15 | /** 16 | * Are there any changes in the current build. 17 | * 18 | * @return true if the build has changes. 19 | */ 20 | public boolean hasChanges() { 21 | try { 22 | // TODO: improve test to be more failproove 23 | find(by.xpath("//h2[text()='%s']/following-sibling::ol/li", "Summary")); 24 | return true; 25 | } catch (NoSuchElementException e) { 26 | return false; 27 | } 28 | } 29 | 30 | /** 31 | * Is there a (diff) link for a specific file. 32 | * Links are present if there are changes in a file and a repository browser is specified. 33 | * 34 | * @param file name of the file with changes. 35 | * @return true if (diff) link for file is present. 36 | */ 37 | public boolean hasDiffFileLink(String file) { 38 | try { 39 | // TODO: improve test to be more failproove 40 | find(by.xpath("//a[text()='/%s']/following-sibling::a[text()='(diff)']", file)); 41 | return true; 42 | } catch (NoSuchElementException e) { 43 | return false; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/Cloud.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * Configuration fragment for cloud. 5 | * 6 | * @author Kohsuke Kawaguchi 7 | */ 8 | public abstract class Cloud extends PageAreaImpl { 9 | protected Cloud(PageObject context, String path) { 10 | super(context, path); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/ComputerConnector.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * Configuration fragment for computer launcher. 5 | *

6 | * Use {@link Describable} annotation to register an implementation. 7 | * 8 | * @author Kohsuke Kawaguchi 9 | */ 10 | public abstract class ComputerConnector extends PageAreaImpl { 11 | protected ComputerConnector(PageObject context, String path) { 12 | super(context, path); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/ComputerLauncher.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * Configuration fragment for computer launcher. 5 | *

6 | * Use {@link Describable} annotation to register an implementation. 7 | * 8 | * @author Kohsuke Kawaguchi 9 | * @see DumbSlave#setLauncher(Class) 10 | */ 11 | public abstract class ComputerLauncher extends PageAreaImpl { 12 | protected ComputerLauncher(PageObject context, String path) { 13 | super(context, path); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/Container.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * A container owns jobs and views. Known container implementations are {@link Jenkins} and {@link Folder}. 5 | * 6 | * @author Ullrich Hafner 7 | */ 8 | public interface Container { 9 | /** 10 | * Returns the jobs in this container. 11 | * 12 | * @return the jobs 13 | */ 14 | JobsMixIn getJobs(); 15 | 16 | /** 17 | * Returns the views in this container. 18 | * 19 | * @return the views 20 | */ 21 | ViewsMixIn getViews(); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/CopyArchivedArtifactsBuildStep.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | @Describable("Copy archived artifacts from remote/local job") 4 | public class CopyArchivedArtifactsBuildStep extends AbstractStep implements BuildStep { 5 | 6 | public final Control sourceJob = control(""); 7 | public final Control timeout = control("timeout"); 8 | public final Control includes = control("includes"); 9 | 10 | public CopyArchivedArtifactsBuildStep(Job parent, String path) { 11 | super(parent, path); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/Describable.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | import org.jvnet.hudson.annotation_indexer.Indexed; 8 | 9 | /** 10 | * Annotation used to register implementations to be discovered automatically. 11 | *

12 | * Note that different services creating an instances have different conventions concerning both the values of this 13 | * annotation as well as the class interface. In some cases, descriptions are visual labels used in UI, but it can as 14 | * well be an internal identifier such as Jenkins class name. Compare {@link Describable} annotations for {@link 15 | * MatrixProject} and {@link ShellBuildStep}. Unique constructor signature is often required for implementations of the 16 | * same abstraction. 17 | *

18 | * The details should be documented in particular superclass, such as {@link Job} or {@link BuildStep}. 19 | * 20 | * @author Kohsuke Kawaguchi 21 | * @see CapybaraPortingLayerImpl#findCaption(Class, CapybaraPortingLayerImpl.Finder) 22 | */ 23 | @Retention(RetentionPolicy.RUNTIME) 24 | @Target(ElementType.TYPE) 25 | @Indexed 26 | public @interface Describable { 27 | /** 28 | * Descriptions. 29 | *

30 | * The annotation accepts several values as possible alternatives. First that exists will be used. 31 | */ 32 | String[] value(); 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/Fingerprint.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | @Describable("Record fingerprints of files to track usage") 4 | public class Fingerprint extends AbstractStep implements PostBuildStep { 5 | public final Control targets = control("targets"); 6 | 7 | public Fingerprint(Job parent, String path) { 8 | super(parent, path); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/FreeStyleJob.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | import com.google.inject.Injector; 4 | import java.net.URL; 5 | 6 | /** 7 | * @author Kohsuke Kawaguchi 8 | */ 9 | @Describable("hudson.model.FreeStyleProject") 10 | public class FreeStyleJob extends Job { 11 | public FreeStyleJob(Injector injector, URL url, String name) { 12 | super(injector, url, name); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/FreeStyleMultiBranchJob.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | import com.google.inject.Injector; 4 | import java.net.URL; 5 | import org.openqa.selenium.WebElement; 6 | 7 | /** 8 | * A freestyle multi-branch job (requires installation of multi-branch-project-plugin). 9 | * 10 | * @author Ullrich Hafner 11 | */ 12 | @Describable("com.github.mjdetullio.jenkins.plugins.multibranch.FreeStyleMultiBranchProject") 13 | public class FreeStyleMultiBranchJob extends Job { 14 | public FreeStyleMultiBranchJob(Injector injector, URL url, String name) { 15 | super(injector, url, name); 16 | } 17 | 18 | @Override 19 | public T addBuildStep(Class type) { 20 | return addStep(type, "builder"); 21 | } 22 | 23 | @Override 24 | public T addPublisher(Class type) { 25 | T p = addStep(type, "publisher"); 26 | 27 | publishers.add(p); 28 | return p; 29 | } 30 | 31 | private T addStep(Class type, String section) { 32 | ensureConfigPage(); 33 | 34 | control(by.path("/projectFactory/hetero-list-add[%s]", section)).selectDropdownMenu(type); 35 | waitFor(by.xpath("//div[@name='%s']", section), 3); // it takes some time until the element is visible 36 | WebElement last = last(by.xpath("//div[@name='%s']", section)); 37 | String path = last.getAttribute("path"); 38 | 39 | return newInstance(type, this, path); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/GlobalPluginConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | import org.openqa.selenium.WebElement; 5 | 6 | /** 7 | * PageArea generated from a server-side {@code GlobalPluginConfiguration} implementation. 8 | * 9 | *

10 | * These page areas do not get fixed path name, so we need to figure that out from the hidden "name" field. 11 | *

12 | * TODO: improve core to make this more robust 13 | * 14 | * @author Kohsuke Kawaguchi 15 | */ 16 | public class GlobalPluginConfiguration extends PageAreaImpl { 17 | public GlobalPluginConfiguration(JenkinsConfig context, String pluginShortName) { 18 | super(context, toPathName(context.driver, pluginShortName)); 19 | } 20 | 21 | private static String toPathName(WebDriver d, String pluginShortName) { 22 | for (int i = 0; ; i++) { 23 | String path = "/jenkins-model-GlobalPluginConfiguration/plugin"; 24 | if (i > 0) { 25 | path += String.format("[%d]", i); 26 | } 27 | 28 | WebElement e = d.findElement(by.path("%s/name", path)); 29 | if (e.getAttribute("value").equals(pluginShortName)) { 30 | return path; 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/JUnitPublisher.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * @author Kohsuke Kawaguchi 5 | */ 6 | @Describable("Publish JUnit test result report") 7 | public class JUnitPublisher extends AbstractStep implements PostBuildStep { 8 | public final Control testResults = control("testResults"); 9 | 10 | public JUnitPublisher(Job parent, String path) { 11 | super(parent, path); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/LabelAxis.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | import java.time.Duration; 4 | import org.openqa.selenium.WebElement; 5 | 6 | /** 7 | * @author Kohsuke Kawaguchi 8 | */ 9 | @Describable({"Agents", "Slaves"}) // Agents for Matrix Project Plugin >= 1.15 10 | public class LabelAxis extends Axis { 11 | public LabelAxis(PageObject context, String path) { 12 | super(context, path); 13 | } 14 | 15 | public void select(String name) { 16 | WebElement checkBox = 17 | find(by.path(getPath())).findElement(by.xpath(".//input[@name='values' and @json='%s']", name)); 18 | if (!checkBox.isDisplayed()) { 19 | // unfold the labels and slaves sub-nodes 20 | find(by.xpath("(//button[@class='jenkins-button mp-label-axis__button'])[1]")) 21 | .click(); 22 | find(by.xpath("(//button[@class='jenkins-button mp-label-axis__button'])[2]")) 23 | .click(); 24 | 25 | waitFor().withTimeout(Duration.ofSeconds(3)).until(checkBox::isDisplayed); 26 | } 27 | check(checkBox, true); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/LabelExpressionAxis.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * @author Scott Hebert 5 | */ 6 | @Describable("Label expression") 7 | public class LabelExpressionAxis extends Axis { 8 | public LabelExpressionAxis(PageObject context, String path) { 9 | super(context, path); 10 | } 11 | 12 | public final Control values = control("values"); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/ListViewColumn.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * Marker Interface for {@link ListView} that corresponds to selectable columns. 5 | *

6 | * Subtypes should have {@link Describable} annotation on it. 7 | * 8 | * @author Fabian Trampusch 9 | */ 10 | public interface ListViewColumn {} 11 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/LoggedInAuthorizationStrategy.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * A logged in user can do everything. Anonymous may have read access. 5 | * 6 | * @author Ullrich Hafner 7 | */ 8 | @Describable("Logged-in users can do anything") 9 | public class LoggedInAuthorizationStrategy extends AuthorizationStrategy { 10 | private final Control name = control("/"); 11 | private final Control allowAnonymousRead = control("allowAnonymousRead"); 12 | 13 | public LoggedInAuthorizationStrategy(GlobalSecurityConfig context, String path) { 14 | super(context, path); 15 | } 16 | 17 | /** 18 | * Enables READ access for anonymous. 19 | */ 20 | public void enableAnonymousReadAccess() { 21 | setAnonymousAccess(true); 22 | } 23 | 24 | /** 25 | * Disables READ access for anonymous. 26 | */ 27 | public void disableAnonymousReadAccess() { 28 | setAnonymousAccess(false); 29 | } 30 | 31 | private void setAnonymousAccess(final boolean state) { 32 | allowAnonymousRead.check(state); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/Logout.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * Page object for logging out of Jenkins. 5 | * @author Marco.Miller@ericsson.com 6 | */ 7 | public class Logout extends PageObject { 8 | public Logout(Jenkins jenkins) { 9 | super(jenkins.injector, jenkins.url("logout")); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/MatrixBuild.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | import java.net.URL; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | /** 8 | * @author Kohsuke Kawaguchi 9 | */ 10 | public class MatrixBuild extends Build { 11 | public MatrixBuild(Job job, URL url) { 12 | super(job.as(MatrixProject.class), url); 13 | } 14 | 15 | public MatrixProject getJob() { 16 | return (MatrixProject) job; 17 | } 18 | 19 | public List getConfigurations() { 20 | List builds = new ArrayList<>(); 21 | for (MatrixConfiguration c : getJob().getConfigurations()) { 22 | builds.add(new MatrixRun(c, this)); 23 | } 24 | return builds; 25 | } 26 | 27 | public MatrixRun getConfiguration(String name) { 28 | return new MatrixRun(getJob().getConfiguration(name), this); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/MatrixConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | import com.google.inject.Injector; 4 | import java.net.URL; 5 | 6 | /** 7 | * Specific combination of axis values. 8 | * 9 | * @author Kohsuke Kawaguchi 10 | */ 11 | public class MatrixConfiguration extends Job { 12 | public MatrixConfiguration(Injector injector, URL url, String name) { 13 | super(injector, url, name); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/MatrixRun.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * @author Kohsuke Kawaguchi 5 | */ 6 | public class MatrixRun extends Build { 7 | 8 | private final MatrixBuild build; 9 | 10 | public MatrixRun(MatrixConfiguration config, MatrixBuild build) { 11 | super(config, build.url("%s/", config.name)); 12 | this.build = build; 13 | } 14 | 15 | public boolean exists() { 16 | return getJson().get("number").asInt() == build.getJson().get("number").asInt(); 17 | } 18 | 19 | public MatrixConfiguration getConfiguration() { 20 | return (MatrixConfiguration) job; 21 | } 22 | 23 | public MatrixBuild getBuild() { 24 | return build; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/MixIn.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * Different Jenkins model objects often share a common trait, 5 | * and for better reuse it makes sense to split them off into a separate page object. 6 | * 7 | *

8 | * This class is mostly a marker super-type for such mix-in types. 9 | * 10 | * @author Kohsuke Kawaguchi 11 | */ 12 | public abstract class MixIn extends ContainerPageObject { 13 | protected MixIn(ContainerPageObject context) { 14 | super(context, context.url); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/OicAuthConfigurationMode.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * Class representing the entry controls for the configuration mode when using the oic-auth plugin 5 | */ 6 | public abstract class OicAuthConfigurationMode extends PageAreaImpl { 7 | 8 | protected OicAuthConfigurationMode(OicAuthSecurityRealm realm) { 9 | super(realm, "serverConfiguration"); 10 | } 11 | 12 | /** 13 | * Class representing the entry controls for well-known endpoint when using the oic-auth plugin 14 | */ 15 | @Describable("Discovery via well-known endpoint") 16 | public static class WellKnownEndpoint extends OicAuthConfigurationMode { 17 | 18 | public final Control wellKnownEndpoint = control("wellKnownOpenIDConfigurationUrl"); 19 | 20 | public WellKnownEndpoint(OicAuthSecurityRealm realm) { 21 | super(realm); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/PasswordParameter.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | @Describable("Password Parameter") 4 | public class PasswordParameter extends Parameter { 5 | 6 | public PasswordParameter(Job job, String path) { 7 | super(job, path); 8 | } 9 | 10 | @Override 11 | public void fillWith(Object v) { 12 | control("value").set(v.toString()); 13 | } 14 | 15 | @Override 16 | public Parameter setDefault(String value) { 17 | control("defaultValueAsSecret").set(value); 18 | return this; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/PostBuildStep.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * Marker Interface for {@link PageArea} that corresponds to 'Publisher' in the core. 5 | *

6 | * Subtypes should have {@link Describable} annotation on it. 7 | * 8 | * @author christian.fritz 9 | */ 10 | public interface PostBuildStep extends Step {} 11 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/ShellBuildStep.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | import org.openqa.selenium.NoSuchElementException; 4 | 5 | /** 6 | * @author Kohsuke Kawaguchi 7 | */ 8 | @Describable("Execute shell") 9 | public class ShellBuildStep extends AbstractStep implements BuildStep { 10 | public ShellBuildStep(Job parent, String path) { 11 | super(parent, path); 12 | } 13 | 14 | public void command(String command) { 15 | try { 16 | new CodeMirror(this, "command").set(command); 17 | } catch (NoSuchElementException e) { 18 | control("command").set(command); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/SnippetGenerator.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import org.openqa.selenium.By; 5 | import org.openqa.selenium.WebElement; 6 | 7 | /** 8 | * {@link PageObject} for the snippet generator to create bits of code for individual steps. 9 | */ 10 | public class SnippetGenerator extends PageObject { 11 | private static final String URI = "pipeline-syntax/"; 12 | 13 | /** 14 | * Creates a new page object for the snippet generator. 15 | * 16 | * @param context 17 | * job context 18 | */ 19 | public SnippetGenerator(final WorkflowJob context) { 20 | super(context, context.url(URI)); 21 | } 22 | 23 | @Override 24 | protected WorkflowJob getContext() { 25 | return (WorkflowJob) super.getContext(); 26 | } 27 | 28 | /** 29 | * Generates the sample pipeline script. 30 | * 31 | * @return the generated script 32 | */ 33 | public String generateScript() { 34 | WebElement generateButton = find(By.id("generatePipelineScript")); 35 | generateButton.click(); 36 | 37 | WebElement snippet = find(By.id("prototypeText")); 38 | waitFor().until(() -> StringUtils.isNotBlank(snippet.getAttribute("value"))); 39 | 40 | return StringUtils.defaultString(snippet.getAttribute("value")); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/Step.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * @author christian.fritz 5 | */ 6 | public interface Step extends PageArea {} 7 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/StringParameter.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * @author Kohsuke Kawaguchi 5 | */ 6 | @Describable("String Parameter") 7 | public class StringParameter extends Parameter { 8 | public StringParameter(Job job, String path) { 9 | super(job, path); 10 | } 11 | 12 | @Override 13 | public void fillWith(Object v) { 14 | control("value").set(v.toString()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/TextAxis.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * @author Kohsuke Kawaguchi 5 | */ 6 | @Describable("User-defined Axis") 7 | public class TextAxis extends Axis { 8 | public TextAxis(PageObject context, String path) { 9 | super(context, path); 10 | } 11 | 12 | public final Control valueString = control("valueString"); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/TimerTrigger.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * @author Kohsuke Kawaguchi 5 | */ 6 | public class TimerTrigger extends Trigger { 7 | public final Control spec = control("spec"); 8 | 9 | public TimerTrigger(Job parent) { 10 | super(parent, "/hudson-triggers-TimerTrigger"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/Trigger.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * Base type for {@link PageAreaImpl} for trigger. 5 | * 6 | * @see Job#addTrigger(Class) 7 | */ 8 | public abstract class Trigger extends PageAreaImpl { 9 | public final Control enabled = control(""); 10 | 11 | protected Trigger(Job parent, String path) { 12 | super(parent, path); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/UpstreamJobTrigger.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | 5 | /** 6 | * Triggers a job, if another job has been finished. 7 | * 8 | * @author Ulli Hafner 9 | */ 10 | public class UpstreamJobTrigger extends Trigger { 11 | private final Control upstreamProjects = control("upstreamProjects"); 12 | 13 | public UpstreamJobTrigger(Job parent) { 14 | super(parent, "/jenkins-triggers-ReverseBuildTrigger"); 15 | } 16 | 17 | public void setUpstreamProjects(final String... upstreamProjects) { 18 | this.upstreamProjects.set(StringUtils.join(upstreamProjects, ",")); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/po/WhoAmI.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | /** 4 | * Who Am I page in Jenkins 5 | */ 6 | public class WhoAmI extends ContainerPageObject { 7 | 8 | public WhoAmI(ContainerPageObject parent) { 9 | super(parent, parent.url("whoAmI/")); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/slave/LocalSlaveController.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.slave; 2 | 3 | import java.io.IOException; 4 | import java.util.concurrent.Future; 5 | import org.apache.http.concurrent.BasicFuture; 6 | import org.jenkinsci.test.acceptance.po.DumbSlave; 7 | import org.jenkinsci.test.acceptance.po.Jenkins; 8 | import org.jenkinsci.test.acceptance.po.Slave; 9 | 10 | /** 11 | * Launches slaves locally on the same box as the Jenkins master. 12 | * 13 | * @author Kohsuke Kawaguchi 14 | */ 15 | public class LocalSlaveController extends SlaveController { 16 | @Override 17 | public Future install(Jenkins jenkins) { 18 | // Just to make sure the dumb slave is set up properly, we should seed it 19 | // with a FS root and executors 20 | final DumbSlave s = jenkins.slaves.create(DumbSlave.class); 21 | 22 | s.asLocal(); 23 | s.save(); 24 | 25 | s.waitUntilOnline(); 26 | 27 | BasicFuture b = new BasicFuture<>(null); 28 | b.completed(s); 29 | return b; 30 | } 31 | 32 | @Override 33 | public void close() throws IOException {} 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/slave/LocalSlaveProvider.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.slave; 2 | 3 | import jakarta.inject.Singleton; 4 | 5 | /** 6 | * @author Kohsuke Kawaguchi 7 | */ 8 | @Singleton 9 | public class LocalSlaveProvider extends SlaveProvider { 10 | @Override 11 | public SlaveController create() { 12 | return new LocalSlaveController(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/slave/SlaveProvider.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.slave; 2 | 3 | import com.google.inject.Inject; 4 | import jakarta.inject.Provider; 5 | import org.jenkinsci.test.acceptance.guice.TestCleaner; 6 | 7 | /** 8 | * Obtains {@link SlaveController}. 9 | * 10 | * @author Kohsuke Kawaguchi 11 | */ 12 | public abstract class SlaveProvider implements Provider, com.google.inject.Provider { 13 | @Inject 14 | Provider cleaner; 15 | 16 | /** 17 | * Provisions a new place to run a computer from somewhere and return 18 | * an object that encapsulates how to let Jenkins connect to it. 19 | */ 20 | @Override 21 | public SlaveController get() { 22 | SlaveController c = create(); 23 | cleaner.get().addTask(c); 24 | return c; 25 | } 26 | 27 | /** 28 | * Actual SPI for {@link #get()} method that subtypes need to implement. 29 | */ 30 | protected abstract SlaveController create(); 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/update_center/UpdateCenterMetadataDecorator.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.update_center; 2 | 3 | import com.cloudbees.sdk.extensibility.ExtensionPoint; 4 | 5 | /** 6 | * A hook to tweak {@link UpdateCenterMetadata} to allow plugins and versions that are not in the update 7 | * center to be installed and tested. 8 | * 9 | * @author Kohsuke Kawaguchi 10 | */ 11 | @ExtensionPoint 12 | public interface UpdateCenterMetadataDecorator { 13 | void decorate(UpdateCenterMetadata ucm); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/utils/GNUCLibrary.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.utils; 2 | 3 | /** 4 | * @author Kohsuke Kawaguchi 5 | */ 6 | public interface GNUCLibrary { 7 | int kill(int pid, int signal); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/test/acceptance/utils/SystemEnvironmentVariables.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.utils; 2 | 3 | /** 4 | * Gets a system environment variable. First it checks if the variable is set as Java system property and if it is the case, 5 | * it returns the configured value. 6 | * If not then it checks if it is defined as environment variable, and if not it returns the default value. 7 | */ 8 | public class SystemEnvironmentVariables { 9 | 10 | public static String getPropertyVariableOrEnvironment(String property, String def) { 11 | 12 | String propertyValue = System.getProperty(property); 13 | 14 | if (propertyValue == null) { 15 | 16 | String envValue = System.getenv(property); 17 | if (envValue == null) { 18 | return def; 19 | } 20 | 21 | return envValue; 22 | } else { 23 | return propertyValue; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/resources/ath-container/set-java.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Inspired by https://disconnected.systems/blog/another-bash-strict-mode/ 3 | set -uo pipefail 4 | trap 's=$?; echo >&2 "$0: Error on line "$LINENO": $BASH_COMMAND"; exit $s' ERR 5 | 6 | # The selection used by update-alternatives for each java version 7 | if [[ $1 == '17' ]]; then 8 | selection='17-openjdk' 9 | elif [[ $1 == '21' ]]; then 10 | selection='21-openjdk' 11 | else 12 | echo >&2 "Unsupported java version '${1}'" 13 | exit 1 14 | fi 15 | 16 | # For some reason, all tools from JDK are split to 2 groups named java and javac 17 | 18 | JAVA_PATH=$(update-alternatives --list java | grep $selection) 19 | JAVAC_PATH=$(update-alternatives --list javac | grep $selection) 20 | 21 | update-alternatives --set java "$JAVA_PATH" 22 | update-alternatives --set javac "$JAVAC_PATH" 23 | 24 | echo 25 | echo -------------------- INFORMATION -------------------- 26 | echo Running on... 27 | java -version 28 | echo 29 | javac -version 30 | echo 31 | echo Start running tests with... 32 | echo 33 | echo run.sh remote-webdriver-firefox latest -DforkCount=1 -Dmaven.test.failure.ignore=true -B -Dtest=... 34 | echo 35 | echo ------------------ END INFORMATION ------------------ 36 | echo 37 | -------------------------------------------------------------------------------- /src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=INFO,stdout 2 | 3 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 4 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 5 | 6 | # Pattern to output the caller's file name and line number. 7 | log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p (%F:%L) %c - %m%n 8 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/ArtifactoryContainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker.bintray.io/jfrog/artifactory-oss:7.77.6 2 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/GitContainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Starts a container with sshd, git 3 | # and prepares for execution of gitplugin tests. 4 | # 5 | 6 | FROM ubuntu:noble 7 | 8 | RUN mkdir -p /var/run/sshd 9 | 10 | # install SSHD, Git and zip 11 | RUN apt-get update && apt-get install -y \ 12 | openssh-server \ 13 | git \ 14 | zip \ 15 | && rm -rf /var/lib/apt/lists/* 16 | 17 | # create a git user and create .ssh dir 18 | RUN useradd git -d /home/git && \ 19 | mkdir -p /home/git/.ssh && \ 20 | echo "git:git" | chpasswd 21 | 22 | # adding public key to authorized keys 23 | ADD unsafe.pub /home/git/ 24 | RUN cat /home/git/unsafe.pub >> /home/git/.ssh/authorized_keys 25 | 26 | # give the whole /home/git back to the git user 27 | RUN chown -R git /home/git 28 | # Proper permissions for ssh 29 | RUN chown -R git:git /home/git/.ssh 30 | RUN chmod 700 /home/git/.ssh 31 | RUN chmod 600 /home/git/.ssh/authorized_keys 32 | 33 | RUN echo "HostbasedAcceptedKeyTypes +ssh-rsa\nHostKeyAlgorithms +ssh-rsa\nPubkeyAcceptedKeyTypes +ssh-rsa" >> /etc/ssh/sshd_config 34 | 35 | # run SSHD in the foreground with error messages to stderr 36 | CMD /usr/sbin/sshd -D -e 37 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/GitContainer/unsafe.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDzpxmTW9mH87DMkMSqBrSecoSHVCkKbW5IOO+4unak8M8cyn+b0iX07xkBn4hUJRfKA7ezUG8EX9ru5VinteqMOJOPknCuzmUS2Xj/WJdcq3BukBxuyiIRoUOXsCZzilR/DOyNqpjjI3iNb4los5//4aoKPCmLInFnQ3Y42VaimH1298ckEr4tRxsoipsEAANPXZ3p48gGwOf1hp56bTFImvATNwxMViPpqyKcyVaA7tXCBnEk/GEwb6MiroyHbS0VvBz9cZOpJv+8yQnyLndGdibk+hPbGp5iVAIsm28FEF+4FvlYlpBwq9OYuhOCREJvH9CxDMhbOXgwKPno9GyN kohsuke@atlas 2 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/GitLabContainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # Use the official GitLab Community Edition image as the base 2 | FROM gitlab/gitlab-ce:18.0.1-ce.0 3 | 4 | COPY create_user.rb /usr/bin/ 5 | 6 | # Expose the required ports 7 | EXPOSE 80 443 22 8 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/GitLabContainer/create_user.rb: -------------------------------------------------------------------------------- 1 | input_array = ARGV 2 | 3 | user = User.create(); 4 | user.name = input_array[0]; 5 | user.username = input_array[0]; 6 | user.password = input_array[1]; 7 | user.confirmed_at = '01/01/1990'; 8 | user.admin = input_array[3]; 9 | user.email = input_array[2]; 10 | user.save!; 11 | 12 | token = user.personal_access_tokens.create(scopes: [:api], name: 'MyToken'); 13 | token.expires_at='01/01/2024'; 14 | token.save!; 15 | puts token.token; 16 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/JavaGitContainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Starts a container with sshd, git and Java tooling 3 | # and prepares for execution of Java compile jobs on slaves. 4 | # 5 | 6 | FROM ubuntu:noble 7 | 8 | RUN mkdir -p /var/run/sshd 9 | 10 | # install SSHD, Git, zip and the JDK 11 | RUN apt-get update && apt-get install --no-install-recommends -y \ 12 | openssh-server \ 13 | git \ 14 | zip \ 15 | openjdk-17-jdk \ 16 | openjdk-21-jdk \ 17 | && rm -rf /var/lib/apt/lists/* 18 | 19 | # create a git user and create .ssh dir 20 | RUN useradd git -d /home/git && \ 21 | mkdir -p /home/git/.ssh && \ 22 | echo "git:git" | chpasswd 23 | 24 | # adding public key to authorized keys 25 | ADD unsafe.pub /home/git/ 26 | RUN cat /home/git/unsafe.pub >> /home/git/.ssh/authorized_keys 27 | 28 | # run SSHD in the foreground with error messages to stderr 29 | CMD /usr/sbin/sshd -D -e 30 | 31 | # give the whole /home/git back to the git user 32 | RUN chown -R git /home/git 33 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/JavaGitContainer/unsafe.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDzpxmTW9mH87DMkMSqBrSecoSHVCkKbW5IOO+4unak8M8cyn+b0iX07xkBn4hUJRfKA7ezUG8EX9ru5VinteqMOJOPknCuzmUS2Xj/WJdcq3BukBxuyiIRoUOXsCZzilR/DOyNqpjjI3iNb4los5//4aoKPCmLInFnQ3Y42VaimH1298ckEr4tRxsoipsEAANPXZ3p48gGwOf1hp56bTFImvATNwxMViPpqyKcyVaA7tXCBnEk/GEwb6MiroyHbS0VvBz9cZOpJv+8yQnyLndGdibk+hPbGp5iVAIsm28FEF+4FvlYlpBwq9OYuhOCREJvH9CxDMhbOXgwKPno9GyN kohsuke@atlas 2 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/JiraContainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Runs JIRA 3 | # 4 | # The initial password is 'admin:admin' 5 | # 6 | FROM ubuntu:noble 7 | 8 | # Pin JIRA version to make the tests more predictable and less fragile 9 | # In particular, pinned to 6.X because from 7.X the SOAP API is gone, and it's 10 | # used in the tests. Upgrading the tests to use the REST API is not trivial 11 | # since some operations are not yet available in its java client (e.g. project creation) 12 | ENV JIRA_VERSION 6.3 13 | 14 | # base package installation 15 | RUN apt-get update && apt-get install -y apt-transport-https wget gnupg2 software-properties-common && add-apt-repository -s "deb https://packages.atlassian.com/debian/atlassian-sdk-deb/ stable contrib" 16 | RUN wget https://packages.atlassian.com/api/gpg/key/public 17 | RUN apt-key add public 18 | 19 | RUN apt-get update && apt-get install -y openjdk-8-jdk atlassian-plugin-sdk netcat-openbsd 20 | 21 | # this will install the whole thing, launches Tomcat, 22 | # asks the user to do Ctrl+C to quit, then it shuts down presumably because it 23 | # fails to read from stdin? 24 | RUN atlas-run-standalone --product jira -v $JIRA_VERSION < /dev/null 25 | 26 | # unlike the above command, this launches Tomcat then hangs, because it feeds its own tail 27 | # and so stdin will block 28 | CMD atlas-run-standalone --product jira -v $JIRA_VERSION < /dev/stderr 29 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/LdapContainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Dockerfile for openLDAP (slapd) 3 | # Manager-DN (for bind): cn=admin,dc=jenkins-ci,dc=org 4 | # Manager-Password: jenkins 5 | # See config/base.ldif for user/groups directory entries 6 | # 7 | # VERSION=2 8 | # 9 | FROM phusion/baseimage:focal-1.2.0 10 | 11 | ENV HOME /root 12 | 13 | # Disable SSH 14 | RUN rm -rf /etc/service/sshd /etc/my_init.d/00_regen_ssh_host_keys.sh 15 | 16 | # Use baseimage-docker's init system. 17 | CMD ["/sbin/my_init"] 18 | 19 | # Install slapd 20 | RUN LC_ALL=C DEBIAN_FRONTEND=noninteractive apt-get -y update && apt-get install -y slapd && apt-get clean 21 | 22 | # Default configuration: can be overridden at the docker command line 23 | ENV LDAP_ROOTPASS jenkins 24 | ENV LDAP_ORGANISATION Jenkins CI 25 | ENV LDAP_DOMAIN jenkins-ci.org 26 | 27 | # Expose ports 28 | EXPOSE 389 636 29 | 30 | RUN mkdir /etc/service/slapd /etc/slapd-config 31 | 32 | ADD config /etc/slapd-config 33 | RUN cp /etc/slapd-config/slapd.sh /etc/service/slapd/run && chmod 755 /etc/service/slapd/run && chown root:root /etc/service/slapd/run 34 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/LdapContainer/config/cn=config.ldif: -------------------------------------------------------------------------------- 1 | # AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify. 2 | dn: cn=config 3 | objectClass: olcGlobal 4 | cn: config 5 | olcArgsFile: /var/run/slapd/slapd.args 6 | olcLogLevel: none 7 | olcPidFile: /var/run/slapd/slapd.pid 8 | olcToolThreads: 1 9 | structuralObjectClass: olcGlobal 10 | entryUUID: 00dc9e14-5042-1033-9a35-ff1e70d71313 11 | creatorsName: cn=config 12 | createTimestamp: 20140404124009Z 13 | entryCSN: 20140404124009.976505Z#000000#000#000000 14 | modifiersName: cn=config 15 | modifyTimestamp: 20140404124009Z 16 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/LdapContainer/config/cn=config/cn=module{0}.ldif: -------------------------------------------------------------------------------- 1 | # AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify. 2 | dn: cn=module{0} 3 | objectClass: olcModuleList 4 | cn: module{0} 5 | olcModulePath: /usr/lib/ldap 6 | olcModuleLoad: {0}back_mdb 7 | structuralObjectClass: olcModuleList 8 | entryUUID: 00dcf792-5042-1033-9a3d-ff1e70d71313 9 | creatorsName: cn=config 10 | createTimestamp: 20140404124009Z 11 | entryCSN: 20140404124009.978834Z#000000#000#000000 12 | modifiersName: cn=config 13 | modifyTimestamp: 20140404124009Z 14 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/LdapContainer/config/cn=config/cn=schema.ldif: -------------------------------------------------------------------------------- 1 | # AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify. 2 | dn: cn=schema 3 | objectClass: olcSchemaConfig 4 | cn: schema 5 | structuralObjectClass: olcSchemaConfig 6 | entryUUID: 00dcaa58-5042-1033-9a38-ff1e70d71313 7 | creatorsName: cn=config 8 | createTimestamp: 20140404124009Z 9 | entryCSN: 20140404124009.976848Z#000000#000#000000 10 | modifiersName: cn=config 11 | modifyTimestamp: 20140404124009Z 12 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/LdapContainer/config/cn=config/olcBackend={0}mdb.ldif: -------------------------------------------------------------------------------- 1 | # AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify. 2 | dn: olcBackend={0}mdb 3 | objectClass: olcBackendConfig 4 | olcBackend: {0}mdb 5 | structuralObjectClass: olcBackendConfig 6 | entryUUID: 00dd052a-5042-1033-9a3e-ff1e70d71313 7 | creatorsName: cn=config 8 | createTimestamp: 20140404124009Z 9 | entryCSN: 20140404124009.979183Z#000000#000#000000 10 | modifiersName: cn=config 11 | modifyTimestamp: 20140404124009Z 12 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/LdapContainer/config/cn=config/olcDatabase={-1}frontend.ldif: -------------------------------------------------------------------------------- 1 | # AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify. 2 | dn: olcDatabase={-1}frontend 3 | objectClass: olcDatabaseConfig 4 | objectClass: olcFrontendConfig 5 | olcDatabase: {-1}frontend 6 | olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external 7 | ,cn=auth manage by * break 8 | olcAccess: {1}to dn.exact="" by * read 9 | olcAccess: {2}to dn.base="cn=Subschema" by * read 10 | olcSizeLimit: 500 11 | structuralObjectClass: olcDatabaseConfig 12 | entryUUID: 00dca1ca-5042-1033-9a36-ff1e70d71313 13 | creatorsName: cn=config 14 | createTimestamp: 20140404124009Z 15 | entryCSN: 20140404124009.976638Z#000000#000#000000 16 | modifiersName: cn=config 17 | modifyTimestamp: 20140404124009Z 18 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/LdapContainer/config/cn=config/olcDatabase={0}config.ldif: -------------------------------------------------------------------------------- 1 | # AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify. 2 | dn: olcDatabase={0}config 3 | objectClass: olcDatabaseConfig 4 | olcDatabase: {0}config 5 | olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external 6 | ,cn=auth manage by * break 7 | structuralObjectClass: olcDatabaseConfig 8 | entryUUID: 00dca684-5042-1033-9a37-ff1e70d71313 9 | creatorsName: cn=config 10 | createTimestamp: 20140404124009Z 11 | entryCSN: 20140404124009.976760Z#000000#000#000000 12 | modifiersName: cn=config 13 | modifyTimestamp: 20140404124009Z 14 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/LdapContainer/config/cn=config/olcDatabase={1}mdb.ldif: -------------------------------------------------------------------------------- 1 | # AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify. 2 | dn: olcDatabase={1}mdb 3 | objectClass: olcDatabaseConfig 4 | objectClass: olcMdbConfig 5 | olcDatabase: {1}mdb 6 | olcDbDirectory: /var/lib/ldap 7 | olcSuffix: ___sub_domain_here___ 8 | olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymou 9 | s auth by dn="cn=admin,___sub_domain_here___" write by * none 10 | olcAccess: {1}to dn.base="" by * read 11 | olcAccess: {2}to * by self write by dn="cn=admin,___sub_domain_here___" write by * r 12 | ead 13 | olcLastMod: TRUE 14 | olcRootDN: cn=admin,___sub_domain_here___ 15 | olcRootPW:: ___sub_root_passwd_here___ 16 | olcDbCheckpoint: 512 30 17 | olcDbIndex: objectClass eq 18 | structuralObjectClass: olcMdbConfig 19 | entryUUID: 00dd0804-5042-1033-9a3f-ff1e70d71313 20 | creatorsName: cn=config 21 | createTimestamp: 20140404124009Z 22 | entryCSN: 20140404124009.979256Z#000000#000#000000 23 | modifiersName: cn=config 24 | modifyTimestamp: 20140404124009Z 25 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/LdapContainer/config/slapd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -eu 4 | 5 | status () { 6 | echo "---> ${@}" >&2 7 | } 8 | 9 | set -x 10 | : LDAP_ROOTPASS=${LDAP_ROOTPASS} 11 | : LDAP_DOMAIN=${LDAP_DOMAIN} 12 | : LDAP_ORGANISATION=${LDAP_ORGANISATION} 13 | 14 | if [ ! -e /var/lib/ldap/docker_bootstrapped ]; then 15 | status "configuring slapd for first run" 16 | rm -rf /etc/ldap/slapd.d/* 17 | (cd /etc/slapd-config ; tar cpf - .) | (cd /etc/ldap/slapd.d ; tar xpf - ) 18 | chown -R openldap:openldap /etc/ldap 19 | enc_pw=$(slappasswd -h '{SSHA}' -s ${LDAP_ROOTPASS} | base64) 20 | enc_domain=$(echo -n ${LDAP_DOMAIN} | sed -e "s|^|dc=|" -e "s|\.|,dc=|g") 21 | dc_one=$(echo -n ${enc_domain} | sed -e "s|^dc=||" -e "s|,dc=.*$||g") 22 | sed -i -e "s|___sub_root_passwd_here___|${enc_pw}|g" \ 23 | -e "s|___sub_domain_here___|${enc_domain}|g" \ 24 | /etc/ldap/slapd.d/cn\=config/olcDatabase\=\{1\}mdb.ldif 25 | sed -i \ 26 | -e "s|___sub_organization_here___|${LDAP_ORGANISATION}|g" \ 27 | -e "s|___sub_dcone_here___|${dc_one}|g" \ 28 | -e "s|___sub_domain_here___|${enc_domain}|g" \ 29 | /etc/slapd-config/base.ldif 30 | slapadd -b ${enc_domain} -c -F /etc/ldap/slapd.d -l /etc/slapd-config/base.ldif 31 | chown -R openldap:openldap /var/lib/ldap 32 | touch /var/lib/ldap/docker_bootstrapped 33 | else 34 | status "found already-configured slapd" 35 | fi 36 | 37 | status "starting slapd" 38 | set -x 39 | exec /usr/sbin/slapd -h "ldap:/// ldaps:/// ldapi:///" -u openldap -g openldap -d 0 40 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/MailhogContainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mailhog/mailhog:latest 2 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/SMBContainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Runs smbd and allow the 'test' user to connect 3 | # 4 | 5 | FROM ubuntu:22.04 6 | 7 | RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list 8 | RUN apt-get update && apt-get -y install samba 9 | 10 | RUN useradd test -d /home/test -s /bin/bash && \ 11 | mkdir -p /home/test && \ 12 | chown test /home/test && \ 13 | echo "test:test" | chpasswd 14 | 15 | RUN echo "workgroup = WORKGROUP" >> /etc/mysmb.conf 16 | RUN echo "restrict anonymous = no" >> /etc/mysmb.conf 17 | RUN echo "server string = DockerJenkinsSMB" >> /etc/mysmb.conf 18 | RUN echo "netbios name = DockerJenkinsSMB" >> /etc/mysmb.conf 19 | RUN echo "security = share" >> /etc/mysmb.conf 20 | 21 | RUN echo "[tmp]" >> /etc/mysmb.conf 22 | RUN echo " comment = Temp" >> /etc/mysmb.conf 23 | RUN echo " path = /tmp" >> /etc/mysmb.conf 24 | RUN echo " guest ok = Yes" >> /etc/mysmb.conf 25 | RUN echo " read only = no" >> /etc/mysmb.conf 26 | 27 | CMD ["/usr/sbin/smbd", "-i", "-s", "/etc/mysmb.conf"] 28 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/SshAgentContainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # curl -s https://raw.githubusercontent.com/jenkinsci/docker-fixtures/master/src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/JavaContainer/Dockerfile | sha1sum | cut -c 1-12 2 | FROM jenkins/java:978f1af53461 3 | COPY *.pub /tmp 4 | RUN cat /tmp/*.pub >> /home/test/.ssh/authorized_keys 5 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/SshAgentContainer/ed25519.pass: -------------------------------------------------------------------------------- 1 | s3cr3t -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/SshAgentContainer/ed25519.priv: -------------------------------------------------------------------------------- 1 | -----BEGIN OPENSSH PRIVATE KEY----- 2 | b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABBBxPsNvv 3 | HGCpenlluHPEV2AAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAILIWeIVLgSykEziw 4 | P452COSJoTzcvxeh4pS5VdbyW37hAAAAkFB7z0biBe9i1MwzJMFcd+RyslPWFYA2eoZ/sk 5 | yrdGH0KVrjWd6j52kdN51wrjIif2tAj+nqBfEWJmvu3vcFkhS2ZHEqVOHHoPSECQdlThpo 6 | zM/N4M7EBVz1VMAe4tU6EAFYAqSPt5YI+ebSilCvNSBJPIFYW8OKFXkpfo/wTbc0108xbR 7 | 3Hs/0HN7YCKad9LQ== 8 | -----END OPENSSH PRIVATE KEY----- 9 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/SshAgentContainer/ed25519.pub: -------------------------------------------------------------------------------- 1 | ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILIWeIVLgSykEziwP452COSJoTzcvxeh4pS5VdbyW37h testing 2 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/SvnContainer/config/passwd: -------------------------------------------------------------------------------- 1 | [users] 2 | svnUser = test -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/SvnContainer/config/passwd.htpasswd: -------------------------------------------------------------------------------- 1 | svnUser:$apr1$hVTk7G7x$9ov.xJ0h6LPFo/2Whlk/I. -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/SvnContainer/config/supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon=true 3 | user=root 4 | 5 | [program:apache2] 6 | command=/bin/bash -c "source /etc/apache2/envvars && /usr/sbin/apache2 -DFOREGROUND" 7 | stdout_logfile=/dev/stdout 8 | stdout_logfile_maxbytes=0 9 | stderr_logfile=/dev/stderr 10 | stderr_logfile_maxbytes=0 11 | 12 | [program:svnserve] 13 | command=/usr/bin/svnserve -d --foreground -r /var/lib/svn/myrepo/ 14 | stdout_logfile=/dev/stdout 15 | stdout_logfile_maxbytes=0 16 | stderr_logfile=/dev/stderr 17 | stderr_logfile_maxbytes=0 18 | 19 | [program:ssh] 20 | command=/usr/sbin/sshd -D -e 21 | stdout_logfile=/dev/stdout 22 | stdout_logfile_maxbytes=0 23 | stderr_logfile=/dev/stderr 24 | stderr_logfile_maxbytes=0 25 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/SvnContainer/svnRepo/simpleProject/testTwo.txt: -------------------------------------------------------------------------------- 1 | I'm going to be uploaded to the repository. -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/SvnContainer/svnRepo/testOne.txt: -------------------------------------------------------------------------------- 1 | I'm going to be uploaded to the repository. -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/Tomcat10Container/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Runs Tomcat10 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:noble 8 | 9 | RUN apt-get update && apt-get install -y tomcat10 tomcat10-admin 10 | 11 | # configure the admin user 12 | RUN echo '' > /etc/tomcat10/tomcat-users.xml 13 | 14 | EXPOSE 8080 15 | CMD CATALINA_BASE=/var/lib/tomcat10/ /usr/share/tomcat10/bin/catalina.sh run 16 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/XvncSlaveContainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # curl -s https://raw.githubusercontent.com/jenkinsci/docker-fixtures/master/src/main/resources/org/jenkinsci/test/acceptance/docker/fixtures/JavaContainer/Dockerfile | sha1sum | cut -c 1-12 2 | FROM jenkins/java:978f1af53461 3 | RUN apt-get update && apt-get install -y tigervnc-standalone-server imagemagick 4 | 5 | # So it is owned by root and has the permissions vncserver seems to require: 6 | RUN mkdir /tmp/.X11-unix && chmod 1777 /tmp/.X11-unix/ 7 | 8 | # TODO seems this can be picked up from the host, which is unwanted: 9 | ENV XAUTHORITY /home/test/.Xauthority 10 | 11 | USER test 12 | RUN mkdir /home/test/.vnc && (echo jenkins; echo jenkins) | vncpasswd /home/test/.vnc/passwd 13 | # Default content includes x-window-manager, which is not installed, plus other stuff we do not need (vncconfig, x-terminal-emulator, etc.): 14 | RUN touch /home/test/.vnc/xstartup && chmod a+x /home/test/.vnc/xstartup 15 | USER root 16 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/machine/autoterminate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ## 4 | ## Touches $HOME/terminate.txt file if there is at least 1 sshd process 5 | ## is found running by the user owning this process. It would wait for $2 6 | ## 7 | ## $1 username 8 | ## $2 timout to wait before shutdown 9 | ## 10 | ## author: Vivek Pandey 11 | ## 12 | function usage(){ 13 | echo "USAGE: sh autoterminate.sh USERNAME TIMEOUT" 14 | exit 1 15 | } 16 | 17 | if [ -z "$1" ] 18 | then 19 | usage 20 | fi 21 | 22 | if [ -z "$2" ] 23 | then 24 | usage 25 | fi 26 | 27 | if [ $# -eq 0 ] 28 | then 29 | usage 30 | fi 31 | 32 | echo "Executing with username=$1, timeout=$2" 33 | 34 | FILE=$HOME/terminate.txt 35 | echo touching file $FILE 36 | 37 | touch $FILE 38 | 39 | while(true) 40 | do 41 | num_of_sshd=$(pgrep -u $1 sshd |wc -l) 42 | if [ -z "$num_of_sshd" ] 43 | then 44 | num_of_sshd=0 45 | fi 46 | 47 | echo Number of sshd processes: $num_of_sshd 48 | 49 | if [ $num_of_sshd -gt 0 ] 50 | then 51 | echo "Touching file..." 52 | touch $FILE 53 | fi 54 | 55 | if test `find "$FILE" -cmin +$2` 56 | then 57 | echo "Shutting down now..." 58 | sudo shutdown -h now 59 | exit 0 60 | else 61 | echo Not yet, waiting for $2 minutes 62 | fi 63 | echo "Going to sleep for 10 min" 64 | sleep 600 65 | done 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/plugins/ant/fake-ant.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo fake ant at $0 3 | export ANT_HOME= 4 | exec "%s/ant" "$@" 5 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/selenium/disable-sticky-elements.js: -------------------------------------------------------------------------------- 1 | // Disable smooth scrolling so scrolling is instantaneous 2 | document.querySelector("html").style.scrollBehavior = "initial"; 3 | 4 | // Disable common sticky elements 5 | const breadcrumbBar = document.querySelector("#breadcrumbBar"); 6 | const bottomAppBar = document.querySelector("#bottom-sticker"); 7 | 8 | if (breadcrumbBar) { 9 | breadcrumbBar.style.position = "relative"; 10 | } 11 | 12 | if (bottomAppBar) { 13 | bottomAppBar.style.position = "relative"; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/test/acceptance/selenium/scroller.js: -------------------------------------------------------------------------------- 1 | // Visually navigate to the element in order to interact with it. 2 | 3 | var eYCoord = arguments[0]; 4 | var eXCoord = arguments[1]; 5 | var id = arguments[2]; 6 | var footer = document.getElementsByTagName("footer"); 7 | var sticker = document.getElementById("bottom-sticker"); 8 | 9 | // Scroll to the element. It will appear at the top edge of the screen. 10 | // We subtract a bit so as to accommodate fixed position banners at the top 11 | // (e.g. breadcrumbs, tabbars etc), making sure they are not hiding the element. 12 | window.scrollTo(eXCoord - 100, eYCoord - 200); 13 | if(sticker == null || !sticker.contains(document.getElementById(id)) || footer.length != 1){ 14 | return true; 15 | } 16 | else{ 17 | //it is sticker button and it is moved up (footer does not overlap) 18 | return (footer[0].getBoundingClientRect().top >= sticker.getBoundingClientRect().bottom) 19 | } -------------------------------------------------------------------------------- /src/test/java/UnixDomainSocketTestServer.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.InputStream; 3 | import java.io.OutputStream; 4 | import java.nio.channels.Channels; 5 | import jnr.unixsocket.UnixServerSocketChannel; 6 | import jnr.unixsocket.UnixSocketAddress; 7 | import jnr.unixsocket.UnixSocketChannel; 8 | import org.apache.commons.io.IOUtils; 9 | 10 | /** 11 | * Unix domain socket test. 12 | * 13 | * @author Kohsuke Kawaguchi 14 | */ 15 | public class UnixDomainSocketTestServer { 16 | public static void main(String[] args) throws Exception { 17 | File path = new File("./jenkins.sock"); 18 | path.deleteOnExit(); 19 | UnixServerSocketChannel channel = UnixServerSocketChannel.open(); 20 | channel.configureBlocking(true); 21 | channel.socket().bind(new UnixSocketAddress(path)); 22 | 23 | while (true) { 24 | UnixSocketChannel c = channel.accept(); 25 | System.out.println("Accepted"); 26 | 27 | InputStream in = Channels.newInputStream(c); 28 | OutputStream out = Channels.newOutputStream(c); 29 | 30 | IOUtils.copy(in, out); 31 | System.out.println("Closed"); 32 | c.close(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/core/JdkTest.java: -------------------------------------------------------------------------------- 1 | package core; 2 | 3 | import org.jenkinsci.test.acceptance.junit.AbstractJUnitTest; 4 | import org.jenkinsci.test.acceptance.junit.Native; 5 | import org.jenkinsci.test.acceptance.po.FreeStyleJob; 6 | import org.jenkinsci.test.acceptance.po.JdkInstallation; 7 | import org.jenkinsci.test.acceptance.po.ToolInstallation; 8 | import org.junit.Test; 9 | 10 | public class JdkTest extends AbstractJUnitTest { 11 | 12 | // This actually tests any installed JDK, not necessarily oracle. 13 | @Test 14 | @Native("java") 15 | public void usePreinstalledJdk() { 16 | String expectedVersion = localJavaVersion(); 17 | 18 | JdkInstallation jdk = ToolInstallation.addTool(jenkins, JdkInstallation.class); 19 | jdk.name.set("preinstalled"); 20 | jdk.useNative(); 21 | jdk.getPage().save(); 22 | 23 | FreeStyleJob job = jenkins.jobs.create(); 24 | job.configure(); 25 | job.addShellStep("java -version"); 26 | job.save(); 27 | 28 | job.startBuild().shouldSucceed().shouldContainsConsoleOutput(expectedVersion); 29 | } 30 | 31 | private String localJavaVersion() { 32 | return jenkins.runScript("'java -version'.execute().text"); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/core/ScriptTest.java: -------------------------------------------------------------------------------- 1 | package core; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.Matchers.is; 5 | 6 | import com.google.inject.Inject; 7 | import org.jenkinsci.test.acceptance.junit.AbstractJUnitTest; 8 | import org.jenkinsci.test.acceptance.po.Slave; 9 | import org.jenkinsci.test.acceptance.slave.SlaveController; 10 | import org.junit.Test; 11 | 12 | public class ScriptTest extends AbstractJUnitTest { 13 | @Inject 14 | SlaveController slave; 15 | 16 | @Test 17 | public void execute_system_script() throws Exception { 18 | String output = jenkins.runScript("println Jenkins.instance.displayName;"); 19 | assertThat(output, is("Jenkins")); 20 | 21 | Slave s = slave.install(jenkins).get(); 22 | output = s.runScript("println 6 * 7"); 23 | assertThat(output, is("42")); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/test/acceptance/ByFactoryTest.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * @author ogondza. 9 | */ 10 | public class ByFactoryTest { 11 | private ByFactory by = new ByFactory(); 12 | 13 | @Test 14 | public void formatXPath() throws Exception { 15 | // No args 16 | String XPATH = "//*[text() = 'foo']"; 17 | assertEquals(XPATH, by.formatXPath(XPATH)); 18 | 19 | // Unquoted, quoted and double quoted placeholder 20 | assertEquals( 21 | "//*[text() =\"D'oh!\"or text() = \"D'oh!\" or text() = \"D'oh!\"]", 22 | by.formatXPath("//*[text() = %s or text() = '%s' or text() = \"%s\"]", "D'oh!", "D'oh!", "D'oh!")); 23 | assertEquals( 24 | "//*[text() ='\"Quotes3\"'or text() = '\"Quotes1\"' or text() = '\"Quotes2\"']", 25 | by.formatXPath( 26 | "//*[text() = %3$s or text() = '%1$s' or text() = \"%2$s\"]", 27 | "\"Quotes1\"", "\"Quotes2\"", "\"Quotes3\"")); 28 | assertEquals( 29 | "//*[text() =concat('40° 26', \"'\", ' 46\"', '')or text() = concat('40° 26', \"'\", ' 46\"', '') or text() = concat('40° 26', \"'\", ' 46\"', '')]", 30 | by.formatXPath("//*[text() = %1$s or text() = '%1$s' or text() = \"%1$s\"]", "40° 26' 46\"")); 31 | 32 | // Part of larger quoted string 33 | assertEquals("'/path/'", by.formatXPath("'/%s/'", "path")); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/test/acceptance/po/PluginManagerTest.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.net.URISyntaxException; 6 | import org.jenkinsci.test.acceptance.junit.AbstractJUnitTest; 7 | import org.junit.Test; 8 | 9 | public class PluginManagerTest extends AbstractJUnitTest { 10 | 11 | @Test 12 | public void installAVerySpecificPluginByHpiFile() throws IOException, URISyntaxException { 13 | final File plugin = new File(getClass().getResource("ant-1.0.hpi").toURI()); 14 | jenkins.getPluginManager().installPlugin(plugin); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/test/acceptance/po/SnippetGeneratorTest.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.test.acceptance.po; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.Matchers.is; 5 | 6 | import org.jenkinsci.test.acceptance.junit.AbstractJUnitTest; 7 | import org.jenkinsci.test.acceptance.junit.WithPlugins; 8 | import org.junit.Test; 9 | 10 | @WithPlugins("pipeline-model-definition") 11 | public class SnippetGeneratorTest extends AbstractJUnitTest { 12 | @Test 13 | public void createPipelineSnippetToArchiveArtifacts() { 14 | WorkflowJob job = jenkins.getJobs().create(WorkflowJob.class); 15 | job.save(); 16 | 17 | SnippetGenerator snippetGenerator = new SnippetGenerator(job); 18 | snippetGenerator.open(); 19 | 20 | assertThat(snippetGenerator.generateScript(), is("archiveArtifacts artifacts: '', followSymlinks: false")); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/plugins/ProjectDescriptionSetterPluginTest.java: -------------------------------------------------------------------------------- 1 | package plugins; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.Matchers.containsString; 5 | 6 | import org.jenkinsci.test.acceptance.junit.AbstractJUnitTest; 7 | import org.jenkinsci.test.acceptance.junit.WithPlugins; 8 | import org.jenkinsci.test.acceptance.plugins.project_description_setter.ProjectDescriptionSetter; 9 | import org.jenkinsci.test.acceptance.po.FreeStyleJob; 10 | import org.junit.Test; 11 | 12 | @WithPlugins({ 13 | "matrix-project", // JENKINS-37545 14 | "project-description-setter" 15 | }) 16 | public class ProjectDescriptionSetterPluginTest extends AbstractJUnitTest { 17 | @Test 18 | public void set_project_description_based_upon_file_in_workspace() { 19 | FreeStyleJob j = jenkins.jobs.create(); 20 | j.configure(); 21 | j.addShellStep("echo 'Project description setter test' > desc.txt"); 22 | ProjectDescriptionSetter w = j.addBuildWrapper(ProjectDescriptionSetter.class); 23 | w.filename.set("desc.txt"); 24 | j.save(); 25 | 26 | j.startBuild().shouldSucceed(); 27 | j.open(); 28 | String t = find(by.xpath("//div[@id=\"description\"]/div")).getText(); 29 | assertThat(t, containsString("Project description setter test")); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/resources/artifactory_plugin/multimodule/module_a/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | gid 5 | module_a 6 | 2.0 7 | 8 | -------------------------------------------------------------------------------- /src/test/resources/artifactory_plugin/multimodule/module_b/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | gid 5 | module_b 6 | 3.0 7 | 8 | -------------------------------------------------------------------------------- /src/test/resources/artifactory_plugin/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 | -------------------------------------------------------------------------------- /src/test/resources/artifactory_plugin/quickstart/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'eclipse' 4 | id 'maven-publish' 5 | } 6 | 7 | version = '1.0' 8 | jar { 9 | manifest { 10 | attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version 11 | } 12 | } 13 | 14 | repositories { 15 | mavenCentral() 16 | } 17 | 18 | dependencies { 19 | compileOnly group: 'commons-collections', name: 'commons-collections', version: '3.2.2' 20 | testImplementation group: 'junit', name: 'junit', version: '4.+' 21 | } 22 | 23 | test { 24 | systemProperties 'property': 'value' 25 | } 26 | 27 | publishing { 28 | publications { 29 | mavenJava(MavenPublication) { 30 | from components.java 31 | } 32 | } 33 | 34 | repositories { 35 | flatDir { 36 | dirs 'repos' 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/resources/artifactory_plugin/quickstart/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/acceptance-test-harness/ca87b2b59e5aaecfa38fc78dff83083ad465f379/src/test/resources/artifactory_plugin/quickstart/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/test/resources/artifactory_plugin/quickstart/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /src/test/resources/artifactory_plugin/quickstart/src/main/java/org/gradle/Person.java: -------------------------------------------------------------------------------- 1 | package org.gradle; 2 | 3 | import org.apache.commons.collections.list.GrowthList; 4 | 5 | public class Person { 6 | private final String name; 7 | 8 | public Person(String name) { 9 | this.name = name; 10 | new GrowthList(); 11 | } 12 | 13 | public String getName() { 14 | return name; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/resources/artifactory_plugin/quickstart/src/main/resources/org/gradle/resource.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/test/resources/artifactory_plugin/quickstart/src/test/java/org/gradle/PersonTest.java: -------------------------------------------------------------------------------- 1 | package org.gradle; 2 | 3 | import org.junit.Test; 4 | import static org.junit.Assert.*; 5 | 6 | public class PersonTest { 7 | @Test 8 | public void canConstructAPersonWithAName() { 9 | Person person = new Person("Larry"); 10 | assertEquals("Larry", person.getName()); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/resources/artifactory_plugin/quickstart/src/test/resources/org/gradle/test-resource.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/test/resources/configuration_as_code/trivial.yaml: -------------------------------------------------------------------------------- 1 | jenkins: 2 | systemMessage: JCasC populated description 3 | -------------------------------------------------------------------------------- /src/test/resources/credentialsbinding/secretFile: -------------------------------------------------------------------------------- 1 | secret inside a file -------------------------------------------------------------------------------- /src/test/resources/credentialsbinding/secretFileScript: -------------------------------------------------------------------------------- 1 | node { 2 | withCredentials([file(credentialsId: '%s', variable: 'SECRETFILE')]) { 3 | sh 'cat $SECRETFILE > testfile' 4 | def content = readFile 'testfile' 5 | sh '[ \"' + content + '\" = \"%s\" ] && echo \"%s\"' 6 | } 7 | } -------------------------------------------------------------------------------- /src/test/resources/credentialsbinding/secretFileScriptWindows: -------------------------------------------------------------------------------- 1 | node { 2 | withCredentials([file(credentialsId: '%s', variable: 'SECRETFILE')]) { 3 | bat '@type %%SECRETFILE%% > testfile' 4 | def content = readFile 'testfile' 5 | bat '@if \"' + content + '\"==\"%s\" echo \"%s\"' 6 | } 7 | } -------------------------------------------------------------------------------- /src/test/resources/credentialsbinding/secretTextScript: -------------------------------------------------------------------------------- 1 | node { 2 | withCredentials([string(credentialsId: '%s', variable: 'SECRET')]) { 3 | sh '[ \"$SECRET\" = \"%s\" ] && echo \"%s\"' 4 | } 5 | } -------------------------------------------------------------------------------- /src/test/resources/credentialsbinding/secretTextScriptWindows: -------------------------------------------------------------------------------- 1 | node { 2 | withCredentials([string(credentialsId: '%s', variable: 'SECRET')]) { 3 | bat '@if \"%%SECRET%%\"==\"%s\" echo \"%s\"' 4 | } 5 | } -------------------------------------------------------------------------------- /src/test/resources/credentialsbinding/secretZip.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/acceptance-test-harness/ca87b2b59e5aaecfa38fc78dff83083ad465f379/src/test/resources/credentialsbinding/secretZip.zip -------------------------------------------------------------------------------- /src/test/resources/credentialsbinding/secretZipFileScript: -------------------------------------------------------------------------------- 1 | node { 2 | withCredentials([zip(credentialsId: '%s', variable: 'SECRETFILE')]) { 3 | sh 'cat $SECRETFILE/dir/testfile.txt > testfile' 4 | def content = readFile 'testfile' 5 | sh '[ \"' + content.trim() + '\" = \"%s\" ] && echo \"%s\"' 6 | } 7 | } -------------------------------------------------------------------------------- /src/test/resources/credentialsbinding/secretZipFileScriptWindows: -------------------------------------------------------------------------------- 1 | node { 2 | withCredentials([zip(credentialsId: '%s', variable: 'SECRETFILE')]) { 3 | bat '@type %%SECRETFILE%%\\dir\\testfile.txt > testfile' 4 | def content = readFile 'testfile' 5 | bat '@if \"' + content.trim() + '\"==\"%s\" echo \"%s\"' 6 | } 7 | } -------------------------------------------------------------------------------- /src/test/resources/credentialsbinding/sshUserPrivateKeyScript: -------------------------------------------------------------------------------- 1 | node { 2 | withCredentials([sshUserPrivateKey(keyFileVariable: 'THEKEY', passphraseVariable: 'THEPASS', usernameVariable: 'THEUSER', credentialsId: '%s')]) { 3 | sh '[ \"$THEUSER\" = \"%s\" ] && echo \"%s\"' 4 | sh '[ \"$THEPASS\" = \"%s\" ] && echo \"%s\"' 5 | sh 'cat $THEKEY > testfile' 6 | def content = readFile 'testfile' 7 | sh '[ \"' + content.trim() + '\" = \"%s\" ] && echo \"%s\"' 8 | } 9 | } -------------------------------------------------------------------------------- /src/test/resources/credentialsbinding/sshUserPrivateKeyScriptWindows: -------------------------------------------------------------------------------- 1 | node { 2 | withCredentials([sshUserPrivateKey(keyFileVariable: 'THEKEY', passphraseVariable: 'THEPASS', usernameVariable: 'THEUSER', credentialsId: '%s')]) { 3 | bat '@if \"%%THEUSER%%\"==\"%s\" echo \"%s\"' 4 | bat '@if \"%%THEPASS%%\"==\"%s\" echo \"%s\"' 5 | bat '@type %%THEKEY%% > testfile' 6 | def content = readFile 'testfile' 7 | bat '@if \"' + content.trim() + '\"==\"%s\" echo \"%s\"' 8 | } 9 | } -------------------------------------------------------------------------------- /src/test/resources/credentialsbinding/usernameSplitPasswordScript: -------------------------------------------------------------------------------- 1 | node { 2 | withCredentials([usernamePassword(credentialsId: '%s', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { 3 | sh '[ \"$USERNAME\" = \"%s\" ] && echo \"%s\"' 4 | sh '[ \"$PASSWORD\" = \"%s\" ] && echo \"%s\"' 5 | } 6 | } -------------------------------------------------------------------------------- /src/test/resources/credentialsbinding/usernameSplitPasswordScriptWindows: -------------------------------------------------------------------------------- 1 | node { 2 | withCredentials([usernamePassword(credentialsId: '%s', usernameVariable: 'MYUSERNAME', passwordVariable: 'MYPASSWORD')]) { 3 | bat '@if \"%%MYUSERNAME%%\"==\"%s\" echo \"%s\"' 4 | bat '@if \"%%MYPASSWORD%%\"==\"%s\" echo \"%s\"' 5 | } 6 | } -------------------------------------------------------------------------------- /src/test/resources/credentialsbinding/usernameTogetherPasswordScript: -------------------------------------------------------------------------------- 1 | node { 2 | withCredentials([usernameColonPassword(credentialsId: '%s', variable: 'COMPLETE_PASSWORD')]) { 3 | sh '[ \"$COMPLETE_PASSWORD\" = \"%s\" ] && echo \"%s\"' 4 | } 5 | } -------------------------------------------------------------------------------- /src/test/resources/credentialsbinding/usernameTogetherPasswordScriptWindows: -------------------------------------------------------------------------------- 1 | node { 2 | withCredentials([usernameColonPassword(credentialsId: '%s', variable: 'COMPLETE_PASSWORD')]) { 3 | bat '@if \"%%COMPLETE_PASSWORD%%\"==\"%s\" echo \"%s\"' 4 | } 5 | } -------------------------------------------------------------------------------- /src/test/resources/deploy_plugin/build-war.sh: -------------------------------------------------------------------------------- 1 | [ -d my-webapp ] || mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-webapp -DarchetypeArtifactId=maven-archetype-webapp 2 | cd my-webapp 3 | mvn install 4 | -------------------------------------------------------------------------------- /src/test/resources/docker_build_step/context.dir/Dockerfile: -------------------------------------------------------------------------------- 1 | # Dummy container 2 | 3 | FROM ubuntu 4 | -------------------------------------------------------------------------------- /src/test/resources/gradle_plugin/pipeline_test_multiple_tasks.txt: -------------------------------------------------------------------------------- 1 | stage ('build_Project') { 2 | tools { 3 | gradle 'Gradle 4.10.2' 4 | } 5 | 6 | steps { 7 | script { 8 | sh "gradle firstTask secondTask --no-daemon" 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/test/resources/gradle_plugin/script.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.gradle.build-scan' version '1.16' 3 | } 4 | 5 | buildScan { 6 | licenseAgreementUrl = 'https://gradle.com/terms-of-service' 7 | licenseAgree = 'yes' 8 | } 9 | 10 | task hello { 11 | doLast { 12 | println 'Hello world!' 13 | } 14 | } 15 | 16 | task firstTask { 17 | doLast { 18 | println 'First!' 19 | } 20 | } 21 | 22 | task secondTask { 23 | doLast { 24 | println 'Second!' 25 | } 26 | } 27 | 28 | task environmentVariables { 29 | doLast { 30 | ext.env = System.getenv() 31 | ext.buildNumber = env.BUILD_NUMBER?.toInteger() 32 | println "Build Number: $buildNumber" 33 | 34 | ext.buildName = env.BUILD_DISPLAY_NAME?.toString() 35 | 36 | ext.jobName = env.JOB_NAME?.toString() 37 | println "Build Name: $jobName $buildName" 38 | } 39 | } 40 | 41 | task jobParametersAsProjectProperties { 42 | doLast { 43 | println "Project Properties: $project.PROJ_PARAM_1 $project.PROJ_PARAM_2" 44 | } 45 | } 46 | 47 | task jobParametersAsSystemProperties { 48 | doLast { 49 | println "System Properties: " + System.properties.getProperty('SYS_PARAM_1') + " " + System.properties.getProperty('SYS_PARAM_2') 50 | } 51 | } 52 | 53 | wrapper { 54 | gradleVersion = '4.0' 55 | } 56 | -------------------------------------------------------------------------------- /src/test/resources/gradle_plugin/scriptNoPlugins.gradle: -------------------------------------------------------------------------------- 1 | 2 | task hello { 3 | doLast { 4 | println 'Hello world!' 5 | } 6 | } 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/test/resources/htmlpublisher_plugin/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

Published HTML

8 |

hidden

9 | 10 | 11 | -------------------------------------------------------------------------------- /src/test/resources/htmlpublisher_plugin/style.css: -------------------------------------------------------------------------------- 1 | p { 2 | display: none; 3 | } 4 | -------------------------------------------------------------------------------- /src/test/resources/job_dsl_plugin/CreateFolder.groovy: -------------------------------------------------------------------------------- 1 | folder('My_Folder') -------------------------------------------------------------------------------- /src/test/resources/job_dsl_plugin/CreateJobInFolder.groovy: -------------------------------------------------------------------------------- 1 | job('My_Folder/New_Job') -------------------------------------------------------------------------------- /src/test/resources/job_dsl_plugin/MyUtilities.groovy: -------------------------------------------------------------------------------- 1 | package utilities 2 | 3 | class MyUtilities { 4 | static void addDescription(def job) { 5 | job.with { 6 | description('Description from class in src folder.') 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/test/resources/job_dsl_plugin/Utility.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/acceptance-test-harness/ca87b2b59e5aaecfa38fc78dff83083ad465f379/src/test/resources/job_dsl_plugin/Utility.jar -------------------------------------------------------------------------------- /src/test/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 | -------------------------------------------------------------------------------- /src/test/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 | -------------------------------------------------------------------------------- /src/test/resources/logparser_plugin/rules/log-parser-rule-markings: -------------------------------------------------------------------------------- 1 | warn /.*warn.*/ 2 | error /.*error.*/ -------------------------------------------------------------------------------- /src/test/resources/logparser_plugin/rules/log-parser-rules-JENKINS33085: -------------------------------------------------------------------------------- 1 | # Fail 2 | error /("grade"(:\s+|:)("D\+"|"D"|"D-"|"F")|Err: Certificate not valid for domain name|Err: Unable to connect to server)/ 3 | 4 | # Warn as TLS Certs Begin to Degrade 5 | warning /"grade"(:\s+|:)("B\+"|"B"|"B-"|"C\+"|"C"|"C-")/ 6 | 7 | # Build Success 8 | info /"grade"(:\s+|:)("A\+"|"A"|"A-")/ -------------------------------------------------------------------------------- /src/test/resources/logparser_plugin/rules/log-parser-rules-sample: -------------------------------------------------------------------------------- 1 | info /Building in workspace.*/ 2 | info /Finished: SUCCESS/ 3 | 4 | start /Started by user.*/ 5 | warning /\[WARNING\].*/ 6 | 7 | error /\[ERROR\].*/ 8 | -------------------------------------------------------------------------------- /src/test/resources/maven_plugin/multimodule/module_a/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | gid 5 | module_a 6 | 2.0 7 | 8 | -------------------------------------------------------------------------------- /src/test/resources/maven_plugin/multimodule/module_b/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | gid 5 | module_b 6 | 3.0 7 | 8 | -------------------------------------------------------------------------------- /src/test/resources/maven_plugin/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 | -------------------------------------------------------------------------------- /src/test/resources/msbuild_plugin/projProject/HelloWorld.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | class HelloWorld 4 | { 5 | static void Main() 6 | { 7 | #if DebugConfig 8 | Console.WriteLine("WE ARE IN THE DEBUG CONFIGURATION"); 9 | #endif 10 | 11 | Console.WriteLine("Hello, world!"); 12 | } 13 | } -------------------------------------------------------------------------------- /src/test/resources/msbuild_plugin/projProject/project.proj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/test/resources/msbuild_plugin/slnProject/HelloWorld.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | class HelloWorld 4 | { 5 | static void Main() 6 | { 7 | #if DebugConfig 8 | Console.WriteLine("WE ARE IN THE DEBUG CONFIGURATION"); 9 | #endif 10 | 11 | Console.WriteLine("Hello, world!"); 12 | } 13 | } -------------------------------------------------------------------------------- /src/test/resources/msbuild_plugin/slnProject/project.proj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/test/resources/msbuild_plugin/slnProject/project.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 14 3 | VisualStudioVersion = 14.0.23107.0 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloWorld", "project.proj", "{00D09290-F731-49A7-B960-C30AEBE8B1F2}" 6 | EndProject -------------------------------------------------------------------------------- /src/test/resources/org/jenkinsci/test/acceptance/po/ant-1.0.hpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/acceptance-test-harness/ca87b2b59e5aaecfa38fc78dff83083ad465f379/src/test/resources/org/jenkinsci/test/acceptance/po/ant-1.0.hpi -------------------------------------------------------------------------------- /src/test/resources/pipelines/hello-world/Jenkinsfile: -------------------------------------------------------------------------------- 1 | echo 'Hello Jenkinsfile in Git' -------------------------------------------------------------------------------- /src/test/resources/plaincredentialsbinding/secretFile: -------------------------------------------------------------------------------- 1 | secret inside a file -------------------------------------------------------------------------------- /src/test/resources/plugins/ant/custom-build-file.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/test/resources/plugins/ant/echo-helloworld.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/test/resources/scriptler_plugin/hello_parameterized.groovy: -------------------------------------------------------------------------------- 1 | println "Hello " + noun + "!" 2 | -------------------------------------------------------------------------------- /src/test/resources/scriptler_plugin/hello_world.groovy: -------------------------------------------------------------------------------- 1 | println "Hello world!" 2 | -------------------------------------------------------------------------------- /src/test/resources/stageview_plugin/multi_job.txt: -------------------------------------------------------------------------------- 1 | node { 2 | stage ('Clone sources'){ 3 | echo 'cloned' 4 | } 5 | stage ('Build'){ 6 | echo 'build' 7 | } 8 | } -------------------------------------------------------------------------------- /src/test/resources/stageview_plugin/multi_job_aborted.txt: -------------------------------------------------------------------------------- 1 | node { 2 | stage ('Clone sources'){ 3 | echo 'cloned' 4 | } 5 | stage ('Unstable') { 6 | currentBuild.result = 'ABORTED' 7 | } 8 | } -------------------------------------------------------------------------------- /src/test/resources/stageview_plugin/multi_job_fail.txt: -------------------------------------------------------------------------------- 1 | node { 2 | stage ('Clone sources'){ 3 | echo 'cloned' 4 | } 5 | stage ('Build'){ 6 | echo 'Meant to fail' 7 | sh 'exit 1' 8 | } 9 | } -------------------------------------------------------------------------------- /src/test/resources/stageview_plugin/multi_job_irregularnames.txt: -------------------------------------------------------------------------------- 1 | node { 2 | stage ('-'){ 3 | } 4 | stage ('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'){ 5 | echo 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890' 6 | } 7 | stage (',.-;:_*+#'){ 8 | echo ',.-;:_*+#' 9 | } 10 | } -------------------------------------------------------------------------------- /src/test/resources/stageview_plugin/multi_job_unstable.txt: -------------------------------------------------------------------------------- 1 | node { 2 | stage ('Clone sources'){ 3 | echo 'cloned' 4 | } 5 | stage ('Unstable') { 6 | currentBuild.result = 'UNSTABLE' 7 | } 8 | } -------------------------------------------------------------------------------- /src/test/resources/stageview_plugin/single_job.txt: -------------------------------------------------------------------------------- 1 | node { 2 | stage ('Clone sources'){ 3 | echo 'cloned' 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/test/resources/textfinder_plugin/textfinder-result_failed.log: -------------------------------------------------------------------------------- 1 | RESULT=FAILED -------------------------------------------------------------------------------- /src/test/resources/textfinder_plugin/textfinder-result_success.log: -------------------------------------------------------------------------------- 1 | RESULT=SUCCESS -------------------------------------------------------------------------------- /src/test/resources/textfinder_plugin/textfinder-result_warning.log: -------------------------------------------------------------------------------- 1 | RESULT=WARNING -------------------------------------------------------------------------------- /vars.cmd: -------------------------------------------------------------------------------- 1 | @REM script for setting all the variables in order to run the ATH locally on windows 2 | @REM use config.groovy in the same folder if desired uncomment below 3 | @REM set CONFIG=%~dp0%config.groovy 4 | set DISPLAY=:0 5 | set INTERACTIVE=false 6 | set BROWSER=remote-webdriver-firefox 7 | set REMOTE_WEBDRIVER_URL=http://127.0.0.1:4444/wd/hub 8 | set JENKINS_JAVA_OPTS=-Xmx1280m 9 | 10 | @REM Jenkins binds to 0.0.0.0 (OMG) so we can use any network but the docker network. 11 | @REM but we may as well use the default network 12 | @echo off 13 | FOR /f "tokens=3" %%F in ('netsh interface ipv4 show addresses "vEthernet (WSL)" ^| findstr /c:"IP Address:"') DO ( 14 | SET IP=%%F 15 | ) 16 | FOR /f "tokens=3" %%F in ('netsh interface ipv4 show addresses "vEthernet (WSL (Hyper-V firewall))" ^| findstr /c:"IP Address:"') DO ( 17 | SET IP=%%F 18 | ) 19 | IF NOT DEFINED IP ( 20 | echo "*** ERROR could not find the docker interface - is docker started?" 21 | exit /b 1 22 | ) 23 | 24 | @echo on 25 | set SELENIUM_PROXY_HOSTNAME=%IP% 26 | set TESTCONTAINERS_HOST_OVERRIDE=%IP% 27 | set JENKINS_LOCAL_HOSTNAME=%IP% 28 | @echo. 29 | @echo To start the remote firefox container run the following command: 30 | @echo docker run --shm-size=2g -d -p 127.0.0.1:4444:4444 -p 127.0.0.1:5900:5900 -e SE_NODE_GRID_URL=http://127.0.0.1:4444 -e no_proxy=localhost -e SE_SCREEN_WIDTH=1680 -e SE_SCREEN_HEIGHT=1090 selenium/standalone-firefox:4.32.0 31 | 32 | -------------------------------------------------------------------------------- /vars.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | die() { 4 | echo "$(basename "$0"): $*" >&2 5 | exit 1 6 | } 7 | 8 | # 9 | # Script for setting all the variables to run the ATH locally on Unix 10 | # Use config.groovy in the same folder if desired, uncomment below 11 | # 12 | 13 | #export CONFIG="${PWD}/config.groovy" 14 | export DISPLAY=:0 15 | export INTERACTIVE=false 16 | export BROWSER=remote-webdriver-firefox 17 | export REMOTE_WEBDRIVER_URL=http://127.0.0.1:4444/wd/hub 18 | export JENKINS_JAVA_OPTS=-Xmx1280m 19 | if [ -z "${JENKINS_WAR}" ] && [ -f /usr/share/java/jenkins.war ]; then 20 | export JENKINS_WAR=/usr/share/java/jenkins.war 21 | fi 22 | 23 | IP=$(ip addr show docker0 2>/dev/null | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1) || 24 | die "failed to retrieve IP address of Docker interface" 25 | export SELENIUM_PROXY_HOSTNAME="${IP}" 26 | export TESTCONTAINERS_HOST_OVERRIDE="${IP}" 27 | export JENKINS_LOCAL_HOSTNAME="${IP}" 28 | 29 | echo "To start the remote Firefox container, run the following command:" 30 | echo "docker run --shm-size=2g -d -p 127.0.0.1:4444:4444 -p 127.0.0.1:5900:5900 -e no_proxy=localhost -e SE_SCREEN_WIDTH=1680 -e SE_SCREEN_HEIGHT=1090 selenium/standalone-firefox:4.33.0" 31 | --------------------------------------------------------------------------------