Merge remote-tracking branch 'upstream/master' into update_traefik
commit
96e032a6c0
|
|
@ -34,9 +34,6 @@ wsmaster/che-core-api-workspace/** @skabashnyuk @mshaposhnik @metlos @nickboldt
|
|||
deploy/** @tolusha @nickboldt
|
||||
deploy/openshift/templates/monitoring/** @skabashnyuk @metlos @nickboldt
|
||||
|
||||
# selenium tests
|
||||
tests/legacy-e2e/** @musienko-maxim @dmytro-ndp @Ohrimenko1988 @rhopp @nickboldt
|
||||
|
||||
# e2e tests
|
||||
tests/e2e/** @musienko-maxim @Ohrimenko1988 @rhopp @nickboldt @Katka92 @ScrewTSW
|
||||
|
||||
|
|
|
|||
|
|
@ -1,72 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2020 Red Hat, Inc.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
set -ex
|
||||
|
||||
source tests/.infra/centos-ci/functional_tests_utils.sh
|
||||
|
||||
eval "$(./env-toolkit load -f jenkins-env.json -r ^ghprbPullId)"
|
||||
|
||||
export PULL_REQUEST_ID="${ghprbPullId}"
|
||||
export TAG=PR-${PULL_REQUEST_ID}
|
||||
|
||||
function prepareCustomResourcePatchFile() {
|
||||
cat > /tmp/custom-resource-patch.yaml <<EOL
|
||||
spec:
|
||||
server:
|
||||
cheImageTag: ${TAG}
|
||||
customCheProperties:
|
||||
CHE_LIMITS_USER_WORKSPACES_RUN_COUNT: '-1'
|
||||
CHE_WORKSPACE_AGENT_DEV_INACTIVE__STOP__TIMEOUT__MS: '300000'
|
||||
auth:
|
||||
updateAdminPassword: false
|
||||
openShiftoAuth: false
|
||||
identityProviderPassword: admin
|
||||
EOL
|
||||
|
||||
cat /tmp/custom-resource-patch.yaml
|
||||
}
|
||||
|
||||
function buildCheServer() {
|
||||
mvn clean install -Pintegration
|
||||
bash dockerfiles/che/build.sh --organization:quay.io/eclipse --tag:${TAG} --dockerfile:Dockerfile
|
||||
}
|
||||
|
||||
function pushImageToRegistry() {
|
||||
docker login -u "${QUAY_ECLIPSE_CHE_USERNAME}" -p "${QUAY_ECLIPSE_CHE_PASSWORD}" "quay.io"
|
||||
docker push "quay.io/eclipse/che-server:${TAG}"
|
||||
}
|
||||
|
||||
setupEnvs
|
||||
installDependencies
|
||||
installDockerCompose
|
||||
buildCheServer
|
||||
pushImageToRegistry
|
||||
installKVM
|
||||
installAndStartMinishift
|
||||
prepareCustomResourcePatchFile
|
||||
installCheCtl
|
||||
deployCheIntoCluster --che-operator-cr-patch-yaml=/tmp/custom-resource-patch.yaml
|
||||
seleniumTestsSetup
|
||||
createIndentityProvider
|
||||
|
||||
bash /root/payload/tests/legacy-e2e/che-selenium-test/selenium-tests.sh \
|
||||
--threads=3 \
|
||||
--host=${CHE_ROUTE} \
|
||||
--https \
|
||||
--port=443 \
|
||||
--multiuser \
|
||||
--fail-script-on-failed-tests \
|
||||
|| IS_TESTS_FAILED=true
|
||||
|
||||
|
||||
echo "=========================== THIS IS POST TEST ACTIONS =============================="
|
||||
saveSeleniumTestResult
|
||||
getOpenshiftLogs
|
||||
archiveArtifacts "che-pullrequests-java-selenium-tests"
|
||||
|
||||
if [[ "$IS_TESTS_FAILED" == "true" ]]; then exit 1; fi
|
||||
|
|
@ -385,50 +385,12 @@ function setupEnvs() {
|
|||
|
||||
}
|
||||
|
||||
function configureGithubTestUser() {
|
||||
echo "======== Configure GitHub test users ========"
|
||||
cd /root/payload
|
||||
mkdir -p che_local_conf_dir
|
||||
export CHE_LOCAL_CONF_DIR=/root/payload/che_local_conf_dir/
|
||||
rm -f che_local_conf_dir/selenium.properties
|
||||
echo "github.username=che6ocpmulti" >> che_local_conf_dir/selenium.properties
|
||||
echo "github.password=CheMain2017" >> che_local_conf_dir/selenium.properties
|
||||
echo "github.auxiliary.username=iedexmain1" >> che_local_conf_dir/selenium.properties
|
||||
echo "github.auxiliary.password=CodenvyMain15" >> che_local_conf_dir/selenium.properties
|
||||
}
|
||||
|
||||
function installDockerCompose() {
|
||||
echo "Install docker compose"
|
||||
sudo curl -L "https://github.com/docker/compose/releases/download/1.25.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
sudo chmod +x /usr/local/bin/docker-compose
|
||||
}
|
||||
|
||||
function seleniumTestsSetup() {
|
||||
echo "======== Start selenium tests ========"
|
||||
cd /root/payload
|
||||
|
||||
export CHE_INFRASTRUCTURE=openshift
|
||||
export CHE_OPENSHIFT_PROJECT=eclipse-che
|
||||
|
||||
defineCheRoute
|
||||
|
||||
mvn clean install -pl :che-selenium-test -am -DskipTests=true -U
|
||||
configureGithubTestUser
|
||||
}
|
||||
|
||||
function saveSeleniumTestResult() {
|
||||
mkdir -p /root/payload/report
|
||||
mkdir -p /root/payload/report/site
|
||||
cp -r /root/payload/tests/legacy-e2e/che-selenium-test/target/site report
|
||||
}
|
||||
|
||||
function createIndentityProvider() {
|
||||
CHE_MULTI_USER_GITHUB_CLIENTID_OCP=04cbc0f8172109322223
|
||||
CHE_MULTI_USER_GITHUB_SECRET_OCP=a0a9b8602bb0916d322223e71b7ed92036563b7a
|
||||
keycloakPodName=$(oc get pod --namespace=eclipse-che | grep keycloak | awk '{print $1}')
|
||||
/tmp/oc exec $keycloakPodName --namespace=eclipse-che -- /opt/jboss/keycloak/bin/kcadm.sh create identity-provider/instances -r che -s alias=github -s providerId=github -s enabled=true -s storeToken=true -s addReadTokenRoleOnCreate=true -s 'config.useJwksUrl="true"' -s config.clientId=$CHE_MULTI_USER_GITHUB_CLIENTID_OCP -s config.clientSecret=$CHE_MULTI_USER_GITHUB_SECRET_OCP -s 'config.defaultScope="repo,user,write:public_key"' --no-config --server http://localhost:8080/auth --user admin --password admin --realm master
|
||||
}
|
||||
|
||||
function runDevfileTestSuite() {
|
||||
defineCheRoute
|
||||
### Create directory for report
|
||||
|
|
|
|||
|
|
@ -1,58 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2018 Red Hat, Inc.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
set -e
|
||||
|
||||
echo "========Starting nigtly test job $(date)========"
|
||||
|
||||
source tests/.infra/centos-ci/functional_tests_utils.sh
|
||||
source .ci/cico_common.sh
|
||||
|
||||
function prepareCustomResourcePatchFile() {
|
||||
cat > /tmp/custom-resource-patch.yaml <<EOL
|
||||
spec:
|
||||
server:
|
||||
customCheProperties:
|
||||
CHE_LIMITS_USER_WORKSPACES_RUN_COUNT: '-1'
|
||||
CHE_WORKSPACE_AGENT_DEV_INACTIVE__STOP__TIMEOUT__MS: '300000'
|
||||
auth:
|
||||
updateAdminPassword: false
|
||||
openShiftoAuth: false
|
||||
identityProviderPassword: admin
|
||||
EOL
|
||||
|
||||
cat /tmp/custom-resource-patch.yaml
|
||||
}
|
||||
|
||||
installKVM
|
||||
setupEnvs
|
||||
installDependencies
|
||||
prepareCustomResourcePatchFile
|
||||
installCheCtl
|
||||
installAndStartMinishift
|
||||
deployCheIntoCluster --che-operator-cr-patch-yaml=/tmp/custom-resource-patch.yaml
|
||||
createTestUserAndObtainUserToken
|
||||
installDockerCompose
|
||||
seleniumTestsSetup
|
||||
createIndentityProvider
|
||||
|
||||
bash tests/legacy-e2e/che-selenium-test/selenium-tests.sh \
|
||||
--threads=3 \
|
||||
--host=${CHE_ROUTE} \
|
||||
--https \
|
||||
--port=443 \
|
||||
--multiuser \
|
||||
--include-tests-under-repair \
|
||||
--include-flaky-tests \
|
||||
--fail-script-on-failed-tests \
|
||||
|| IS_TESTS_FAILED=true
|
||||
|
||||
echo "=========================== THIS IS POST TEST ACTIONS =============================="
|
||||
saveSeleniumTestResult
|
||||
getOpenshiftLogs
|
||||
archiveArtifacts "che-nigthly-multiuser-all-test"
|
||||
|
||||
if [[ "$IS_TESTS_FAILED" == "true" ]]; then exit 1; fi
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2018 Red Hat, Inc.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
set -e
|
||||
|
||||
echo "========Starting nigtly test job $(date)========"
|
||||
|
||||
source tests/.infra/centos-ci/functional_tests_utils.sh
|
||||
|
||||
function prepareCustomResourcePatchFile() {
|
||||
cat > /tmp/custom-resource-patch.yaml <<EOL
|
||||
spec:
|
||||
server:
|
||||
customCheProperties:
|
||||
CHE_LIMITS_USER_WORKSPACES_RUN_COUNT: '-1'
|
||||
auth:
|
||||
updateAdminPassword: false
|
||||
openShiftoAuth: false
|
||||
identityProviderPassword: admin
|
||||
EOL
|
||||
|
||||
cat /tmp/custom-resource-patch.yaml
|
||||
}
|
||||
|
||||
setupEnvs
|
||||
installKVM
|
||||
installDependencies
|
||||
installDockerCompose
|
||||
installAndStartMinishift
|
||||
installCheCtl
|
||||
prepareCustomResourcePatchFile
|
||||
deployCheIntoCluster --che-operator-cr-patch-yaml=/tmp/custom-resource-patch.yaml
|
||||
seleniumTestsSetup
|
||||
|
||||
bash tests/legacy-e2e/che-selenium-test/selenium-tests.sh \
|
||||
--host=${CHE_ROUTE} \
|
||||
--https \
|
||||
--port=443 \
|
||||
--multiuser \
|
||||
--threads=1 \
|
||||
--fail-script-on-failed-tests \
|
||||
--test=org.eclipse.che.selenium.hotupdate.rolling.** \
|
||||
|| IS_TESTS_FAILED=true
|
||||
|
||||
echo "=========================== THIS IS POST TEST ACTIONS =============================="
|
||||
saveSeleniumTestResult
|
||||
getOpenshiftLogs
|
||||
archiveArtifacts "cico-nightly-hot-update-test"
|
||||
|
||||
if [[ "$IS_TESTS_FAILED" == "true" ]]; then exit 1; fi
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2018 Red Hat, Inc.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
set -x
|
||||
|
||||
echo "========Starting nigtly test job $(date)========"
|
||||
./tests/.infra/centos-ci/nightly/
|
||||
source tests/.infra/centos-ci/functional_tests_utils.sh
|
||||
|
||||
function prepareCustomResourcePatchFile() {
|
||||
cat > /tmp/custom-resource-patch.yaml <<EOL
|
||||
spec:
|
||||
server:
|
||||
customCheProperties:
|
||||
CHE_LIMITS_USER_WORKSPACES_RUN_COUNT: '-1'
|
||||
CHE_WORKSPACE_AGENT_DEV_INACTIVE__STOP__TIMEOUT__MS: '300000'
|
||||
auth:
|
||||
updateAdminPassword: false
|
||||
openShiftoAuth: false
|
||||
identityProviderPassword: admin
|
||||
EOL
|
||||
|
||||
cat /tmp/custom-resource-patch.yaml
|
||||
}
|
||||
|
||||
setupEnvs
|
||||
installKVM
|
||||
installDependencies
|
||||
installCheCtl
|
||||
installAndStartMinishift
|
||||
prepareCustomResourcePatchFile
|
||||
deployCheIntoCluster --che-operator-cr-patch-yaml=/tmp/custom-resource-patch.yaml
|
||||
createTestUserAndObtainUserToken
|
||||
installDockerCompose
|
||||
seleniumTestsSetup
|
||||
createIndentityProvider
|
||||
bash tests/legacy-e2e/che-selenium-test/selenium-tests.sh \
|
||||
--threads=3 \
|
||||
--host=${CHE_ROUTE} \
|
||||
--https \
|
||||
--port=443 \
|
||||
--multiuser \
|
||||
--fail-script-on-failed-tests \
|
||||
|| IS_TESTS_FAILED=true
|
||||
|
||||
echo "=========================== THIS IS POST TEST ACTIONS =============================="
|
||||
saveSeleniumTestResult
|
||||
getOpenshiftLogs
|
||||
archiveArtifacts "che-nigthly-multiuser-stable-test"
|
||||
|
||||
if [[ "$IS_TESTS_FAILED" == "true" ]]; then exit 1; fi
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2020 Red Hat, Inc.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
set -e
|
||||
set +x
|
||||
source tests/.infra/centos-ci/functional_tests_utils.sh
|
||||
|
||||
function prepareCustomResourcePatchFile() {
|
||||
cat > /tmp/custom-resource-patch.yaml <<EOL
|
||||
spec:
|
||||
server:
|
||||
customCheProperties:
|
||||
CHE_LIMITS_USER_WORKSPACES_RUN_COUNT: '-1'
|
||||
CHE_WORKSPACE_AGENT_DEV_INACTIVE__STOP__TIMEOUT__MS: '180000'
|
||||
auth:
|
||||
openShiftoAuth: true
|
||||
updateAdminPassword: false
|
||||
identityProviderPassword: admin
|
||||
EOL
|
||||
|
||||
cat /tmp/custom-resource-patch.yaml
|
||||
}
|
||||
|
||||
setupEnvs
|
||||
installKVM
|
||||
installDependencies
|
||||
installDockerCompose
|
||||
installAndStartMinishift
|
||||
prepareCustomResourcePatchFile
|
||||
installCheCtl
|
||||
deployCheIntoCluster --che-operator-cr-patch-yaml=/tmp/custom-resource-patch.yaml
|
||||
seleniumTestsSetup
|
||||
|
||||
export OPENSHIFT_USERNAME=developer
|
||||
export OPENSHIFT_PASSWORD=123
|
||||
export OPENSHIFT_REGULAR_USERNAME=developer
|
||||
export OPENSHIFT_REGULAR_PASSWORD=123
|
||||
export OPENSHIFT_REGULAR_EMAIL=${OPENSHIFT_REGULAR_USERNAME}@1.com
|
||||
|
||||
export TEST_USER_NAME=admin
|
||||
export CHE_TESTUSER_NAME=${TEST_USER_NAME}
|
||||
export CHE_TESTUSER_PASSWORD=admin
|
||||
export CHE_TESTUSER_EMAIL=${TEST_USER_NAME}@admin.com
|
||||
|
||||
bash tests/legacy-e2e/che-selenium-test/selenium-tests.sh \
|
||||
--threads=3 \
|
||||
--host=${CHE_ROUTE} \
|
||||
--https \
|
||||
--port=443 \
|
||||
--multiuser \
|
||||
--fail-script-on-failed-tests \
|
||||
|| IS_TESTS_FAILED=true
|
||||
|
||||
echo "=========================== THIS IS POST TEST ACTIONS =============================="
|
||||
saveSeleniumTestResult
|
||||
getOpenshiftLogs
|
||||
archiveArtifacts "nightly-ocp-oauth-test"
|
||||
|
||||
if [[ "$IS_TESTS_FAILED" == "true" ]]; then exit 1; fi
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2018 Red Hat, Inc.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
set -x
|
||||
|
||||
source tests/.infra/centos-ci/functional_tests_utils.sh
|
||||
source tests/.infra/centos-ci/release/release_function_util.sh
|
||||
|
||||
setupEnvs
|
||||
installKVM
|
||||
installDependencies
|
||||
installAndStartMinishift
|
||||
prepareCustomResourcePatchFile false
|
||||
installCheCtl stable
|
||||
deployCheIntoCluster --che-operator-cr-patch-yaml=/tmp/custom-resource-patch.yaml
|
||||
runDevfileTestSuite
|
||||
echo "=========================== THIS IS POST TEST ACTIONS =============================="
|
||||
getOpenshiftLogs
|
||||
archiveArtifacts "release-devfile-test"
|
||||
if [[ "$IS_TESTS_FAILED" == "true" ]]; then exit 1; fi
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2020 Red Hat, Inc.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
set -e
|
||||
set +x
|
||||
|
||||
source tests/.infra/centos-ci/functional_tests_utils.sh
|
||||
source tests/.infra/centos-ci/release/release_function_util.sh
|
||||
|
||||
# It needs to implement the patch of 'devfile' yaml to appropriate release tags images
|
||||
|
||||
setupEnvs
|
||||
installKVM
|
||||
installDependencies
|
||||
installAndStartMinishift
|
||||
prepareCustomResourcePatchFile false
|
||||
installCheCtl stable
|
||||
deployCheIntoCluster --che-operator-cr-patch-yaml=/tmp/custom-resource-patch.yaml
|
||||
createTestUserAndObtainUserToken
|
||||
createTestWorkspaceAndRunTest --devfile=https://raw.githubusercontent.com/eclipse/che/cico-release-test/tests/e2e/files/happy-path/happy-path-workspace.yaml
|
||||
getOpenshiftLogs
|
||||
archiveArtifacts "release-multiuser-happy-path-test"
|
||||
if [[ "$IS_TESTS_FAILED" == "true" ]]; then exit 1; fi
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2020 Red Hat, Inc.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
set -e
|
||||
set +x
|
||||
|
||||
source tests/.infra/centos-ci/functional_tests_utils.sh
|
||||
source tests/.infra/centos-ci/release/release_function_util.sh
|
||||
|
||||
setupEnvs
|
||||
installDependencies
|
||||
installDockerCompose
|
||||
installKVM
|
||||
installAndStartMinishift
|
||||
prepareCustomResourcePatchFile false
|
||||
installCheCtl stable
|
||||
deployCheIntoCluster --che-operator-cr-patch-yaml=/tmp/custom-resource-patch.yaml
|
||||
createIndentityProvider
|
||||
seleniumTestsSetup
|
||||
|
||||
bash /root/payload/tests/legacy-e2e/che-selenium-test/selenium-tests.sh \
|
||||
--threads=3 \
|
||||
--host=${CHE_ROUTE} \
|
||||
--https \
|
||||
--port=443 \
|
||||
--multiuser \
|
||||
--fail-script-on-failed-tests \
|
||||
|| IS_TESTS_FAILED=true
|
||||
|
||||
|
||||
echo "=========================== THIS IS POST TEST ACTIONS =============================="
|
||||
saveSeleniumTestResult
|
||||
getOpenshiftLogs
|
||||
archiveArtifacts "release-multiuser-integration-tests"
|
||||
if [[ "$IS_TESTS_FAILED" == "true" ]]; then exit 1; fi
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2020 Red Hat, Inc.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
set -e
|
||||
set +x
|
||||
|
||||
source tests/.infra/centos-ci/functional_tests_utils.sh
|
||||
source tests/.infra/centos-ci/release/release_function_util.sh
|
||||
|
||||
setupEnvs
|
||||
installDependencies
|
||||
installDockerCompose
|
||||
installKVM
|
||||
installAndStartMinishift
|
||||
prepareCustomResourcePatchFile true
|
||||
installCheCtl stable
|
||||
deployCheIntoCluster --che-operator-cr-patch-yaml=/tmp/custom-resource-patch.yaml
|
||||
seleniumTestsSetup
|
||||
|
||||
bash tests/legacy-e2e/che-selenium-test/selenium-tests.sh \
|
||||
--threads=1 \
|
||||
--host=${CHE_ROUTE} \
|
||||
--https \
|
||||
--port=443 \
|
||||
--multiuser \
|
||||
--test=org.eclipse.che.selenium.site.ocpoauth.** \
|
||||
--fail-script-on-failed-tests \
|
||||
|| IS_TESTS_FAILED=true
|
||||
|
||||
echo "=========================== THIS IS POST TEST ACTIONS =============================="
|
||||
saveSeleniumTestResult
|
||||
getOpenshiftLogs
|
||||
archiveArtifacts "release-ocp-oauth-test"
|
||||
if [[ "$IS_TESTS_FAILED" == "true" ]]; then exit 1; fi
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2020 Red Hat, Inc.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
set -e
|
||||
set +x
|
||||
|
||||
source tests/.infra/centos-ci/functional_tests_utils.sh
|
||||
source tests/.infra/centos-ci/release/release_function_util.sh
|
||||
|
||||
setupEnvs
|
||||
installDependencies
|
||||
installDockerCompose
|
||||
installKVM
|
||||
installAndStartMinishift
|
||||
prepareCustomResourcePatchFile false
|
||||
installCheCtl stable
|
||||
deployCheIntoCluster --che-operator-cr-patch-yaml=/tmp/custom-resource-patch.yaml
|
||||
seleniumTestsSetup
|
||||
|
||||
bash tests/legacy-e2e/che-selenium-test/selenium-tests.sh \
|
||||
--threads=1 \
|
||||
--host=${CHE_ROUTE} \
|
||||
--https \
|
||||
--port=443 \
|
||||
--multiuser \
|
||||
--test=org.eclipse.che.selenium.hotupdate.rolling.** \
|
||||
--fail-script-on-failed-tests \
|
||||
|| IS_TESTS_FAILED=true
|
||||
|
||||
echo "=========================== THIS IS POST TEST ACTIONS =============================="
|
||||
saveSeleniumTestResult
|
||||
getOpenshiftLogs
|
||||
archiveArtifacts "release-rolling-strategy-test"
|
||||
if [[ "$IS_TESTS_FAILED" == "true" ]]; then exit 1; fi
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2020 Red Hat, Inc.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
function prepareCustomResourcePatchFile() {
|
||||
cat > /tmp/custom-resource-patch.yaml <<EOL
|
||||
spec:
|
||||
server:
|
||||
customCheProperties:
|
||||
CHE_LIMITS_USER_WORKSPACES_RUN_COUNT: '-1'
|
||||
CHE_WORKSPACE_AGENT_DEV_INACTIVE__STOP__TIMEOUT__MS: '300000'
|
||||
auth:
|
||||
openShiftoAuth: $1
|
||||
updateAdminPassword: false
|
||||
identityProviderPassword: admin
|
||||
EOL
|
||||
|
||||
cat /tmp/custom-resource-patch.yaml
|
||||
}
|
||||
|
||||
|
|
@ -6,6 +6,7 @@ export * from './TimeoutConstants';
|
|||
|
||||
export * from './driver/ChromeDriver';
|
||||
export * from './driver/IDriver';
|
||||
export * from './utils/BrowserTabsUtil';
|
||||
export * from './utils/DriverHelper';
|
||||
export * from './utils/Logger';
|
||||
export * from './utils/PreferencesHandler';
|
||||
|
|
@ -22,8 +23,8 @@ export * from './utils/workspace/ITestWorkspaceUtil';
|
|||
export * from './utils/WorkspaceNameHandler';
|
||||
export * from './utils/workspace/TestWorkspaceUtil';
|
||||
export * from './utils/workspace/WorkspaceStatus';
|
||||
export * from './pageobjects/dashboard/CreateWorkspace';
|
||||
export * from './pageobjects/dashboard/Dashboard';
|
||||
export * from './pageobjects/dashboard/GetStarted';
|
||||
export * from './pageobjects/dashboard/workspace-details/WorkspaceDetailsPlugins';
|
||||
export * from './pageobjects/dashboard/workspace-details/WorkspaceDetails';
|
||||
export * from './pageobjects/dashboard/Workspaces';
|
||||
|
|
@ -57,4 +58,4 @@ export * from './pageobjects/openshift/OcpLoginPage';
|
|||
export * from './testsLibrary/CodeExecutionTests';
|
||||
export * from './testsLibrary/LsTests';
|
||||
export * from './testsLibrary/ProjectAndFileTests';
|
||||
export * from './testsLibrary/WorksapceHandlingTests';
|
||||
export * from './testsLibrary/WorkspaceHandlingTests';
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ import { ITokenHandler } from './utils/requestHandlers/tokens/ITokenHandler';
|
|||
import { CheApiRequestHandler } from './utils/requestHandlers/CheApiRequestHandler';
|
||||
import { CheGitApi } from './utils/VCS/CheGitApi';
|
||||
import { GitHubUtil } from './utils/VCS/github/GitHubUtil';
|
||||
import { GetStarted } from './pageobjects/dashboard/GetStarted';
|
||||
import { CreateWorkspace } from './pageobjects/dashboard/CreateWorkspace';
|
||||
import { OpenshiftPlugin } from './pageobjects/ide/OpenshiftPlugin';
|
||||
import { OpenDialogWidget } from './pageobjects/ide/OpenDialogWidget';
|
||||
import { UpdateAccountInformationPage } from './pageobjects/login/UpdateAccountInformationPage';
|
||||
|
|
@ -111,7 +111,7 @@ e2eContainer.bind<CheApiRequestHandler>(CLASSES.CheApiRequestHandler).to(CheApiR
|
|||
e2eContainer.bind<CheGitApi>(CLASSES.CheGitApi).to(CheGitApi);
|
||||
e2eContainer.bind<GitHubUtil>(CLASSES.GitHubUtil).to(GitHubUtil);
|
||||
e2eContainer.bind<OpenshiftPlugin>(CLASSES.OpenshiftPlugin).to(OpenshiftPlugin);
|
||||
e2eContainer.bind<GetStarted>(CLASSES.GetStarted).to(GetStarted);
|
||||
e2eContainer.bind<CreateWorkspace>(CLASSES.CreateWorkspace).to(CreateWorkspace);
|
||||
e2eContainer.bind<OpenDialogWidget>(CLASSES.OpenDialogWidget).to(OpenDialogWidget);
|
||||
e2eContainer.bind<UpdateAccountInformationPage>(CLASSES.UpdateAccountInformationPage).to(UpdateAccountInformationPage);
|
||||
e2eContainer.bind<KubernetesPlugin>(CLASSES.KubernetesPlugin).to(KubernetesPlugin);
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ const CLASSES = {
|
|||
NotificationCenter: 'NotificationCenter',
|
||||
PreferencesHandler: 'PreferencesHandler',
|
||||
CheApiRequestHandler: 'CheApiRequestHandler',
|
||||
GetStarted: 'GetStarted',
|
||||
CreateWorkspace: 'CreateWorkspace',
|
||||
OpenDialogWidget: 'OpenDialogWidget',
|
||||
UpdateAccountInformationPage: 'UpdateAccountInformationPage',
|
||||
KubernetesPlugin: 'KubernetesPlugin',
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@ import { Logger } from '../../utils/Logger';
|
|||
import { TimeoutConstants } from '../../TimeoutConstants';
|
||||
|
||||
@injectable()
|
||||
export class GetStarted {
|
||||
export class CreateWorkspace {
|
||||
constructor(@inject(CLASSES.DriverHelper) private readonly driverHelper: DriverHelper) { }
|
||||
|
||||
async waitTitleContains(expectedText: string, timeout: number = TimeoutConstants.TS_COMMON_DASHBOARD_WAIT_TIMEOUT) {
|
||||
Logger.debug(`GetStarted.waitTitleContains text: "${expectedText}"`);
|
||||
Logger.debug(`CreateWorkspace.waitTitleContains text: "${expectedText}"`);
|
||||
|
||||
const pageTitleLocator: By = By.xpath(`//h1[contains(text(), '${expectedText}')]`);
|
||||
|
||||
|
|
@ -28,13 +28,13 @@ export class GetStarted {
|
|||
}
|
||||
|
||||
async waitPage(timeout: number = TimeoutConstants.TS_SELENIUM_LOAD_PAGE_TIMEOUT) {
|
||||
Logger.debug('GetStarted.waitPage');
|
||||
Logger.debug('CreateWorkspace.waitPage');
|
||||
|
||||
await this.waitTitleContains('Getting Started', timeout);
|
||||
}
|
||||
|
||||
async waitSample(sampleName: string, timeout: number = TimeoutConstants.TS_COMMON_DASHBOARD_WAIT_TIMEOUT) {
|
||||
Logger.debug(`GetStarted.waitSample sampleName: "${sampleName}"`);
|
||||
Logger.debug(`CreateWorkspace.waitSample sampleName: "${sampleName}"`);
|
||||
|
||||
const sampleLocator: By = this.getSampleLocator(sampleName);
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ export class GetStarted {
|
|||
}
|
||||
|
||||
async clickOnSample(sampleName: string, timeout: number = TimeoutConstants.TS_CLICK_DASHBOARD_ITEM_TIMEOUT) {
|
||||
Logger.debug(`GetStarted.clickOnSample sampleName: "${sampleName}"`);
|
||||
Logger.debug(`CreateWorkspace.clickOnSample sampleName: "${sampleName}"`);
|
||||
|
||||
const sampleLocator: By = this.getSampleLocator(sampleName);
|
||||
|
||||
|
|
@ -50,7 +50,7 @@ export class GetStarted {
|
|||
}
|
||||
|
||||
private getSampleLocator(sampleName: string): By {
|
||||
Logger.trace(`GetStarted.getSampleLocator sampleName: ${sampleName}`);
|
||||
Logger.trace(`CreateWorkspace.getSampleLocator sampleName: ${sampleName}`);
|
||||
|
||||
return By.xpath(`//article[contains(@class, 'sample-card')]//div[text()='${sampleName}']`);
|
||||
}
|
||||
|
|
@ -19,8 +19,7 @@ import { Logger } from '../../utils/Logger';
|
|||
|
||||
@injectable()
|
||||
export class Dashboard {
|
||||
private static readonly WORKSPACES_BUTTON_XPATH: string = `//div[@id='page-sidebar']//a[text()='Workspaces']`;
|
||||
private static readonly GET_STARTED_BUTTON_XPATH: string = `//div[@id='page-sidebar']//a[text()='Get Started']`;
|
||||
private static readonly WORKSPACES_BUTTON_XPATH: string = `//div[@id='page-sidebar']//a[contains(text(), 'Workspaces (')]`;
|
||||
private static readonly CREATE_WORKSPACE_BUTTON_XPATH: string = `//div[@id='page-sidebar']//a[text()='Create Workspace']`;
|
||||
private static readonly LOADER_PAGE_CSS: string = '.main-page-loader';
|
||||
|
||||
|
|
@ -79,7 +78,6 @@ export class Dashboard {
|
|||
Logger.debug('Dashboard.waitPage');
|
||||
|
||||
await this.driverHelper.waitVisibility(By.xpath(Dashboard.WORKSPACES_BUTTON_XPATH), timeout);
|
||||
await this.driverHelper.waitVisibility(By.xpath(Dashboard.GET_STARTED_BUTTON_XPATH), timeout);
|
||||
await this.driverHelper.waitVisibility(By.xpath(Dashboard.CREATE_WORKSPACE_BUTTON_XPATH), timeout);
|
||||
}
|
||||
|
||||
|
|
@ -95,12 +93,6 @@ export class Dashboard {
|
|||
await this.driverHelper.waitAndClick(By.xpath(Dashboard.CREATE_WORKSPACE_BUTTON_XPATH), timeout);
|
||||
}
|
||||
|
||||
async clickGetStartedButton(timeout: number = TimeoutConstants.TS_CLICK_DASHBOARD_ITEM_TIMEOUT) {
|
||||
Logger.debug('Dashboard.clickGetStartedButton');
|
||||
|
||||
await this.driverHelper.waitAndClick(By.xpath(Dashboard.GET_STARTED_BUTTON_XPATH), timeout);
|
||||
}
|
||||
|
||||
async waitLoader(timeout: number = TimeoutConstants.TS_WAIT_LOADER_PRESENCE_TIMEOUT) {
|
||||
Logger.debug('Dashboard.waitLoader');
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
**********************************************************************/
|
||||
import 'reflect-metadata';
|
||||
import * as projectAndFileTests from '../../testsLibrary/ProjectAndFileTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorksapceHandlingTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorkspaceHandlingTests';
|
||||
import * as commonLsTests from '../../testsLibrary/LsTests';
|
||||
import * as codeExecutionTests from '../../testsLibrary/CodeExecutionTests';
|
||||
import { e2eContainer } from '../../inversify.config';
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
import 'reflect-metadata';
|
||||
import { WorkspaceNameHandler} from '../..';
|
||||
import * as projectAndFileTests from '../../testsLibrary/ProjectAndFileTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorksapceHandlingTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorkspaceHandlingTests';
|
||||
|
||||
const workspaceSampleName: string = 'console-java-simple';
|
||||
const workspaceRootFolderName: string = 'src';
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { WorkspaceNameHandler, Editor, CLASSES } from '../..';
|
|||
import { e2eContainer } from '../../inversify.config';
|
||||
import * as projectAndFileTests from '../../testsLibrary/ProjectAndFileTests';
|
||||
import * as commonLsTests from '../../testsLibrary/LsTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorksapceHandlingTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorkspaceHandlingTests';
|
||||
import * as codeExecutionTests from '../../testsLibrary/CodeExecutionTests';
|
||||
|
||||
const editor: Editor = e2eContainer.get(CLASSES.Editor);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import 'reflect-metadata';
|
|||
import * as codeExecutionHelper from '../../testsLibrary/CodeExecutionTests';
|
||||
import * as commonLsTests from '../../testsLibrary/LsTests';
|
||||
import * as projectManager from '../../testsLibrary/ProjectAndFileTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorksapceHandlingTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorkspaceHandlingTests';
|
||||
import { Logger } from '../../utils/Logger';
|
||||
import { PreferencesHandler } from '../../utils/PreferencesHandler';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import 'reflect-metadata';
|
|||
import { WorkspaceNameHandler} from '../..';
|
||||
import * as projectAndFileTests from '../../testsLibrary/ProjectAndFileTests';
|
||||
import * as commonLsTests from '../../testsLibrary/LsTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorksapceHandlingTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorkspaceHandlingTests';
|
||||
import * as codeExecutionTests from '../../testsLibrary/CodeExecutionTests';
|
||||
|
||||
const workspaceSampleName: string = 'console-java-simple';
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import 'reflect-metadata';
|
|||
import { WorkspaceNameHandler } from '../..';
|
||||
import * as projectAndFileTests from '../../testsLibrary/ProjectAndFileTests';
|
||||
import * as commonLsTests from '../../testsLibrary/LsTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorksapceHandlingTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorkspaceHandlingTests';
|
||||
import * as codeExecutionTests from '../../testsLibrary/CodeExecutionTests';
|
||||
|
||||
const stack: string = 'Java Spring Boot';
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
**********************************************************************/
|
||||
import 'reflect-metadata';
|
||||
import * as projectAndFileTests from '../../testsLibrary/ProjectAndFileTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorksapceHandlingTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorkspaceHandlingTests';
|
||||
import * as commonLsTests from '../../testsLibrary/LsTests';
|
||||
import * as codeExecutionTests from '../../testsLibrary/CodeExecutionTests';
|
||||
import { WorkspaceNameHandler } from '../..';
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import 'reflect-metadata';
|
|||
import * as codeExecutionHelper from '../../testsLibrary/CodeExecutionTests';
|
||||
import * as commonLsTests from '../../testsLibrary/LsTests';
|
||||
import * as projectManager from '../../testsLibrary/ProjectAndFileTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorksapceHandlingTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorkspaceHandlingTests';
|
||||
|
||||
const workspaceStack: string = 'NodeJS Express Web Application';
|
||||
const workspaceSampleName: string = 'nodejs-web-app';
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
**********************************************************************/
|
||||
import 'reflect-metadata';
|
||||
import * as projectAndFileTests from '../../testsLibrary/ProjectAndFileTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorksapceHandlingTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorkspaceHandlingTests';
|
||||
import * as commonLsTests from '../../testsLibrary/LsTests';
|
||||
import * as codeExecutionTests from '../../testsLibrary/CodeExecutionTests';
|
||||
import { e2eContainer } from '../../inversify.config';
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import * as codeExecutionHelper from '../../testsLibrary/CodeExecutionTests';
|
|||
import * as projectManager from '../../testsLibrary/ProjectAndFileTests';
|
||||
import * as commonLsTests from '../../testsLibrary/LsTests';
|
||||
import * as projectAndFileTests from '../../testsLibrary/ProjectAndFileTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorksapceHandlingTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorkspaceHandlingTests';
|
||||
|
||||
const workspaceStack: string = 'Python';
|
||||
const workspaceSampleName: string = 'python-hello-world';
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
import { WorkspaceNameHandler } from '../..';
|
||||
import 'reflect-metadata';
|
||||
import * as codeExecutionHelper from '../../testsLibrary/CodeExecutionTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorksapceHandlingTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorkspaceHandlingTests';
|
||||
import * as projectManager from '../../testsLibrary/ProjectAndFileTests';
|
||||
|
||||
const workspaceStack: string = 'Python Django';
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { WorkspaceNameHandler } from '../..';
|
|||
import 'reflect-metadata';
|
||||
import * as codeExecutionHelper from '../../testsLibrary/CodeExecutionTests';
|
||||
import * as commonLsTests from '../../testsLibrary/LsTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorksapceHandlingTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorkspaceHandlingTests';
|
||||
import * as projectManager from '../../testsLibrary/ProjectAndFileTests';
|
||||
|
||||
const workspaceStack: string = 'Quarkus CLI';
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
**********************************************************************/
|
||||
import 'reflect-metadata';
|
||||
import * as projectAndFileTests from '../../testsLibrary/ProjectAndFileTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorksapceHandlingTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorkspaceHandlingTests';
|
||||
import * as commonLsTests from '../../testsLibrary/LsTests';
|
||||
import * as codeExecutionTests from '../../testsLibrary/CodeExecutionTests';
|
||||
import { WorkspaceNameHandler } from '../..';
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { CLASSES } from '../../inversify.types';
|
|||
import { TestConstants } from '../../TestConstants';
|
||||
import { DriverHelper } from '../../utils/DriverHelper';
|
||||
import { WorkspaceNameHandler } from '../..';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorksapceHandlingTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorkspaceHandlingTests';
|
||||
import * as projectAndFileTests from '../../testsLibrary/ProjectAndFileTests';
|
||||
|
||||
const driverHelper: DriverHelper = e2eContainer.get(CLASSES.DriverHelper);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { CLASSES } from '../../inversify.types';
|
|||
import { TestConstants } from '../../TestConstants';
|
||||
import { DriverHelper } from '../../utils/DriverHelper';
|
||||
import { WorkspaceNameHandler } from '../..';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorksapceHandlingTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorkspaceHandlingTests';
|
||||
import * as projectAndFileTests from '../../testsLibrary/ProjectAndFileTests';
|
||||
|
||||
const driverHelper: DriverHelper = e2eContainer.get(CLASSES.DriverHelper);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { CLASSES } from '../../inversify.types';
|
|||
import { TestConstants } from '../../TestConstants';
|
||||
import { DriverHelper } from '../../utils/DriverHelper';
|
||||
import { WorkspaceNameHandler } from '../..';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorksapceHandlingTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorkspaceHandlingTests';
|
||||
import * as projectAndFileTests from '../../testsLibrary/ProjectAndFileTests';
|
||||
|
||||
const driverHelper: DriverHelper = e2eContainer.get(CLASSES.DriverHelper);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { CLASSES } from '../../inversify.types';
|
|||
import { TestConstants } from '../../TestConstants';
|
||||
import { DriverHelper } from '../../utils/DriverHelper';
|
||||
import { WorkspaceNameHandler } from '../..';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorksapceHandlingTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorkspaceHandlingTests';
|
||||
import * as projectAndFileTests from '../../testsLibrary/ProjectAndFileTests';
|
||||
|
||||
const driverHelper: DriverHelper = e2eContainer.get(CLASSES.DriverHelper);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
**********************************************************************/
|
||||
import { WorkspaceNameHandler } from '../..';
|
||||
import 'reflect-metadata';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorksapceHandlingTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorkspaceHandlingTests';
|
||||
import { DriverHelper } from '../../utils/DriverHelper';
|
||||
import { e2eContainer } from '../../inversify.config';
|
||||
import { CLASSES } from '../../inversify.types';
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
**********************************************************************/
|
||||
import { WorkspaceNameHandler } from '../..';
|
||||
import 'reflect-metadata';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorksapceHandlingTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorkspaceHandlingTests';
|
||||
import { DriverHelper } from '../../utils/DriverHelper';
|
||||
import { e2eContainer } from '../../inversify.config';
|
||||
import { CLASSES } from '../../inversify.types';
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
**********************************************************************/
|
||||
import { WorkspaceNameHandler } from '../..';
|
||||
import 'reflect-metadata';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorksapceHandlingTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorkspaceHandlingTests';
|
||||
import { DriverHelper } from '../../utils/DriverHelper';
|
||||
import { e2eContainer } from '../../inversify.config';
|
||||
import { CLASSES } from '../../inversify.types';
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
**********************************************************************/
|
||||
import { WorkspaceNameHandler } from '../..';
|
||||
import 'reflect-metadata';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorksapceHandlingTests';
|
||||
import * as workspaceHandling from '../../testsLibrary/WorkspaceHandlingTests';
|
||||
import { DriverHelper } from '../../utils/DriverHelper';
|
||||
import { e2eContainer } from '../../inversify.config';
|
||||
import { CLASSES } from '../../inversify.types';
|
||||
|
|
|
|||
|
|
@ -10,22 +10,22 @@
|
|||
|
||||
import { CLASSES, Dashboard } from '..';
|
||||
import { e2eContainer } from '../inversify.config';
|
||||
import { GetStarted } from '../pageobjects/dashboard/GetStarted';
|
||||
import { CreateWorkspace as CreateWorkspace } from '../pageobjects/dashboard/CreateWorkspace';
|
||||
import { Logger } from '../utils/Logger';
|
||||
|
||||
const dashboard: Dashboard = e2eContainer.get(CLASSES.Dashboard);
|
||||
const getStarted: GetStarted = e2eContainer.get(CLASSES.GetStarted);
|
||||
const createWorkspace: CreateWorkspace = e2eContainer.get(CLASSES.CreateWorkspace);
|
||||
|
||||
export function createAndOpenWorkspace(stack: string) {
|
||||
test(`Open 'New Workspace' page`, async () => {
|
||||
Logger.trace(`WorkspaceHandlingTests.createAndOpenWorkspace wait for dashboard`);
|
||||
await dashboard.waitPage();
|
||||
Logger.trace(`WorkspaceHandlingTests.createAndOpenWorkspace click get started button`);
|
||||
await dashboard.clickGetStartedButton();
|
||||
Logger.trace(`WorkspaceHandlingTests.createAndOpenWorkspace click Create workspace button`);
|
||||
await dashboard.clickCreateWorkspaceButton();
|
||||
Logger.trace(`WorkspaceHandlingTests.createAndOpenWorkspace wait for getting started page`);
|
||||
await getStarted.waitPage();
|
||||
await createWorkspace.waitPage();
|
||||
Logger.trace(`WorkspaceHandlingTests.createAndOpenWorkspace click on sample ${stack}`);
|
||||
await getStarted.clickOnSample(stack);
|
||||
await createWorkspace.clickOnSample(stack);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -1,995 +0,0 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
# This program and the accompanying materials are made
|
||||
# available under the terms of the Eclipse Public License 2.0
|
||||
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
#
|
||||
# SPDX-License-Identifier: EPL-2.0
|
||||
#
|
||||
# Contributors:
|
||||
# Red Hat, Inc. - initial API and implementation
|
||||
#
|
||||
|
||||
getRecommendedThreadCount() {
|
||||
local threadCount=$MIN_THREAD_COUNT
|
||||
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
local totalMemory=$(sysctl -a | awk '/hw./' | grep hw.memsize | awk '{print $2}')
|
||||
if [[ -n "$totalNumber" ]]; then
|
||||
threadCount=$(( ${totalMemory} / 6000000 ))
|
||||
fi
|
||||
else
|
||||
local freeMemory=$(grep MemFree /proc/meminfo | awk '{print $2}')
|
||||
if [[ -n "$freeMemory" ]]; then
|
||||
threadCount=$(( ${freeMemory} / 4000000 ))
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $threadCount < ${MIN_THREAD_COUNT} ]]; then
|
||||
threadCount=${MIN_THREAD_COUNT}
|
||||
|
||||
elif [[ $threadCount > ${MAX_THREAD_COUNT} ]]; then
|
||||
threadCount=${MAX_THREAD_COUNT}
|
||||
fi
|
||||
|
||||
echo $threadCount
|
||||
}
|
||||
|
||||
detectDockerInterfaceIp() {
|
||||
docker run --rm --net host eclipse/che-ip:6.19.0
|
||||
}
|
||||
|
||||
initVariables() {
|
||||
# we need to have at least 2 threads for tests which start several WebDriver instances at once, for example, tests of File Watcher
|
||||
readonly MIN_THREAD_COUNT=2
|
||||
# having more than 5 threads doesn't impact on performance significantly
|
||||
readonly MAX_THREAD_COUNT=5
|
||||
|
||||
readonly FAILSAFE_DIR="target/failsafe-reports"
|
||||
readonly TESTNG_FAILED_SUITE=${FAILSAFE_DIR}"/testng-failed.xml"
|
||||
readonly FAILSAFE_REPORT="target/site/failsafe-report.html"
|
||||
|
||||
readonly SINGLE_TEST_MSG="single test/package"
|
||||
|
||||
export CHE_MULTIUSER=${CHE_MULTIUSER:-false}
|
||||
export CHE_INFRASTRUCTURE=${CHE_INFRASTRUCTURE:-docker}
|
||||
|
||||
# CALLER variable contains parent caller script name
|
||||
# CUR_DIR variable contains the current directory where CALLER is executed
|
||||
[[ -z ${CALLER+x} ]] && { CALLER=$(basename $0); }
|
||||
[[ -z ${CUR_DIR+x} ]] && { CUR_DIR=$(cd "$(dirname "$0")"; pwd); }
|
||||
|
||||
[[ -z ${API_SUFFIX+x} ]] && { API_SUFFIX="/api/"; }
|
||||
|
||||
MODE="grid"
|
||||
GRID_OPTIONS="-Dgrid.mode=true"
|
||||
RERUN_ATTEMPTS=0
|
||||
BROWSER="GOOGLE_CHROME"
|
||||
WEBDRIVER_VERSION=$(curl -s http://chromedriver.storage.googleapis.com/LATEST_RELEASE)
|
||||
WEBDRIVER_PORT="9515"
|
||||
NODE_CHROME_DEBUG_SUFFIX=
|
||||
THREADS=$(getRecommendedThreadCount)
|
||||
WORKSPACE_POOL_SIZE=0
|
||||
|
||||
ACTUAL_RESULTS=()
|
||||
COMPARE_WITH_CI=false
|
||||
|
||||
PRODUCT_PROTOCOL="http"
|
||||
PRODUCT_HOST=$(detectDockerInterfaceIp)
|
||||
PRODUCT_PORT=8080
|
||||
INCLUDE_TESTS_UNDER_REPAIR=false
|
||||
INCLUDE_FLAKY_TESTS=false
|
||||
FAIL_SCRIPT_ON_FAILED_TESTS=false
|
||||
|
||||
unset DEBUG_OPTIONS
|
||||
unset MAVEN_OPTIONS
|
||||
unset TMP_SUITE_PATH
|
||||
unset ORIGIN_TESTS_SCOPE
|
||||
unset TMP_DIR
|
||||
unset EXCLUDE_PARAM
|
||||
unset TOTAL_FAILS
|
||||
}
|
||||
|
||||
cleanUpEnvironment() {
|
||||
if [[ ${MODE} == "grid" ]]; then
|
||||
stopWebDriver
|
||||
stopSeleniumDockerContainers
|
||||
fi
|
||||
}
|
||||
|
||||
checkParameters() {
|
||||
for var in "$@"; do
|
||||
if [[ "$var" =~ --web-driver-version=.* ]]; then :
|
||||
elif [[ "$var" =~ --web-driver-port=[0-9]+$ ]]; then :
|
||||
elif [[ "$var" == --http ]]; then :
|
||||
elif [[ "$var" == --https ]]; then :
|
||||
elif [[ "$var" == --che ]]; then :
|
||||
elif [[ "$var" =~ --host=.* ]]; then :
|
||||
elif [[ "$var" =~ --port=.* ]]; then :
|
||||
elif [[ "$var" =~ --threads=[0-9]+$ ]]; then :
|
||||
|
||||
elif [[ "$var" == --rerun ]]; then :
|
||||
elif [[ "$var" =~ ^[0-9]+$ ]] && [[ $@ =~ --rerun[[:space:]]$var ]]; then :
|
||||
|
||||
elif [[ "$var" == --debug ]]; then :
|
||||
elif [[ "$var" == --all-tests ]]; then
|
||||
echo "[WARN] '--all-tests' parameter is outdated and is being ignored"
|
||||
|
||||
elif [[ "$var" =~ --test=.* ]]; then
|
||||
local fileName=$(basename $(echo "$var" | sed -e "s/--test=//g"))
|
||||
find "target/test-classes" | grep "${fileName}.[class|java]" > /dev/null
|
||||
[[ $? != 0 ]] && {
|
||||
echo "[TEST] Test "${fileName}" not found";
|
||||
echo "[TEST] Proper way to use --test parameter:";
|
||||
echo -e "[TEST] \t--test=DialogAboutTest";
|
||||
echo -e "[TEST] \t--test=org.eclipse.che.selenium.miscellaneous.DialogAboutTest";
|
||||
echo -e "[TEST] \t--test=org.eclipse.che.selenium.miscellaneous.**";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
elif [[ "$var" =~ --suite=.* ]]; then
|
||||
local suite=$(basename $(echo "$var" | sed -e "s/--suite=//g"))
|
||||
find "target/test-classes/suites" | grep ${suite} > /dev/null
|
||||
[[ $? != 0 ]] && {
|
||||
echo "[TEST] Suite "${suite}" not found";
|
||||
echo "[TEST] Proper way to use --suite parameter:";
|
||||
echo -e "[TEST] \t--suite=CheSuite.xml";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
elif [[ "$var" == --failed-tests ]]; then :
|
||||
elif [[ "$var" == --regression-tests ]]; then :
|
||||
elif [[ "$var" =~ -M.* ]]; then :
|
||||
elif [[ "$var" =~ -P.* ]]; then :
|
||||
elif [[ "$var" == --help ]]; then :
|
||||
|
||||
elif [[ "$var" == --compare-with-ci ]]; then :
|
||||
elif [[ "$var" =~ ^[0-9]+$ ]] && [[ $@ =~ --compare-with-ci[[:space:]]$var ]]; then :
|
||||
|
||||
elif [[ "$var" =~ ^--workspace-pool-size=(auto|[0-9]+)$ ]]; then :
|
||||
elif [[ "$var" =~ ^-D.* ]]; then :
|
||||
elif [[ "$var" =~ ^-[[:alpha:]]$ ]]; then :
|
||||
elif [[ "$var" == --skip-sources-validation ]]; then :
|
||||
elif [[ "$var" == --multiuser ]]; then :
|
||||
elif [[ "$var" =~ --exclude=.* ]]; then :
|
||||
elif [[ "$var" =~ --include-tests-under-repair ]]; then :
|
||||
elif [[ "$var" =~ --include-flaky-tests ]]; then :
|
||||
elif [[ "$var" =~ --fail-script-on-failed-tests ]]; then :
|
||||
|
||||
else
|
||||
printHelp
|
||||
echo "[TEST] Unrecognized or misused parameter "${var}
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
applyCustomOptions() {
|
||||
for var in "$@"; do
|
||||
if [[ "$var" =~ --web-driver-version=.* ]]; then
|
||||
if [[ ${MODE} == "local" ]]; then
|
||||
WEBDRIVER_VERSION=$(echo "$var" | sed -e "s/--web-driver-version=//g")
|
||||
fi
|
||||
|
||||
elif [[ "$var" =~ --web-driver-port=.* ]]; then
|
||||
if [[ ${MODE} == "local" ]]; then
|
||||
WEBDRIVER_PORT=$(echo "$var" | sed -e "s/--web-driver-port=//g")
|
||||
fi
|
||||
|
||||
elif [[ "$var" == --http ]]; then
|
||||
PRODUCT_PROTOCOL="http"
|
||||
|
||||
elif [[ "$var" == --https ]]; then
|
||||
PRODUCT_PROTOCOL="https"
|
||||
|
||||
elif [[ "$var" =~ --host=.* ]]; then
|
||||
PRODUCT_HOST=$(echo "$var" | sed -e "s/--host=//g")
|
||||
|
||||
elif [[ "$var" =~ --port=.* ]]; then
|
||||
PRODUCT_PORT=$(echo "$var" | sed -e "s/--port=//g")
|
||||
|
||||
elif [[ "$var" =~ --threads=.* ]]; then
|
||||
THREADS=$(echo "$var" | sed -e "s/--threads=//g")
|
||||
|
||||
elif [[ "$var" =~ --workspace-pool-size=.* ]]; then
|
||||
WORKSPACE_POOL_SIZE=$(echo "$var" | sed -e "s/--workspace-pool-size=//g")
|
||||
|
||||
elif [[ "$var" =~ --rerun ]]; then
|
||||
local rerunAttempts=$(echo $@ | sed 's/.*--rerun\W\+\([0-9]\+\).*/\1/')
|
||||
if [[ "$rerunAttempts" =~ ^[0-9]+$ ]]; then
|
||||
RERUN_ATTEMPTS=$rerunAttempts
|
||||
else
|
||||
RERUN_ATTEMPTS=1
|
||||
fi
|
||||
|
||||
elif [[ "$var" == --debug ]]; then
|
||||
DEBUG_OPTIONS="-Dmaven.failsafe.debug"
|
||||
NODE_CHROME_DEBUG_SUFFIX="-debug"
|
||||
|
||||
elif [[ "$var" == --compare-with-ci ]]; then
|
||||
COMPARE_WITH_CI=true
|
||||
|
||||
elif [[ "$var" == --multiuser ]]; then
|
||||
CHE_MULTIUSER=true
|
||||
|
||||
elif [[ "$var" =~ --exclude=.* ]]; then
|
||||
EXCLUDE_PARAM=$(echo "$var" | sed -e "s/--exclude=//g")
|
||||
|
||||
elif [[ "$var" == --include-tests-under-repair ]]; then
|
||||
INCLUDE_TESTS_UNDER_REPAIR=true
|
||||
|
||||
elif [[ "$var" == --include-flaky-tests ]]; then
|
||||
INCLUDE_FLAKY_TESTS=true
|
||||
|
||||
elif [[ "$var" == --fail-script-on-failed-tests ]]; then
|
||||
FAIL_SCRIPT_ON_FAILED_TESTS=true
|
||||
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
extractMavenOptions() {
|
||||
for var in "$@"; do
|
||||
if [[ "$var" =~ ^-D.* ]]; then
|
||||
MAVEN_OPTIONS="${MAVEN_OPTIONS} $var"
|
||||
elif [[ "$var" =~ ^-[[:alpha:]]$ ]]; then :
|
||||
MAVEN_OPTIONS="${MAVEN_OPTIONS} $var"
|
||||
elif [[ "$var" == "--skip-sources-validation" ]]; then :
|
||||
MAVEN_OPTIONS="${MAVEN_OPTIONS} -Dskip-enforce -Dskip-validate-sources"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
defineTestsScope() {
|
||||
for var in "$@"; do
|
||||
if [[ "$var" =~ --test=.* ]]; then
|
||||
TESTS_SCOPE="-Dit.test="$(echo "$var" | sed -e "s/--test=//g")
|
||||
THREADS=1
|
||||
|
||||
elif [[ "$var" =~ --suite=.* ]]; then
|
||||
TESTS_SCOPE="-DrunSuite=target/test-classes/suites/"$(echo "$var" | sed -e "s/--suite=//g")
|
||||
|
||||
elif [[ "$var" == --failed-tests ]]; then
|
||||
generateTestNgFailedReport $(fetchFailedTests)
|
||||
TESTS_SCOPE="-DrunSuite=${TESTNG_FAILED_SUITE}"
|
||||
|
||||
elif [[ "$var" == --regression-tests ]]; then
|
||||
generateTestNgFailedReport $(findRegressions)
|
||||
TESTS_SCOPE="-DrunSuite=${TESTNG_FAILED_SUITE}"
|
||||
fi
|
||||
done
|
||||
|
||||
ORIGIN_TESTS_SCOPE=${TESTS_SCOPE}
|
||||
}
|
||||
|
||||
defineOperationSystemSpecificVariables() {
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
TMP_DIR=$(echo ${TMPDIR})
|
||||
else
|
||||
TMP_DIR="/tmp"
|
||||
fi
|
||||
}
|
||||
|
||||
init() {
|
||||
BLUE='\033[1;34m'
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[0;33m'
|
||||
NO_COLOUR='\033[0m'
|
||||
}
|
||||
|
||||
defineRunMode() {
|
||||
for var in "$@"; do
|
||||
if [[ "$var" =~ -M.* ]]; then
|
||||
MODE=$(echo "$var" | sed -e "s/-M//g")
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ${MODE} == "grid" ]]; then
|
||||
WEBDRIVER_PORT="4444"
|
||||
|
||||
checkDockerRequirements
|
||||
checkDockerComposeRequirements
|
||||
|
||||
elif [[ ${MODE} == "local" ]]; then
|
||||
GRID_OPTIONS="-Dgrid.mode=false"
|
||||
|
||||
else
|
||||
echo "[TEST] Unrecognized mode "${MODE}
|
||||
echo "[TEST] Available modes: -M[local|grid]"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
stopWebDriver() {
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
ps -cf | grep chromedriver | awk '{if(NR>0) print $2}' | while read -r pid; do kill "${pid}" > /dev/null; done
|
||||
else
|
||||
ps -fC chromedriver | awk '{if(NR>1) print $2}' | while read -r pid; do kill "${pid}" > /dev/null; done
|
||||
fi
|
||||
}
|
||||
|
||||
startWebDriver() {
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
curl -s -o ${TMP_DIR}chromedriver_mac64.zip http://chromedriver.storage.googleapis.com/${WEBDRIVER_VERSION}/chromedriver_mac64.zip
|
||||
unzip -o ${TMP_DIR}chromedriver_mac64.zip -d ${TMP_DIR} > /dev/null
|
||||
chmod +x ${TMP_DIR}chromedriver
|
||||
${TMP_DIR}chromedriver --port=9515 --no-sandbox > /dev/null &
|
||||
else
|
||||
curl -s -o ${TMP_DIR}/chromedriver_linux64.zip http://chromedriver.storage.googleapis.com/${WEBDRIVER_VERSION}/chromedriver_linux64.zip
|
||||
unzip -o ${TMP_DIR}/chromedriver_linux64.zip -d ${TMP_DIR} > /dev/null
|
||||
chmod +x ${TMP_DIR}/chromedriver
|
||||
${TMP_DIR}/chromedriver --port=9515 --no-sandbox > /dev/null &
|
||||
fi
|
||||
}
|
||||
|
||||
initRunMode() {
|
||||
if [[ ${MODE} == "local" ]]; then
|
||||
startWebDriver
|
||||
|
||||
elif [[ ${MODE} == "grid" ]]; then
|
||||
export NODE_CHROME_DEBUG_SUFFIX
|
||||
docker-compose -p=selenium up -d > /dev/null
|
||||
docker-compose -p=selenium scale chromenode=${THREADS} > /dev/null
|
||||
|
||||
else
|
||||
echo "[TEST] Unrecognized mode "${MODE}
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
stopSeleniumDockerContainers() {
|
||||
local containers=$(docker ps -qa --filter="name=selenium_*" | wc -l)
|
||||
if [[ ${containers} != "0" ]]; then
|
||||
echo "[TEST] Stopping and removing selenium docker containers..."
|
||||
docker rm -f $(docker ps -qa --filter="name=selenium_*") > /dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
checkDockerRequirements() {
|
||||
command -v docker >/dev/null 2>&1 || {
|
||||
echo >&2 -e "[TEST] Could not find Docker client, please install it.\n https://docs.docker.com/engine/installation/"
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
checkDockerComposeRequirements() {
|
||||
command -v docker-compose >/dev/null 2>&1 || {
|
||||
echo >&2 -e "[TEST] Could not find Docker Compose client, please install it.\n https://docs.docker.com/compose/install/"
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
checkIfProductIsRun() {
|
||||
local url=${PRODUCT_PROTOCOL}"://"${PRODUCT_HOST}:${PRODUCT_PORT}${API_SUFFIX};
|
||||
|
||||
curl -s -k -X OPTIONS ${url} > /dev/null
|
||||
if [[ $? != 0 ]]; then
|
||||
echo "[TEST] "${url}" is down"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
prepareTestSuite() {
|
||||
local suitePath=${ORIGIN_TESTS_SCOPE:11}
|
||||
TMP_SUITE_PATH="/tmp/"$(basename "${suitePath}")
|
||||
rm -f ${TMP_SUITE_PATH}
|
||||
cp -f ${suitePath} /tmp
|
||||
|
||||
TESTS_SCOPE="-DrunSuite=${TMP_SUITE_PATH}"
|
||||
|
||||
# set number of threads directly in the suite
|
||||
sed -i -e "s#thread-count=\"[^\"]*\"#thread-count=\"${THREADS}\"#" "$TMP_SUITE_PATH"
|
||||
}
|
||||
|
||||
printHelp() {
|
||||
local usage="
|
||||
Usage: ${CALLER} [-Mmode] [options] [tests scope]
|
||||
|
||||
Options:
|
||||
--http Use 'http' protocol to connect to product
|
||||
--https Use 'https' protocol to connect to product
|
||||
--host=<PRODUCT_HOST> Set host where product is deployed
|
||||
--port=<PRODUCT_PORT> Set port of the product, default is 8080
|
||||
--multiuser Run tests of Multi User Che
|
||||
|
||||
Modes (defines environment to run tests):
|
||||
-Mlocal All tests will be run in a Web browser on the developer machine.
|
||||
Recommended if test visualization is needed and for debugging purpose.
|
||||
|
||||
Options that go with 'local' mode:
|
||||
--web-driver-version=<VERSION> To use the specific version of the WebDriver, be default the latest will be used: "${WEBDRIVER_VERSION}"
|
||||
--web-driver-port=<PORT> To run WebDriver on the specific port, by default: "${WEBDRIVER_PORT}"
|
||||
--threads=<THREADS> Number of tests that will be run simultaneously. It also means the very same number of
|
||||
Web browsers will be opened on the developer machine.
|
||||
Default value is in range [2,5] and depends on available RAM.
|
||||
|
||||
-Mgrid (default) All tests will be run in parallel among several docker containers.
|
||||
One container per thread. Recommended to run test suite.
|
||||
|
||||
Options that go with 'grid' mode:
|
||||
--threads=<THREADS> Number of tests that will be run simultaneously.
|
||||
Default value is in range [2,5] and depends on available RAM.
|
||||
|
||||
Define tests scope:
|
||||
--test=<TEST_CLASS> Single test/package to run.
|
||||
For example: '--test=DialogAboutTest', '--test=org.eclipse.che.selenium.git.**'.
|
||||
--suite=<SUITE> Test suite to run, found ('CheSuite.xml' is default one):
|
||||
"$(for x in $(ls -1 target/test-classes/suites); do echo " * "$x; done)"
|
||||
--exclude=<TEST_GROUPS_TO_EXCLUDE> Comma-separated list of test groups to exclude from execution.
|
||||
For example, use '--exclude=github' to exclude GitHub-related tests.
|
||||
|
||||
Handle failing tests:
|
||||
--failed-tests Rerun failed tests that left after the previous try
|
||||
--regression-tests Rerun regression tests that left after the previous try
|
||||
--rerun [ATTEMPTS] Automatically rerun failing tests.
|
||||
Default attempts number is 1.
|
||||
--compare-with-ci [BUILD NUMBER] Compare failed tests with results on CI server.
|
||||
Default build is the latest.
|
||||
--fail-script-on-failed-tests Fail webdriver.sh if tests failed.
|
||||
|
||||
Other options:
|
||||
--debug Run tests in debug mode
|
||||
--skip-sources-validation Fast build. Skips source validation and enforce plugins
|
||||
--workspace-pool-size=[<SIZE>|auto] Size of test workspace pool.
|
||||
Default value is 0, that means that test workspaces are created on demand.
|
||||
--include-tests-under-repair Include tests which permanently fail and so belong to group 'UNDER REPAIR'
|
||||
--include-flaky-tests Include tests which randomly fail and so belong to group 'FLAKY'
|
||||
|
||||
HOW TO of usage:
|
||||
Test Eclipse Che single user assembly:
|
||||
${CALLER}
|
||||
|
||||
Test Eclipse Che multi user assembly:
|
||||
${CALLER} --multiuser
|
||||
|
||||
Test Eclipse Che assembly and automatically rerun failing tests:
|
||||
${CALLER} --rerun [ATTEMPTS]
|
||||
|
||||
Run single test or package of tests:
|
||||
${CALLER} <...> --test=<TEST>
|
||||
|
||||
Run suite:
|
||||
${CALLER} <...> --suite=<PATH_TO_SUITE>
|
||||
|
||||
Include tests which belong to groups 'UNDER REPAIR' and 'FLAKY'
|
||||
./selenium-tests.sh --include-tests-under-repair --include-flaky-tests
|
||||
|
||||
Rerun failed tests:
|
||||
${CALLER} <...> --failed-tests
|
||||
${CALLER} <...> --failed-tests --rerun [ATTEMPTS]
|
||||
|
||||
Debug selenium test:
|
||||
${CALLER} -Mlocal --test=<TEST> --debug
|
||||
|
||||
Analyse tests results:
|
||||
${CALLER} --compare-with-ci [BUILD NUMBER]
|
||||
"
|
||||
|
||||
printf "%s" "${usage}"
|
||||
}
|
||||
|
||||
printRunOptions() {
|
||||
echo "[TEST]"
|
||||
echo "[TEST] =========== RUN OPTIONS ==========================="
|
||||
echo "[TEST] Mode : ${MODE}"
|
||||
echo "[TEST] Rerun attempts : ${RERUN_ATTEMPTS}"
|
||||
echo "[TEST] ==================================================="
|
||||
echo "[TEST] Product Protocol : ${PRODUCT_PROTOCOL}"
|
||||
echo "[TEST] Product Host : ${PRODUCT_HOST}"
|
||||
echo "[TEST] Product Port : ${PRODUCT_PORT}"
|
||||
echo "[TEST] Product Config : $(getProductConfig)"
|
||||
echo "[TEST] Tests scope : ${TESTS_SCOPE}"
|
||||
echo "[TEST] Tests to exclude : $(getExcludedGroups)"
|
||||
echo "[TEST] Threads : ${THREADS}"
|
||||
echo "[TEST] Workspace pool size : ${WORKSPACE_POOL_SIZE}"
|
||||
echo "[TEST] Web browser : ${BROWSER}"
|
||||
echo "[TEST] Web driver ver : ${WEBDRIVER_VERSION}"
|
||||
echo "[TEST] Web driver port : ${WEBDRIVER_PORT}"
|
||||
echo "[TEST] Additional opts : ${GRID_OPTIONS} ${DEBUG_OPTIONS} ${MAVEN_OPTIONS}"
|
||||
echo "[TEST] ==================================================="
|
||||
}
|
||||
|
||||
# convert failed tests methods in the unique list of test classes
|
||||
# a.b.c.SomeTest.someMethod1
|
||||
# a.b.c.SomeTest.someMethod2
|
||||
# |------> a.b.c.SomeTest
|
||||
getTestClasses() {
|
||||
local tests=$@
|
||||
for t in ${tests[*]}
|
||||
do
|
||||
echo $(echo ${t} | sed 's/\(.*\)[.][^.]*/\1/')
|
||||
done
|
||||
}
|
||||
|
||||
fetchRunTestsNumber() {
|
||||
local run=0
|
||||
for report in target/failsafe-reports/*.txt
|
||||
do
|
||||
if [[ -f ${report} ]]; then
|
||||
run=$((run + $(cat ${report} | grep "Tests run" | sed 's/Tests run:[[:space:]]\([0-9]*\).*/\1/')))
|
||||
fi
|
||||
done
|
||||
echo ${run}
|
||||
}
|
||||
|
||||
# Returns unique records.
|
||||
fetchFailedTests() {
|
||||
local fails=()
|
||||
for report in target/failsafe-reports/*.txt
|
||||
do
|
||||
if [[ -f ${report} ]]; then
|
||||
for item in $(cat ${report} | grep "<<< FAILURE!" | grep -e '(.*).*' | tr ' ' '_')
|
||||
do
|
||||
local method=$(echo ${item} | sed 's/\(.*\)(.*)_.*/\1/')
|
||||
local class=$(echo ${item} | sed 's/.*(\(.*\))_.*/\1/')
|
||||
fails+=(${class}'.'${method})
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
for f in $(echo ${fails[@]} | tr ' ' '\n' | sort | uniq)
|
||||
do
|
||||
echo ${f}
|
||||
done
|
||||
}
|
||||
|
||||
fetchFailedTestsNumber() {
|
||||
echo $(fetchFailedTests) | wc -w
|
||||
}
|
||||
|
||||
detectLatestResultsUrl() {
|
||||
local build=$(curl -s ${BASE_ACTUAL_RESULTS_URL} | tr '\n' ' ' | sed 's/.*Last build (#\([0-9]\+\)).*/\1/')
|
||||
echo ${BASE_ACTUAL_RESULTS_URL}${build}"/testReport/"
|
||||
}
|
||||
|
||||
# Fetches list of failed tests and failed configurations.
|
||||
# Combines them into a single unique list.
|
||||
fetchActualResults() {
|
||||
unset ACTUAL_RESULTS
|
||||
unset ACTUAL_RESULTS_URL
|
||||
|
||||
# define the URL of CI job to compare local result with result on CI
|
||||
local multiuserToken=$([[ "$CHE_MULTIUSER" == true ]] && echo "-multiuser")
|
||||
local infrastructureToken=$([[ "$CHE_INFRASTRUCTURE" == "openshift" ]] && echo "-ocp" || echo "-$CHE_INFRASTRUCTURE")
|
||||
local nameOfCIJob="che-integration-tests${multiuserToken}-master${infrastructureToken}"
|
||||
|
||||
[[ -z ${BASE_ACTUAL_RESULTS_URL+x} ]] && { BASE_ACTUAL_RESULTS_URL="https://ci.codenvycorp.com/view/qa/job/${nameOfCIJob}/"; }
|
||||
|
||||
local build=$(echo $@ | sed 's/.*--compare-with-ci\W\+\([0-9]\+\).*/\1/')
|
||||
if [[ ! ${build} =~ ^[0-9]+$ ]]; then
|
||||
ACTUAL_RESULTS_URL=$(detectLatestResultsUrl)
|
||||
else
|
||||
ACTUAL_RESULTS_URL=${BASE_ACTUAL_RESULTS_URL}${build}"/testReport/"
|
||||
fi
|
||||
|
||||
# get list of failed tests from CI server, remove duplicates from it and sort
|
||||
ACTUAL_RESULTS=$(echo $( curl -s ${ACTUAL_RESULTS_URL} | \
|
||||
tr '>' '\n' | tr '<' '\n' | tr '"' '\n' | \
|
||||
grep --extended-regexp "^[a-z_$][a-z0-9_$.]*\.[A-Z_$][a-zA-Z0-9_$]*\.[a-z_$][a-zA-Z0-9_$]*$" | \
|
||||
tr ' ' '\n' | sort | uniq ))
|
||||
}
|
||||
|
||||
findRegressions() {
|
||||
local expected=(${ACTUAL_RESULTS[*]})
|
||||
local failed=$(fetchFailedTests)
|
||||
|
||||
for f in ${failed[*]}
|
||||
do
|
||||
local skip=false
|
||||
for e in ${expected[*]}
|
||||
do
|
||||
[[ ${f} == ${e} ]] && { skip=true; break; }
|
||||
done
|
||||
[[ ${skip} == true ]] || echo ${f}
|
||||
done
|
||||
}
|
||||
|
||||
# Analyses tests results by comparing with the actual ones.
|
||||
analyseTestsResults() {
|
||||
echo "[TEST]"
|
||||
echo -e "[TEST] "${YELLOW}"RESULTS ANALYSE:"${NO_COLOUR}
|
||||
|
||||
echo "[TEST]"
|
||||
echo -e "[TEST] Command line: ${BLUE}${CUR_DIR}/${CALLER} $@${NO_COLOUR}"
|
||||
echo "[TEST]"
|
||||
|
||||
if [[ ${COMPARE_WITH_CI} == true ]]; then
|
||||
echo -e "[TEST] CI results ${BLUE}${ACTUAL_RESULTS_URL}${NO_COLOUR}"
|
||||
echo -e "[TEST] \t- Failed: $(printf "%5s" "$(echo ${ACTUAL_RESULTS[@]} | wc -w)") (unique tests)"
|
||||
echo "[TEST]"
|
||||
fi
|
||||
|
||||
local run=$(fetchRunTestsNumber)
|
||||
local runToDisplay=$(printf "%7s" "${run}")
|
||||
local fails=$(fetchFailedTests)
|
||||
TOTAL_FAILS=$(echo ${fails[@]} | wc -w)
|
||||
local totalFailsToDisplay=$(printf "%5s" "${TOTAL_FAILS}")
|
||||
|
||||
echo "[TEST] Local results:"
|
||||
echo -e "[TEST] \t- Run: \t${runToDisplay}"
|
||||
echo -e "[TEST] \t- Failed: ${totalFailsToDisplay}"
|
||||
|
||||
if [[ ${COMPARE_WITH_CI} == true ]]; then
|
||||
if [[ ! ${TOTAL_FAILS} -eq 0 ]]; then
|
||||
for r in $(echo ${fails[@]} | tr ' ' '\n' | sort)
|
||||
do
|
||||
echo -e "[TEST] \t"${r}
|
||||
done
|
||||
fi
|
||||
echo "[TEST]"
|
||||
|
||||
echo -e -n "[TEST] Comparing with "${BLUE}${ACTUAL_RESULTS_URL}${NO_COLOUR}
|
||||
if [[ ${ACTUAL_RESULTS_URL} != $(detectLatestResultsUrl) ]]; then
|
||||
echo -e ${RED}" (not the latest results)"${NO_COLOUR}
|
||||
else
|
||||
echo
|
||||
fi
|
||||
echo "[TEST] If a test failed then it is NOT marked as regression."
|
||||
fi
|
||||
|
||||
echo "[TEST]"
|
||||
|
||||
if [[ ${run} == "0" ]]; then
|
||||
echo -e "[TEST] "${RED}"NO RESULTS"${NO_COLOUR}
|
||||
else
|
||||
local regressions=$(findRegressions)
|
||||
local totalRegressions=$(echo ${regressions[@]} | wc -w)
|
||||
if [[ ${totalRegressions} -eq 0 ]]; then
|
||||
echo -e -n "[TEST] "${GREEN}"NO REGRESSION! "${NO_COLOUR}
|
||||
if [[ ! ${TOTAL_FAILS} -eq 0 ]]; then
|
||||
echo -e ${RED}"CHECK THE FAILED TESTS. THEY MIGHT FAIL DUE TO DIFFERENT REASON."${NO_COLOUR}
|
||||
else
|
||||
echo -e ${GREEN}"NO FAILED TESTS, GREAT JOB!"${NO_COLOUR}
|
||||
fi
|
||||
else
|
||||
echo -e "[TEST] "${RED}"REGRESSION"${NO_COLOUR}" ("${totalRegressions}"):"
|
||||
|
||||
for r in $(echo ${regressions[@]} | tr ' ' '\n' | sort)
|
||||
do
|
||||
echo -e "[TEST] \t"${r}
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "[TEST]"
|
||||
echo "[TEST]"
|
||||
}
|
||||
|
||||
printProposals() {
|
||||
echo -e "[TEST] "${YELLOW}"PROPOSALS:"${NO_COLOUR}
|
||||
local cmd=$(echo $@ | sed -e "s/--rerun\W*[0-9]*//g" | \
|
||||
sed -e "s/-M[^ ]*//g" | \
|
||||
sed -e "s/--failed-tests//g" | \
|
||||
sed -e "s/--regression-tests//g" | \
|
||||
sed -e "s/--suite=[^ ]*//g " | \
|
||||
sed -e "s/--test*=[^ ]*//g " | \
|
||||
sed -e "s/--compare-with-ci\W*[0-9]*//g" | \
|
||||
sed -e "s/--threads=[0-9]*//g" | \
|
||||
sed -e "s/--workspace-pool-size=auto|[0-9]*//g")
|
||||
|
||||
local regressions=$(findRegressions)
|
||||
local total=$(echo ${regressions[@]} | wc -w)
|
||||
|
||||
if [[ ! ${total} -eq 0 ]]; then
|
||||
echo "[TEST]"
|
||||
echo "[TEST] Try rerun all tests:"
|
||||
echo -e "[TEST] \t${BLUE}${CUR_DIR}/${CALLER} ${cmd} --threads=${THREADS} -Mlocal --failed-tests${NO_COLOUR}"
|
||||
echo -e "[TEST] \t${BLUE}${CUR_DIR}/${CALLER} ${cmd} --threads=${THREADS} -Mgrid --failed-tests${NO_COLOUR}"
|
||||
|
||||
echo "[TEST]"
|
||||
if [[ ${total} -lt 50 ]]; then
|
||||
echo "[TEST] Or run them one by one:"
|
||||
for r in $(echo ${regressions[@]} | tr ' ' '\n' | sed 's/\(.*\)[.][^.]*/\1/' | sort | uniq)
|
||||
do
|
||||
echo -e "[TEST] \t${BLUE}${CUR_DIR}/${CALLER} ${cmd} -Mlocal --test=${r}${NO_COLOUR}"
|
||||
done
|
||||
echo "[TEST]"
|
||||
echo -e "[TEST] You might need add ${BLUE}--debug${NO_COLOUR} option for debugging purpose."
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "[TEST]"
|
||||
echo "[TEST] To compare tests results with the latest results on CI job"
|
||||
echo -e "[TEST] \t${BLUE}${CUR_DIR}/${CALLER} ${cmd} --compare-with-ci${NO_COLOUR}"
|
||||
echo "[TEST]"
|
||||
echo "[TEST] To compare local tests results with certain build on CI job"
|
||||
echo -e "[TEST] \t${BLUE}${CUR_DIR}/${CALLER} ${cmd} --compare-with-ci [BUILD NUMBER]${NO_COLOUR}"
|
||||
echo "[TEST]"
|
||||
echo "[TEST]"
|
||||
}
|
||||
|
||||
printElapsedTime() {
|
||||
local totalTime=$(($(date +%s)-${START_TIME}))
|
||||
echo "[TEST]"
|
||||
echo "[TEST] Elapsed time: "$((${totalTime} / 3600))"hrs "$(( $((${totalTime} / 60)) % 60))"min "$((${totalTime} % 60))"sec"
|
||||
}
|
||||
|
||||
runTests() {
|
||||
if [[ ${TESTS_SCOPE} =~ -DrunSuite ]]; then
|
||||
prepareTestSuite
|
||||
fi
|
||||
|
||||
printRunOptions
|
||||
|
||||
mvn clean verify -Pselenium-test \
|
||||
${TESTS_SCOPE} \
|
||||
-Dche.host=${PRODUCT_HOST} \
|
||||
-Dche.port=${PRODUCT_PORT} \
|
||||
-Dche.protocol=${PRODUCT_PROTOCOL} \
|
||||
-Ddocker.interface.ip=$(detectDockerInterfaceIp) \
|
||||
-Ddriver.port=${WEBDRIVER_PORT} \
|
||||
-Ddriver.version=${WEBDRIVER_VERSION} \
|
||||
-Dbrowser=${BROWSER} \
|
||||
-Dche.threads=${THREADS} \
|
||||
-Dche.workspace_pool_size=${WORKSPACE_POOL_SIZE} \
|
||||
-DexcludedGroups="$(getExcludedGroups)" \
|
||||
${DEBUG_OPTIONS} \
|
||||
${GRID_OPTIONS} \
|
||||
${MAVEN_OPTIONS}
|
||||
}
|
||||
|
||||
# Return list of product features
|
||||
getProductConfig() {
|
||||
local testGroups=${CHE_INFRASTRUCTURE}
|
||||
|
||||
if [[ ${CHE_MULTIUSER} == true ]]; then
|
||||
testGroups=${testGroups},multiuser
|
||||
else
|
||||
testGroups=${testGroups},singleuser
|
||||
fi
|
||||
|
||||
echo ${testGroups}
|
||||
}
|
||||
|
||||
# Prepare list of test groups to exclude.
|
||||
getExcludedGroups() {
|
||||
local excludeParamArray=(${EXCLUDE_PARAM//,/ })
|
||||
|
||||
if [[ ${INCLUDE_TESTS_UNDER_REPAIR} == false ]]; then
|
||||
excludeParamArray+=( 'under_repair' )
|
||||
fi
|
||||
|
||||
if [[ ${INCLUDE_FLAKY_TESTS} == false ]]; then
|
||||
excludeParamArray+=( 'flaky' )
|
||||
fi
|
||||
|
||||
echo $(IFS=$','; echo "${excludeParamArray[*]}")
|
||||
}
|
||||
|
||||
# Reruns failed tests
|
||||
rerunTests() {
|
||||
local regressions=$(findRegressions)
|
||||
local total=$(echo ${regressions[@]} | wc -w)
|
||||
|
||||
if [[ ! ${total} -eq 0 ]]; then
|
||||
local rerunCounter=$1 && shift
|
||||
|
||||
analyseTestsResults $@
|
||||
generateFailSafeReport
|
||||
printProposals $@
|
||||
storeTestReport
|
||||
printElapsedTime
|
||||
|
||||
echo -e "[TEST]"
|
||||
echo -e "[TEST] ${YELLOW}---------------------------------------------------${NO_COLOUR}"
|
||||
echo -e "[TEST] ${YELLOW}RERUNNING FAILED TESTS IN ONE THREAD: ATTEMPT #${rerunCounter}${NO_COLOUR}"
|
||||
echo -e "[TEST] ${YELLOW}---------------------------------------------------${NO_COLOUR}"
|
||||
|
||||
defineTestsScope "--failed-tests"
|
||||
runTests
|
||||
|
||||
if [[ ${rerunCounter} < ${RERUN_ATTEMPTS} ]]; then
|
||||
rerunTests $(($rerunCounter+1)) $@
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Finds regressions and generates testng-failed.xml suite bases on them.
|
||||
generateTestNgFailedReport() {
|
||||
local failsClasses=$(getTestClasses $@)
|
||||
|
||||
if [[ -d ${FAILSAFE_DIR} ]]; then
|
||||
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" > ${TESTNG_FAILED_SUITE}
|
||||
echo "<suite thread-count=\"1\" verbose=\"0\" parallel=\"classes\" name=\"Failed suite\">" >> ${TESTNG_FAILED_SUITE}
|
||||
echo -e "\t<test name=\"Surefire test\">" >> ${TESTNG_FAILED_SUITE}
|
||||
echo -e "\t\t<classes>" >> ${TESTNG_FAILED_SUITE}
|
||||
|
||||
for f in $(echo ${failsClasses[@]} | tr ' ' '\n' | sort | uniq)
|
||||
do
|
||||
echo -e -n "\t\t\t<class name=\"" >> ${TESTNG_FAILED_SUITE}
|
||||
echo -e -n ${f} >> ${TESTNG_FAILED_SUITE}
|
||||
echo -e "\"/>" >> ${TESTNG_FAILED_SUITE}
|
||||
done
|
||||
echo -e "\t\t</classes>" >> ${TESTNG_FAILED_SUITE}
|
||||
echo -e "\t</test>" >> ${TESTNG_FAILED_SUITE}
|
||||
echo -e "</suite>" >> ${TESTNG_FAILED_SUITE}
|
||||
fi
|
||||
}
|
||||
|
||||
# generates and updates failsafe report
|
||||
generateFailSafeReport () {
|
||||
mvn -q surefire-report:failsafe-report-only
|
||||
mvn -q site -DgenerateReports=false
|
||||
|
||||
echo "[TEST]"
|
||||
echo -e "[TEST] ${YELLOW}REPORT:${NO_COLOUR}"
|
||||
|
||||
if [[ ! -f ${FAILSAFE_REPORT} ]]; then
|
||||
echo -e "[TEST] Failsafe report: ${BLUE}file://${CUR_DIR}/${FAILSAFE_REPORT}${NO_COLOUR} not found."
|
||||
echo "[TEST] Either maven surefire report plugin failed or tests haven't been run at all."
|
||||
echo "[TEST]"
|
||||
echo "[TEST] To regenerate report manually use the command below:"
|
||||
echo -e "[TEST] \t${BLUE}${CUR_DIR}/${CALLER} --compare-with-ci${NO_COLOUR}"
|
||||
echo "[TEST]"
|
||||
echo "[TEST]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local regressions=$(findRegressions)
|
||||
|
||||
# add REGRESSION marks
|
||||
for r in ${regressions[*]}
|
||||
do
|
||||
local test=$(basename $(echo ${r} | tr '.' '/') | sed 's/\(.*\)_.*/\1/')
|
||||
|
||||
local aTag="<a href=\"#"${r}"\">"${test}"<\/a>"
|
||||
local divRegTag="<h2>REGRESSION<\/h2>"${aTag}
|
||||
sed -i "s/${aTag}/${divRegTag}/" ${FAILSAFE_REPORT}
|
||||
done
|
||||
|
||||
# pack logs of workspaces which failed on start when injecting into test object and add link into the 'Summary' section of failsafe report
|
||||
local dirWithFailedWorkspacesLogs="target/site/workspace-logs/injecting_workspaces_which_did_not_start"
|
||||
if [[ -d ${dirWithFailedWorkspacesLogs} ]]; then
|
||||
cd ${dirWithFailedWorkspacesLogs}
|
||||
zip -qr "../injecting_workspaces_which_did_not_start_logs.zip" .
|
||||
cd - > /dev/null
|
||||
rm -rf ${dirWithFailedWorkspacesLogs}
|
||||
summaryTag="Summary<\/h2><a name=\"Summary\"><\/a>"
|
||||
linkToFailedWorkspacesLogsTag="<p>\[<a href=\"workspace-logs\/injecting_workspaces_which_did_not_start_logs.zip\" target=\"_blank\">Injecting workspaces which didn't start logs<\/a>\]<\/p>"
|
||||
sed -i "s/${summaryTag}/${summaryTag}${linkToFailedWorkspacesLogsTag}/" ${FAILSAFE_REPORT}
|
||||
fi
|
||||
|
||||
# add link the che server logs archive into the 'Summary' section of failsafe report
|
||||
local summaryTag="Summary<\/h2><a name=\"Summary\"><\/a>"
|
||||
local linkToCheServerLogsTag="<p>\[<a href=\"che_server_logs.zip\" target=\"_blank\">Eclipse Che Server logs<\/a>\]<\/p>"
|
||||
sed -i "s/${summaryTag}/${summaryTag}${linkToCheServerLogsTag}/" ${FAILSAFE_REPORT}
|
||||
|
||||
# attach screenshots
|
||||
if [[ -d "target/site/screenshots" ]]; then
|
||||
for file in $(ls target/site/screenshots/* | sort -r)
|
||||
do
|
||||
local test=$(basename ${file} | sed 's/\(.*\)_.*/\1/')
|
||||
local testDetailTag="<div id=\"${test}-failure\" style=\"display:none;\">"
|
||||
local screenshotTag="<p><img src=\"screenshots\/"$(basename ${file})"\"><p>"
|
||||
sed -i "s/${testDetailTag}/${testDetailTag}${screenshotTag}/" ${FAILSAFE_REPORT}
|
||||
done
|
||||
fi
|
||||
|
||||
attachLinkToTestReport workspace-logs "Workspace logs"
|
||||
attachLinkToTestReport webdriver-logs "Browser logs"
|
||||
attachLinkToTestReport htmldumps "Web page source"
|
||||
|
||||
echo "[TEST]"
|
||||
echo "[TEST] Failsafe report"
|
||||
echo -e "[TEST] \t${BLUE}file://${CUR_DIR}/${FAILSAFE_REPORT}${NO_COLOUR}"
|
||||
echo "[TEST]"
|
||||
echo "[TEST]"
|
||||
}
|
||||
|
||||
# first argument - relative path to directory inside target/site
|
||||
# second argument - title of the link
|
||||
attachLinkToTestReport() {
|
||||
# attach links to resource related to failed test
|
||||
local relativePathToResource=$1
|
||||
local titleOfLink=$2
|
||||
local dirWithResources="target/site/$relativePathToResource"
|
||||
|
||||
# return if directory doesn't exist
|
||||
[[ ! -d ${dirWithResources} ]] && return
|
||||
|
||||
# return if directory is empty
|
||||
[[ -z "$(ls -A ${dirWithResources})" ]] && return
|
||||
|
||||
for file in $(ls ${dirWithResources}/* | sort -r)
|
||||
do
|
||||
local test=$(basename ${file} | sed 's/\(.*\)_.*/\1/')
|
||||
local testDetailTag="<div id=\"${test}-failure\" style=\"display:none;\">"
|
||||
local filename=$(basename ${file})
|
||||
local linkTag="<p><li><a href=\"$relativePathToResource\/$filename\" target=\"_blank\"><b>$titleOfLink<\/b>: $filename<\/a><\/li><\/p>"
|
||||
sed -i "s/${testDetailTag}/${testDetailTag}${linkTag}/" ${FAILSAFE_REPORT}
|
||||
done
|
||||
}
|
||||
|
||||
storeTestReport() {
|
||||
mkdir -p ${TMP_DIR}/webdriver
|
||||
local report="${TMP_DIR}/webdriver/report$(date +%s).zip"
|
||||
|
||||
rm -rf ${TMP_DIR}/webdriver/tmp
|
||||
mkdir target/suite
|
||||
if [[ -f ${TMP_SUITE_PATH} ]]; then
|
||||
cp ${TMP_SUITE_PATH} target/suite;
|
||||
fi
|
||||
zip -qr ${report} target/screenshots target/htmldumps target/workspace-logs target/webdriver-logs target/site target/failsafe-reports target/log target/bin target/suite
|
||||
|
||||
echo -e "[TEST] Tests results and reports are saved to ${BLUE}${report}${NO_COLOUR}"
|
||||
echo "[TEST]"
|
||||
echo "[TEST] If target directory is accidentally cleaned it is possible to restore it: "
|
||||
echo -e "[TEST] \t${BLUE}rm -rf ${CUR_DIR}/target && unzip -q ${report} -d ${CUR_DIR}${NO_COLOUR}"
|
||||
echo "[TEST]"
|
||||
}
|
||||
|
||||
checkBuild() {
|
||||
mvn package ${MAVEN_OPTIONS}
|
||||
[[ $? != 0 ]] && { exit 1; }
|
||||
}
|
||||
|
||||
prepareToFirstRun() {
|
||||
checkIfProductIsRun
|
||||
cleanUpEnvironment
|
||||
initRunMode
|
||||
}
|
||||
|
||||
getKeycloakContainerId() {
|
||||
if [[ "${CHE_INFRASTRUCTURE}" == "openshift" ]]; then
|
||||
echo $(docker ps | grep 'keycloak_keycloak-' | cut -d ' ' -f1)
|
||||
else
|
||||
echo $(docker ps | grep che_keycloak | cut -d ' ' -f1)
|
||||
fi
|
||||
}
|
||||
|
||||
testProduct() {
|
||||
runTests
|
||||
|
||||
if [[ ${RERUN_ATTEMPTS} > 0 ]]; then
|
||||
MAVEN_OPTIONS="${MAVEN_OPTIONS} -o"
|
||||
rerunTests 1 $@
|
||||
fi
|
||||
}
|
||||
|
||||
run() {
|
||||
if [[ $@ =~ --help ]]; then
|
||||
printHelp
|
||||
exit
|
||||
fi
|
||||
|
||||
START_TIME=$(date +%s)
|
||||
|
||||
trap cleanUpEnvironment EXIT
|
||||
|
||||
initVariables
|
||||
init
|
||||
extractMavenOptions $@
|
||||
checkBuild
|
||||
|
||||
checkParameters $@
|
||||
defineOperationSystemSpecificVariables
|
||||
defineRunMode $@
|
||||
|
||||
defineTestsScope $@
|
||||
applyCustomOptions $@
|
||||
|
||||
if [[ ${COMPARE_WITH_CI} == true ]]; then
|
||||
fetchActualResults $@
|
||||
else
|
||||
prepareToFirstRun
|
||||
testProduct $@
|
||||
fi
|
||||
|
||||
analyseTestsResults $@
|
||||
|
||||
if [[ ${COMPARE_WITH_CI} == false ]]; then
|
||||
generateFailSafeReport
|
||||
printProposals $@
|
||||
storeTestReport
|
||||
printElapsedTime
|
||||
fi
|
||||
}
|
||||
|
||||
run "$@"
|
||||
|
||||
if [[ ${TOTAL_FAILS} -ne 0 && ${FAIL_SCRIPT_ON_FAILED_TESTS} == true ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -1,168 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
||||
SPDX-License-Identifier: EPL-2.0
|
||||
|
||||
Contributors:
|
||||
Red Hat, Inc. - initial API and implementation
|
||||
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>che-selenium-parent</artifactId>
|
||||
<groupId>org.eclipse.che.selenium</groupId>
|
||||
<version>7.29.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>che-selenium-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Che Legacy E2E :: Core</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-assistedinject</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-dto</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-factory-shared</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-model</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-ssh-shared</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-user-shared</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-workspace-shared</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-annotations</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-json</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-lang</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.multiuser</groupId>
|
||||
<artifactId>che-multiuser-api-organization-shared</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.multiuser</groupId>
|
||||
<artifactId>che-multiuser-api-permission-shared</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.kohsuke</groupId>
|
||||
<artifactId>github-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.seleniumhq.selenium</groupId>
|
||||
<artifactId>selenium-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.seleniumhq.selenium</groupId>
|
||||
<artifactId>selenium-chrome-driver</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.seleniumhq.selenium</groupId>
|
||||
<artifactId>selenium-remote-driver</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.seleniumhq.selenium</groupId>
|
||||
<artifactId>selenium-support</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-inject</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-testng</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>bin</directory>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/java</directory>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -1,383 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.eclipse.che.selenium.core.constant.TestTimeoutsConstants.APPLICATION_START_TIMEOUT_SEC;
|
||||
import static org.eclipse.che.selenium.core.constant.TestTimeoutsConstants.LOADER_TIMEOUT_SEC;
|
||||
import static org.eclipse.che.selenium.core.utils.WaitUtils.sleepQuietly;
|
||||
import static org.openqa.selenium.support.ui.ExpectedConditions.frameToBeAvailableAndSwitchToIt;
|
||||
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.name.Named;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.ForbiddenException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.UnauthorizedException;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonRequestFactory;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
import org.eclipse.che.selenium.core.constant.TestBrowser;
|
||||
import org.eclipse.che.selenium.core.utils.DockerUtil;
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.Dimension;
|
||||
import org.openqa.selenium.JavascriptExecutor;
|
||||
import org.openqa.selenium.OutputType;
|
||||
import org.openqa.selenium.TakesScreenshot;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebDriverException;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.chrome.ChromeOptions;
|
||||
import org.openqa.selenium.interactions.HasInputDevices;
|
||||
import org.openqa.selenium.interactions.Keyboard;
|
||||
import org.openqa.selenium.interactions.Mouse;
|
||||
import org.openqa.selenium.logging.LogType;
|
||||
import org.openqa.selenium.logging.LoggingPreferences;
|
||||
import org.openqa.selenium.remote.CapabilityType;
|
||||
import org.openqa.selenium.remote.DesiredCapabilities;
|
||||
import org.openqa.selenium.remote.RemoteWebDriver;
|
||||
import org.openqa.selenium.support.ui.ExpectedCondition;
|
||||
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Wrapper for {@link WebDriver} to have ability to use in Guice container.
|
||||
*
|
||||
* @author Anatolii Bazko
|
||||
*/
|
||||
@Singleton
|
||||
public class SeleniumWebDriver
|
||||
implements Closeable, WebDriver, JavascriptExecutor, TakesScreenshot, HasInputDevices {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SeleniumWebDriver.class);
|
||||
private static final int MAX_ATTEMPTS = 5;
|
||||
private static final int DELAY_IN_SECONDS = 5;
|
||||
|
||||
private TestBrowser browser;
|
||||
private boolean gridMode;
|
||||
private String gridNodeContainerId;
|
||||
private String webDriverPort;
|
||||
private final RemoteWebDriver driver;
|
||||
private final HttpJsonRequestFactory httpJsonRequestFactory;
|
||||
private final DockerUtil dockerUtil;
|
||||
private final String downloadDir;
|
||||
|
||||
@Inject
|
||||
public SeleniumWebDriver(
|
||||
@Named("sys.browser") TestBrowser browser,
|
||||
@Named("sys.driver.port") String webDriverPort,
|
||||
@Named("sys.grid.mode") boolean gridMode,
|
||||
HttpJsonRequestFactory httpJsonRequestFactory,
|
||||
DockerUtil dockerUtil,
|
||||
@Named("tests.tmp_dir") String downloadDir) {
|
||||
this.browser = browser;
|
||||
this.webDriverPort = webDriverPort;
|
||||
this.gridMode = gridMode;
|
||||
this.httpJsonRequestFactory = httpJsonRequestFactory;
|
||||
this.dockerUtil = dockerUtil;
|
||||
this.downloadDir = downloadDir;
|
||||
|
||||
try {
|
||||
URL webDriverUrl =
|
||||
new URL(format("http://localhost:%s%s", webDriverPort, gridMode ? "/wd/hub" : ""));
|
||||
this.driver = createDriver(webDriverUrl);
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException("Error of construction URL to web driver.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void get(String url) {
|
||||
driver.get(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentUrl() {
|
||||
return driver.getCurrentUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return driver.getTitle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WebElement> findElements(By by) {
|
||||
return driver.findElements(by);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebElement findElement(By by) {
|
||||
return driver.findElement(by);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPageSource() {
|
||||
return driver.getPageSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
driver.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void quit() {
|
||||
driver.quit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getWindowHandles() {
|
||||
return driver.getWindowHandles();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWindowHandle() {
|
||||
return driver.getWindowHandle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetLocator switchTo() {
|
||||
return driver.switchTo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Navigation navigate() {
|
||||
return driver.navigate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Options manage() {
|
||||
return driver.manage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object executeScript(String script, Object... args) {
|
||||
return driver.executeScript(script, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object executeAsyncScript(String script, Object... args) {
|
||||
return driver.executeAsyncScript(script, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> X getScreenshotAs(OutputType<X> target) throws WebDriverException {
|
||||
return driver.getScreenshotAs(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Keyboard getKeyboard() {
|
||||
return driver.getKeyboard();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mouse getMouse() {
|
||||
return driver.getMouse();
|
||||
}
|
||||
|
||||
private RemoteWebDriver createDriver(URL webDriverUrl) {
|
||||
for (int i = 1; ; ) {
|
||||
try {
|
||||
return doCreateDriver(webDriverUrl);
|
||||
} catch (WebDriverException e) {
|
||||
if (i++ >= MAX_ATTEMPTS) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
sleepQuietly(DELAY_IN_SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read supported version info from official site.
|
||||
*
|
||||
* @param webDriverOfficialNotes address of official page with Google driver info
|
||||
* @return string with supported version range (for example, "36-40"), or null if version info
|
||||
* doesn't found inside the official notes.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Nullable
|
||||
private String readSupportedVersionInfoForGoogleDriver(URL webDriverOfficialNotes)
|
||||
throws IOException {
|
||||
try (Scanner scanner = new Scanner(webDriverOfficialNotes.openStream(), "UTF-8")) {
|
||||
while (scanner.hasNextLine()) {
|
||||
String versionLine = scanner.findInLine("Supports Chrome v([\\d-]+)");
|
||||
if (versionLine != null) {
|
||||
return scanner.match().group(1);
|
||||
}
|
||||
|
||||
scanner.nextLine();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private RemoteWebDriver doCreateDriver(URL webDriverUrl) {
|
||||
DesiredCapabilities capability;
|
||||
|
||||
switch (browser) {
|
||||
case GOOGLE_CHROME:
|
||||
LoggingPreferences loggingPreferences = new LoggingPreferences();
|
||||
loggingPreferences.enable(LogType.PERFORMANCE, Level.ALL);
|
||||
loggingPreferences.enable(LogType.BROWSER, Level.ALL);
|
||||
|
||||
ChromeOptions options = new ChromeOptions();
|
||||
options.addArguments("--no-sandbox");
|
||||
options.addArguments("--dns-prefetch-disable");
|
||||
options.addArguments("--ignore-certificate-errors");
|
||||
|
||||
// set parameters required for automatic download capability
|
||||
Map<String, Object> chromePrefs = new HashMap<>();
|
||||
chromePrefs.put("download.default_directory", downloadDir);
|
||||
chromePrefs.put("download.prompt_for_download", false);
|
||||
chromePrefs.put("download.directory_upgrade", true);
|
||||
chromePrefs.put("safebrowsing.enabled", true);
|
||||
chromePrefs.put("profile.default_content_settings.popups", 0);
|
||||
chromePrefs.put("plugins.plugins_disabled", "['Chrome PDF Viewer']");
|
||||
options.setExperimentalOption("prefs", chromePrefs);
|
||||
|
||||
capability = DesiredCapabilities.chrome();
|
||||
capability.setCapability(ChromeOptions.CAPABILITY, options);
|
||||
capability.setCapability(CapabilityType.LOGGING_PREFS, loggingPreferences);
|
||||
capability.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
|
||||
break;
|
||||
|
||||
default:
|
||||
capability = DesiredCapabilities.firefox();
|
||||
capability.setCapability("dom.max_script_run_time", 240);
|
||||
capability.setCapability("dom.max_chrome_script_run_time", 240);
|
||||
}
|
||||
|
||||
RemoteWebDriver driver = new RemoteWebDriver(webDriverUrl, capability);
|
||||
if (driver.getErrorHandler().isIncludeServerErrors()
|
||||
&& driver.getCapabilities().getCapability("message") != null) {
|
||||
String errorMessage =
|
||||
format(
|
||||
"Web driver creation error occurred: %s",
|
||||
driver.getCapabilities().getCapability("message"));
|
||||
LOG.error(errorMessage);
|
||||
throw new RuntimeException(errorMessage);
|
||||
}
|
||||
|
||||
driver.manage().window().setSize(new Dimension(1920, 1080));
|
||||
|
||||
return driver;
|
||||
}
|
||||
|
||||
/** wait while in a browser appears more the 1 window */
|
||||
public void waitOpenedSomeWin() {
|
||||
new WebDriverWait(this, 30)
|
||||
.until(
|
||||
(ExpectedCondition<Boolean>)
|
||||
input -> {
|
||||
Set<String> driverWindows = getWindowHandles();
|
||||
return (driverWindows.size() > 1);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate name of workspace from browser url cut symbols from end of slash symbol ("/") to end
|
||||
*/
|
||||
public String getWorkspaceNameFromBrowserUrl() {
|
||||
String currentUrl = getCurrentUrl();
|
||||
return currentUrl.substring(currentUrl.lastIndexOf("/") + 1, currentUrl.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* switch to the next browser window (this means that if opened 2 windows, and we are in the
|
||||
* window 1, we will be switched into the window 2 )
|
||||
*
|
||||
* @param currentWindowHandler
|
||||
*/
|
||||
public void switchToNoneCurrentWindow(String currentWindowHandler) {
|
||||
waitOpenedSomeWin();
|
||||
for (String handle : getWindowHandles()) {
|
||||
if (!currentWindowHandler.equals(handle)) {
|
||||
switchTo().window(handle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void switchFromDashboardIframeToIde() {
|
||||
switchFromDashboardIframeToIde(APPLICATION_START_TIMEOUT_SEC);
|
||||
}
|
||||
|
||||
public void switchFromDashboardIframeToIde(int timeout) {
|
||||
wait(timeout).until(visibilityOfElementLocated(By.id("ide-application-iframe")));
|
||||
|
||||
wait(LOADER_TIMEOUT_SEC)
|
||||
.until(
|
||||
(ExpectedCondition<Boolean>)
|
||||
driver ->
|
||||
(((JavascriptExecutor) driver)
|
||||
.executeScript("return angular.element('body').scope().showIDE"))
|
||||
.toString()
|
||||
.equals("true"));
|
||||
|
||||
wait(timeout).until(frameToBeAvailableAndSwitchToIt(By.id("ide-application-iframe")));
|
||||
}
|
||||
|
||||
private WebDriverWait wait(int timeOutInSeconds) {
|
||||
return new WebDriverWait(this, timeOutInSeconds);
|
||||
}
|
||||
|
||||
public String getGridNodeContainerId() throws IOException {
|
||||
if (!gridMode) {
|
||||
throw new UnsupportedOperationException("We can't get grid node container id in local mode.");
|
||||
}
|
||||
|
||||
if (gridNodeContainerId == null) {
|
||||
String getGridNodeInfoUrl =
|
||||
format(
|
||||
"http://localhost:%s/grid/api/testsession?session=%s",
|
||||
webDriverPort, driver.getSessionId());
|
||||
|
||||
Map<String, String> gridNodeInfo;
|
||||
try {
|
||||
gridNodeInfo = httpJsonRequestFactory.fromUrl(getGridNodeInfoUrl).request().asProperties();
|
||||
} catch (ServerException
|
||||
| UnauthorizedException
|
||||
| ForbiddenException
|
||||
| NotFoundException
|
||||
| ConflictException
|
||||
| BadRequestException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
|
||||
if (!gridNodeInfo.containsKey("proxyId")) {
|
||||
throw new IOException("Proxy ID of grid node wasn't found.");
|
||||
}
|
||||
|
||||
URL proxyId = new URL(gridNodeInfo.get("proxyId"));
|
||||
gridNodeContainerId = dockerUtil.findGridNodeContainerByIp(proxyId.getHost());
|
||||
}
|
||||
|
||||
return gridNodeContainerId;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core;
|
||||
|
||||
/** @author Dmytro Nochevnov */
|
||||
public interface TestGroup {
|
||||
String MULTIUSER = "multiuser";
|
||||
String SINGLEUSER = "singleuser";
|
||||
String OPENSHIFT = "openshift";
|
||||
String DOCKER = "docker";
|
||||
String GITHUB = "github";
|
||||
String OSIO = "osio";
|
||||
String K8S = "k8s";
|
||||
String UNDER_REPAIR = "under_repair";
|
||||
String FLAKY = "flaky";
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.action;
|
||||
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.interactions.Actions;
|
||||
|
||||
/**
|
||||
* Main interface for producing new instances of {@link Actions}.
|
||||
*
|
||||
* @author Vlad Zhukovskyi
|
||||
*/
|
||||
public interface ActionsFactory {
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@link Actions} based on input {@code webDriver}
|
||||
*
|
||||
* @param webDriver instance of {@link WebDriver}
|
||||
* @return a new instance of {@link Actions}
|
||||
*/
|
||||
Actions createAction(WebDriver webDriver);
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.action;
|
||||
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.interactions.Actions;
|
||||
|
||||
/**
|
||||
* Generic actions. Default extension of the {@link Actions} which actually doesn't modify a
|
||||
* behavior of internal {@link Actions}.
|
||||
*
|
||||
* @author Vlad Zhukovskyi
|
||||
* @see Actions
|
||||
*/
|
||||
public class GenericActions extends PlatformBasedActions {
|
||||
public GenericActions(WebDriver driver) {
|
||||
super(driver);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CharSequence[] modifyCharSequence(CharSequence... keysToSend) {
|
||||
return keysToSend;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.action;
|
||||
|
||||
import com.google.inject.Singleton;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.interactions.Actions;
|
||||
|
||||
/**
|
||||
* Default actions factory for the generic operation system, linux, windows, etc.
|
||||
*
|
||||
* @author Vlad Zhukovskyi
|
||||
* @see GenericActions
|
||||
* @see ActionsFactory
|
||||
*/
|
||||
@Singleton
|
||||
public class GenericActionsFactory implements ActionsFactory {
|
||||
@Override
|
||||
public Actions createAction(WebDriver webDriver) {
|
||||
return new GenericActions(webDriver);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.action;
|
||||
|
||||
import static com.google.common.collect.Lists.newArrayList;
|
||||
|
||||
import java.util.List;
|
||||
import org.openqa.selenium.Keys;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.interactions.Actions;
|
||||
import org.openqa.selenium.interactions.SendKeysAction;
|
||||
|
||||
/**
|
||||
* Mac OS based extension of {@link Actions}. Modifies the behavior of {@link SendKeysAction} by
|
||||
* replacing key press calls. Unfortunately this may need for that reason, that some of selenium
|
||||
* tests may send:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link Keys#END}
|
||||
* <li>{@link Keys#HOME}
|
||||
* <li>{@link Keys#PAGE_DOWN}
|
||||
* <li>{@link Keys#PAGE_UP}
|
||||
* </ul>
|
||||
*
|
||||
* which don't work in current operation system. So some tests may fail. but for above key press in
|
||||
* Mac OS there are equivalence:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Command+Right
|
||||
* <li>Command+Left
|
||||
* <li>Command+Down
|
||||
* <li>Command+Up
|
||||
* </ul>
|
||||
*
|
||||
* and method may look for non-working key presses from the input array of {@link CharSequence} and
|
||||
* replace them with equivalence. So for test it will looks like it runs transparently on any OS.
|
||||
*
|
||||
* <p>For more information see {@link #modifyCharSequence(CharSequence...)}
|
||||
*
|
||||
* @author Vlad Zhukovskyi
|
||||
*/
|
||||
public class MacOSActions extends PlatformBasedActions {
|
||||
public MacOSActions(WebDriver driver) {
|
||||
super(driver);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CharSequence[] modifyCharSequence(CharSequence... keysToSend) {
|
||||
final List<CharSequence> modKeysToSend = newArrayList();
|
||||
|
||||
for (CharSequence charSequence : keysToSend) {
|
||||
final String key = charSequence.toString();
|
||||
|
||||
if (Keys.END.toString().equals(key)) {
|
||||
modKeysToSend.add(Keys.chord(Keys.COMMAND, Keys.RIGHT));
|
||||
} else if (Keys.HOME.toString().equals(key)) {
|
||||
modKeysToSend.add(Keys.chord(Keys.COMMAND, Keys.LEFT));
|
||||
} else if (Keys.PAGE_UP.toString().equals(key)) {
|
||||
modKeysToSend.add(Keys.chord(Keys.COMMAND, Keys.UP));
|
||||
} else if (Keys.PAGE_DOWN.toString().equals(key)) {
|
||||
modKeysToSend.add(Keys.chord(Keys.COMMAND, Keys.DOWN));
|
||||
} else {
|
||||
modKeysToSend.add(charSequence);
|
||||
}
|
||||
}
|
||||
|
||||
return modKeysToSend.toArray(new CharSequence[modKeysToSend.size()]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.action;
|
||||
|
||||
import com.google.inject.Singleton;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.interactions.Actions;
|
||||
|
||||
/**
|
||||
* Mac OS based actions factory.
|
||||
*
|
||||
* @author Vlad Zhukovskyi
|
||||
* @see MacOSActions
|
||||
* @see ActionsFactory
|
||||
*/
|
||||
@Singleton
|
||||
public class MacOSActionsFactory implements ActionsFactory {
|
||||
|
||||
@Override
|
||||
public Actions createAction(WebDriver webDriver) {
|
||||
return new MacOSActions(webDriver);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.action;
|
||||
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.interactions.Actions;
|
||||
import org.openqa.selenium.interactions.SendKeysAction;
|
||||
import org.openqa.selenium.internal.Locatable;
|
||||
|
||||
/**
|
||||
* Abstract class for platform based actions. Generify the interface for using selenium action
|
||||
* independently from the OS on which tests are running.
|
||||
*
|
||||
* @author Vlad Zhukovskyi
|
||||
*/
|
||||
public abstract class PlatformBasedActions extends Actions {
|
||||
|
||||
public PlatformBasedActions(WebDriver driver) {
|
||||
super(driver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Actions sendKeys(WebElement element, CharSequence... keysToSend) {
|
||||
action.addAction(
|
||||
new SendKeysAction(keyboard, mouse, (Locatable) element, modifyCharSequence(keysToSend)));
|
||||
return this;
|
||||
}
|
||||
|
||||
protected abstract CharSequence[] modifyCharSequence(CharSequence... keysToSend);
|
||||
}
|
||||
|
|
@ -1,366 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.lang.String.valueOf;
|
||||
import static org.eclipse.che.api.core.model.workspace.WorkspaceStatus.STOPPED;
|
||||
import static org.eclipse.che.api.core.model.workspace.WorkspaceStatus.STOPPING;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.model.workspace.Workspace;
|
||||
import org.eclipse.che.api.core.model.workspace.WorkspaceStatus;
|
||||
import org.eclipse.che.api.core.model.workspace.runtime.Machine;
|
||||
import org.eclipse.che.api.core.model.workspace.runtime.Server;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonRequestFactory;
|
||||
import org.eclipse.che.api.workspace.shared.Constants;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceDto;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
import org.eclipse.che.selenium.core.constant.TestTimeoutsConstants;
|
||||
import org.eclipse.che.selenium.core.provider.TestApiEndpointUrlProvider;
|
||||
import org.eclipse.che.selenium.core.requestfactory.TestUserHttpJsonRequestFactoryCreator;
|
||||
import org.eclipse.che.selenium.core.user.TestUser;
|
||||
import org.eclipse.che.selenium.core.utils.WaitUtils;
|
||||
import org.eclipse.che.selenium.core.workspace.MemoryMeasure;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Musienko Maxim
|
||||
* @author Dmytro Nochevnov
|
||||
*/
|
||||
public abstract class AbstractTestWorkspaceServiceClient implements TestWorkspaceServiceClient {
|
||||
|
||||
private static final Logger LOG =
|
||||
LoggerFactory.getLogger(AbstractTestWorkspaceServiceClient.class);
|
||||
|
||||
protected final TestApiEndpointUrlProvider apiEndpointProvider;
|
||||
protected final HttpJsonRequestFactory requestFactory;
|
||||
|
||||
public AbstractTestWorkspaceServiceClient(
|
||||
TestApiEndpointUrlProvider apiEndpointProvider, HttpJsonRequestFactory requestFactory) {
|
||||
this.apiEndpointProvider = apiEndpointProvider;
|
||||
this.requestFactory = requestFactory;
|
||||
}
|
||||
|
||||
public AbstractTestWorkspaceServiceClient(
|
||||
TestApiEndpointUrlProvider apiEndpointProvider,
|
||||
TestUserHttpJsonRequestFactoryCreator userHttpJsonRequestFactoryCreator,
|
||||
TestUser testUser) {
|
||||
this(apiEndpointProvider, userHttpJsonRequestFactoryCreator.create(testUser));
|
||||
}
|
||||
|
||||
protected String getBaseUrl() {
|
||||
return apiEndpointProvider.get() + "workspace";
|
||||
}
|
||||
|
||||
/** Returns the list of workspaces names that belongs to the user. */
|
||||
@Override
|
||||
public List<String> getAll() throws Exception {
|
||||
List<WorkspaceDto> workspaces =
|
||||
requestFactory.fromUrl(getBaseUrl()).request().asList(WorkspaceDto.class);
|
||||
return workspaces.stream().map(ws -> ws.getConfig().getName()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/** Returns the number of workspaces that belongs to the user. */
|
||||
@Override
|
||||
public int getWorkspacesCount() throws Exception {
|
||||
List<WorkspaceDto> workspaces =
|
||||
requestFactory.fromUrl(getBaseUrl()).request().asList(WorkspaceDto.class);
|
||||
return workspaces.size();
|
||||
}
|
||||
|
||||
/** Stops workspace. */
|
||||
@Override
|
||||
public void stop(String workspaceName, String userName) throws Exception {
|
||||
sendStopRequest(workspaceName, userName);
|
||||
waitStatus(workspaceName, userName, STOPPED);
|
||||
}
|
||||
|
||||
/** Returns workspace of default user by its name. */
|
||||
@Override
|
||||
public Workspace getByName(String workspace, String username) throws Exception {
|
||||
return requestFactory
|
||||
.fromUrl(getNameBasedUrl(workspace, username))
|
||||
.request()
|
||||
.asDto(WorkspaceDto.class);
|
||||
}
|
||||
|
||||
/** Indicates if workspace exists. */
|
||||
@Override
|
||||
public boolean exists(String workspace, String username) throws Exception {
|
||||
try {
|
||||
requestFactory.fromUrl(getNameBasedUrl(workspace, username)).request();
|
||||
} catch (NotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Deletes workspace of default user. */
|
||||
@Override
|
||||
public void delete(String workspaceName, String userName) throws Exception {
|
||||
if (!exists(workspaceName, userName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Workspace workspace = getByName(workspaceName, userName);
|
||||
if (workspace.getStatus() == STOPPING) {
|
||||
waitStatus(workspaceName, userName, STOPPED);
|
||||
} else if (workspace.getStatus() != STOPPED) {
|
||||
stop(workspaceName, userName);
|
||||
}
|
||||
|
||||
requestFactory.fromUrl(getIdBasedUrl(workspace.getId())).useDeleteMethod().request();
|
||||
|
||||
WaitUtils.waitSuccessCondition(
|
||||
() -> {
|
||||
try {
|
||||
return !exists(workspaceName, userName);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(
|
||||
format(
|
||||
"Error of waiting on workspace name='%s', id='%s', username='%s' removal.",
|
||||
workspaceName, workspace.getId(), userName),
|
||||
e);
|
||||
}
|
||||
},
|
||||
TestTimeoutsConstants.PREPARING_WS_TIMEOUT_SEC,
|
||||
500,
|
||||
TimeUnit.SECONDS);
|
||||
|
||||
LOG.info(
|
||||
"Workspace name='{}', id='{}', username='{}' removed",
|
||||
workspaceName,
|
||||
workspace.getId(),
|
||||
userName);
|
||||
}
|
||||
|
||||
/** Waits workspace is started. */
|
||||
@Override
|
||||
public void waitWorkspaceStart(String workspaceName, String userName) throws Exception {
|
||||
WaitUtils.sleepQuietly(5); // delay 5 secs to obtain starting status for sure
|
||||
WaitUtils.waitSuccessCondition(
|
||||
() -> {
|
||||
WorkspaceStatus status;
|
||||
try {
|
||||
status = getByName(workspaceName, userName).getStatus();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
switch (status) {
|
||||
case RUNNING:
|
||||
return true;
|
||||
|
||||
case STARTING:
|
||||
return false;
|
||||
|
||||
default:
|
||||
throw new RuntimeException(
|
||||
format("Workspace with name '%s' didn't start", workspaceName));
|
||||
}
|
||||
},
|
||||
600,
|
||||
1000,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/** Waits needed status. */
|
||||
@Override
|
||||
public void waitStatus(String workspaceName, String userName, WorkspaceStatus expectedStatus)
|
||||
throws Exception {
|
||||
waitStatus(workspaceName, userName, expectedStatus, 600);
|
||||
}
|
||||
|
||||
public void waitStatus(
|
||||
String workspaceName, String userName, WorkspaceStatus expectedStatus, int timeoutSeconds)
|
||||
throws Exception {
|
||||
WaitUtils.waitSuccessCondition(
|
||||
() -> {
|
||||
try {
|
||||
if (getByName(workspaceName, userName).getStatus() == expectedStatus) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
timeoutSeconds,
|
||||
1000,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/** Sends start workspace request. */
|
||||
@Override
|
||||
public void sendStartRequest(String workspaceId, String workspaceName) throws Exception {
|
||||
requestFactory
|
||||
.fromUrl(getIdBasedUrl(workspaceId) + "/runtime")
|
||||
.addQueryParam("environment", workspaceName)
|
||||
.usePostMethod()
|
||||
.request();
|
||||
}
|
||||
|
||||
/** Gets workspace by its id. */
|
||||
@Override
|
||||
public WorkspaceDto getById(String workspaceId) throws Exception {
|
||||
return requestFactory.fromUrl(getIdBasedUrl(workspaceId)).request().asDto(WorkspaceDto.class);
|
||||
}
|
||||
|
||||
/** Gets workspace status by id. */
|
||||
@Override
|
||||
public WorkspaceStatus getStatus(String workspaceId) throws Exception {
|
||||
return getById(workspaceId).getStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return server URL related with defined port
|
||||
*
|
||||
* @deprecated use {@link #getServerFromDevMachineBySymbolicName(String, String)} to retrieve
|
||||
* server URL from instead
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
@Nullable
|
||||
public String getServerAddressByPort(String workspaceId, int port) throws Exception {
|
||||
Workspace workspace = getById(workspaceId);
|
||||
ensureRunningStatus(workspace);
|
||||
|
||||
Map<String, ? extends Machine> machines = workspace.getRuntime().getMachines();
|
||||
for (Machine machine : machines.values()) {
|
||||
if (containsWsAgentServer(machine)) {
|
||||
return machine.getServers().get(valueOf(port) + "/tcp").getUrl();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return ServerDto object from runtime by it's symbolic name
|
||||
*
|
||||
* @param workspaceId workspace id of current user
|
||||
* @param serverName server name
|
||||
* @return ServerDto object
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
public Server getServerFromDevMachineBySymbolicName(String workspaceId, String serverName)
|
||||
throws Exception {
|
||||
Workspace workspace =
|
||||
requestFactory.fromUrl(getIdBasedUrl(workspaceId)).request().asDto(WorkspaceDto.class);
|
||||
|
||||
ensureRunningStatus(workspace);
|
||||
|
||||
Map<String, ? extends Machine> machines = workspace.getRuntime().getMachines();
|
||||
for (Machine machine : machines.values()) {
|
||||
if (containsWsAgentServer(machine)) {
|
||||
return machine.getServers().get(serverName);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure workspace has running status, or throw IllegalStateException.
|
||||
*
|
||||
* @param workspace workspace description to get status and id.
|
||||
* @throws IllegalStateException if workspace with certain workspaceId doesn't have RUNNING
|
||||
* status.
|
||||
*/
|
||||
@Override
|
||||
public void ensureRunningStatus(Workspace workspace) throws IllegalStateException {
|
||||
if (workspace.getStatus() != WorkspaceStatus.RUNNING) {
|
||||
throw new IllegalStateException(
|
||||
format(
|
||||
"Workspace with id='%s' should has '%s' status, but its actual state='%s'",
|
||||
workspace.getId(), WorkspaceStatus.RUNNING, workspace.getStatus()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete workspaces which could be created from factory
|
||||
*
|
||||
* @param originalName name workspace which was used to create factory
|
||||
*/
|
||||
@Override
|
||||
public void deleteFactoryWorkspaces(String originalName, String username) throws Exception {
|
||||
String workspace2delete = originalName;
|
||||
for (int i = 1; ; i++) {
|
||||
if (!exists(workspace2delete, username)) {
|
||||
break;
|
||||
}
|
||||
|
||||
delete(workspace2delete, username);
|
||||
workspace2delete = originalName + "_" + i;
|
||||
}
|
||||
}
|
||||
|
||||
// ================= //
|
||||
// PRIVATE METHODS //
|
||||
// ================= //
|
||||
|
||||
/** Sends stop workspace request. */
|
||||
private void sendStopRequest(String workspaceName, String userName) throws Exception {
|
||||
if (!exists(workspaceName, userName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Workspace workspace = getByName(workspaceName, userName);
|
||||
String apiUrl = getIdBasedUrl(workspace.getId()) + "/runtime/";
|
||||
|
||||
requestFactory.fromUrl(apiUrl).useDeleteMethod().request();
|
||||
}
|
||||
|
||||
protected String getNameBasedUrl(String workspaceName, String username) {
|
||||
return getBaseUrl() + "/" + username + "/" + workspaceName;
|
||||
}
|
||||
|
||||
protected String getIdBasedUrl(String workspaceId) {
|
||||
return getBaseUrl() + "/" + workspaceId;
|
||||
}
|
||||
|
||||
protected long convertToByte(int numberOfMemValue, MemoryMeasure desiredMeasureMemory) {
|
||||
long calculatedValue = 0;
|
||||
// represents values of bytes in 1 megabyte (2x20)
|
||||
final long MEGABYTES_CONST = 1048576;
|
||||
|
||||
// represents values of bytes in 1 gygabyte (2x30)
|
||||
final long GYGABYTES_CONST = 1073741824;
|
||||
|
||||
switch (desiredMeasureMemory) {
|
||||
case MB:
|
||||
calculatedValue = numberOfMemValue * MEGABYTES_CONST;
|
||||
break;
|
||||
case GB:
|
||||
calculatedValue = numberOfMemValue * GYGABYTES_CONST;
|
||||
break;
|
||||
}
|
||||
return calculatedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether provided {@link Machine} contains wsagent server.
|
||||
*
|
||||
* @param machine machine to check
|
||||
* @return true when wsagent server is found in provided machine, false otherwise
|
||||
*/
|
||||
public static boolean containsWsAgentServer(Machine machine) {
|
||||
return machine.getServers().keySet().contains(Constants.SERVER_WS_AGENT_HTTP_REFERENCE);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.selenium.core.provider.TestApiEndpointUrlProvider;
|
||||
import org.eclipse.che.selenium.core.requestfactory.TestUserHttpJsonRequestFactory;
|
||||
|
||||
/** @author Anton Korneta */
|
||||
@Singleton
|
||||
public class CheTestUserServiceClient extends TestUserServiceClientImpl {
|
||||
|
||||
@Inject
|
||||
public CheTestUserServiceClient(
|
||||
TestApiEndpointUrlProvider apiEndpointProvider,
|
||||
TestUserHttpJsonRequestFactory requestFactory) {
|
||||
super(apiEndpointProvider, requestFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create(String name, String email, String password)
|
||||
throws BadRequestException, ConflictException, ServerException {}
|
||||
|
||||
@Override
|
||||
public void remove(String id) throws ServerException, ConflictException {}
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.google.inject.assistedinject.AssistedInject;
|
||||
import org.eclipse.che.api.core.model.workspace.Workspace;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonRequestFactory;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceConfigDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceDto;
|
||||
import org.eclipse.che.selenium.core.provider.TestApiEndpointUrlProvider;
|
||||
import org.eclipse.che.selenium.core.requestfactory.TestUserHttpJsonRequestFactoryCreator;
|
||||
import org.eclipse.che.selenium.core.user.TestUser;
|
||||
import org.eclipse.che.selenium.core.workspace.MemoryMeasure;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class CheTestWorkspaceServiceClient extends AbstractTestWorkspaceServiceClient {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(CheTestWorkspaceServiceClient.class);
|
||||
|
||||
@Inject
|
||||
public CheTestWorkspaceServiceClient(
|
||||
TestApiEndpointUrlProvider apiEndpointProvider, HttpJsonRequestFactory requestFactory) {
|
||||
super(apiEndpointProvider, requestFactory);
|
||||
}
|
||||
|
||||
@AssistedInject
|
||||
public CheTestWorkspaceServiceClient(
|
||||
TestApiEndpointUrlProvider apiEndpointProvider,
|
||||
TestUserHttpJsonRequestFactoryCreator userHttpJsonRequestFactoryCreator,
|
||||
@Assisted TestUser testUser) {
|
||||
super(apiEndpointProvider, userHttpJsonRequestFactoryCreator, testUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Workspace createWorkspace(
|
||||
String workspaceName, int memory, MemoryMeasure memoryUnit, WorkspaceConfigDto workspace)
|
||||
throws Exception {
|
||||
workspace.setName(workspaceName);
|
||||
workspace.setDefaultEnv(workspaceName);
|
||||
WorkspaceDto workspaceDto =
|
||||
requestFactory
|
||||
.fromUrl(getBaseUrl())
|
||||
.usePostMethod()
|
||||
.setBody(workspace)
|
||||
.request()
|
||||
.asDto(WorkspaceDto.class);
|
||||
|
||||
LOG.info("Workspace name='{}' and id='{}' created", workspaceName, workspaceDto.getId());
|
||||
|
||||
return workspaceDto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(String workspaceId, String workspaceName, TestUser workspaceOwner)
|
||||
throws Exception {
|
||||
sendStartRequest(workspaceId, workspaceName);
|
||||
waitWorkspaceStart(workspaceName, workspaceOwner.getName());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
import org.eclipse.che.dto.shared.DTO;
|
||||
|
||||
@DTO
|
||||
public class GitHubKey {
|
||||
private int id;
|
||||
private String key;
|
||||
private String url;
|
||||
private String title;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
/** @author Anatolii Bazko */
|
||||
public interface TestAuthServiceClient {
|
||||
|
||||
/** Logs user into the system and returns auth token. */
|
||||
String login(String username, String password) throws Exception;
|
||||
|
||||
void logout(String token) throws Exception;
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonRequestFactory;
|
||||
import org.eclipse.che.api.workspace.shared.dto.CommandDto;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
import org.eclipse.che.selenium.core.provider.TestApiEndpointUrlProvider;
|
||||
|
||||
/** @author Musienko Maxim */
|
||||
@Singleton
|
||||
public class TestCommandServiceClient {
|
||||
private final String apiEndpoint;
|
||||
private final HttpJsonRequestFactory requestFactory;
|
||||
|
||||
@Inject
|
||||
public TestCommandServiceClient(
|
||||
TestApiEndpointUrlProvider apiEndpointProvider, HttpJsonRequestFactory requestFactory) {
|
||||
this.apiEndpoint = apiEndpointProvider.get().toString();
|
||||
this.requestFactory = requestFactory;
|
||||
}
|
||||
|
||||
public void createCommand(String commandLine, String commandName, String commandType, String wsId)
|
||||
throws Exception {
|
||||
CommandDto commandDto = DtoFactory.newDto(CommandDto.class);
|
||||
commandDto.setName(commandName);
|
||||
commandDto.setType(commandType);
|
||||
commandDto.setCommandLine(commandLine);
|
||||
commandDto.setAttributes(ImmutableMap.of("previewUrl", ""));
|
||||
createCommand(commandDto, wsId);
|
||||
}
|
||||
|
||||
public void createCommand(CommandDto command, String wsId) throws Exception {
|
||||
requestFactory
|
||||
.fromUrl(apiEndpoint + "workspace/" + wsId + "/command")
|
||||
.usePostMethod()
|
||||
.setBody(command)
|
||||
.request();
|
||||
}
|
||||
|
||||
public void deleteCommand(String commandName, String wsId) throws Exception {
|
||||
requestFactory
|
||||
.fromUrl(apiEndpoint + "workspace/" + wsId + "/command/" + commandName)
|
||||
.useDeleteMethod()
|
||||
.request();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,125 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Optional.ofNullable;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import org.eclipse.che.api.core.ApiException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonRequestFactory;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonResponse;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
import org.eclipse.che.selenium.core.provider.TestApiEndpointUrlProvider;
|
||||
import org.eclipse.che.selenium.core.provider.TestIdeUrlProvider;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/** @author Musienko Maxim */
|
||||
@Singleton
|
||||
public class TestFactoryServiceClient {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TestFactoryServiceClient.class);
|
||||
|
||||
private final String factoryApiEndpoint;
|
||||
private final String ideUrl;
|
||||
private final HttpJsonRequestFactory requestFactory;
|
||||
|
||||
@Inject
|
||||
public TestFactoryServiceClient(
|
||||
TestApiEndpointUrlProvider testApiEndpointUrlProvider,
|
||||
TestIdeUrlProvider ideUrlProvider,
|
||||
HttpJsonRequestFactory requestFactory)
|
||||
throws Exception {
|
||||
this.factoryApiEndpoint = testApiEndpointUrlProvider.get() + "factory/";
|
||||
this.ideUrl = ideUrlProvider.get().toString();
|
||||
this.requestFactory = requestFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates factory
|
||||
*
|
||||
* @param createFactoryDto DTO object to create the factory
|
||||
* @return URL for the saved factory
|
||||
*/
|
||||
public String createFactory(FactoryDto createFactoryDto) throws Exception {
|
||||
HttpJsonResponse request =
|
||||
requestFactory
|
||||
.fromUrl(factoryApiEndpoint)
|
||||
.usePostMethod()
|
||||
.setBody(createFactoryDto)
|
||||
.request();
|
||||
|
||||
FactoryDto responseDto =
|
||||
ofNullable(request.asDto(FactoryDto.class))
|
||||
.orElseThrow(() -> new RuntimeException("There is a problem creation of factory."));
|
||||
|
||||
LOG.debug(
|
||||
"Factory with name='{}' and id='{}' has been created without errors",
|
||||
responseDto.getName(),
|
||||
responseDto.getId());
|
||||
|
||||
return format("%sf?id=%s", ideUrl, responseDto.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for factories of certain name.
|
||||
*
|
||||
* @param name name of factory to find.
|
||||
* @return List of factory DTOs with certain name.
|
||||
* @throws ApiException
|
||||
* @throws IOException
|
||||
*/
|
||||
public List<FactoryDto> findFactory(String name) throws ApiException, IOException {
|
||||
String queryParamPrefix = "find?name=" + name;
|
||||
HttpJsonResponse request;
|
||||
try {
|
||||
request = requestFactory.fromUrl(factoryApiEndpoint + queryParamPrefix).request();
|
||||
} catch (NotFoundException e) {
|
||||
return emptyList();
|
||||
}
|
||||
|
||||
return request.asList(FactoryDto.class);
|
||||
}
|
||||
|
||||
public void deleteFactory(String name) {
|
||||
List<FactoryDto> factories;
|
||||
try {
|
||||
factories = findFactory(name);
|
||||
if (factories.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
} catch (NotFoundException e) {
|
||||
// ignore in case of there is no factory with certain name
|
||||
return;
|
||||
} catch (ApiException | IOException e) {
|
||||
LOG.error(
|
||||
format("Error of getting info about factory with name='%s': %s", name, e.getMessage()),
|
||||
e);
|
||||
return;
|
||||
}
|
||||
|
||||
FactoryDto factory = factories.get(0);
|
||||
try {
|
||||
requestFactory.fromUrl(factoryApiEndpoint + factory.getId()).useDeleteMethod().request();
|
||||
} catch (IOException | ApiException e) {
|
||||
LOG.error(format("Error of deletion of factory with name='%s': %s", name, e.getMessage()), e);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG.info("Factory name='{}' removed", name);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
import static org.slf4j.LoggerFactory.getLogger;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.name.Named;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
/** @author Dmytro Nochevnov */
|
||||
@Singleton
|
||||
public class TestGitHubKeyUploader {
|
||||
public static final String GITHUB_COM = "github.com";
|
||||
|
||||
private static final Logger LOG = getLogger(TestGitHubKeyUploader.class);
|
||||
|
||||
@Inject private TestGitHubServiceClient testGitHubServiceClient;
|
||||
|
||||
@Inject private TestSshServiceClient testSshServiceClient;
|
||||
|
||||
@Inject
|
||||
@Named("github.username")
|
||||
private String gitHubUsername;
|
||||
|
||||
@Inject
|
||||
@Named("github.password")
|
||||
private String gitHubPassword;
|
||||
|
||||
public synchronized void updateGithubKey() throws Exception {
|
||||
testSshServiceClient.deleteVCSKey(GITHUB_COM);
|
||||
|
||||
try {
|
||||
String publicKey = testSshServiceClient.generateVCSKey(GITHUB_COM);
|
||||
testGitHubServiceClient.uploadPublicKey(
|
||||
gitHubUsername, gitHubPassword, publicKey, "Eclipse Che Key");
|
||||
} catch (ConflictException e) {
|
||||
// ignore if ssh-key for github.com has already existed
|
||||
LOG.debug("Ssh key for {} has already existed.", GITHUB_COM);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG.debug("Ssh key for {} has been generated.", GITHUB_COM);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,453 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.eclipse.che.selenium.core.utils.WaitUtils.sleepQuietly;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.name.Named;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.annotation.PreDestroy;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.eclipse.che.commons.lang.NameGenerator;
|
||||
import org.kohsuke.github.GHCommit;
|
||||
import org.kohsuke.github.GHContent;
|
||||
import org.kohsuke.github.GHFileNotFoundException;
|
||||
import org.kohsuke.github.GHRef;
|
||||
import org.kohsuke.github.GHRepository;
|
||||
import org.kohsuke.github.GitHub;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* This is facade and helper for {@link GHRepository}.
|
||||
*
|
||||
* @author Dmytro Nochevnov
|
||||
*/
|
||||
public class TestGitHubRepository {
|
||||
|
||||
private static final int GITHUB_OPERATION_TIMEOUT_SEC = 1;
|
||||
private static final int REPO_CREATION_ATTEMPTS = 6;
|
||||
|
||||
private final String repoName = NameGenerator.generate("EclipseCheTestRepo-", 5);
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TestGitHubRepository.class);
|
||||
|
||||
private GHRepository ghRepo;
|
||||
private final GitHub gitHub;
|
||||
|
||||
private final String gitHubUsername;
|
||||
private final String gitHubPassword;
|
||||
|
||||
private final List<TestGitHubRepository> submodules = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Creates repository with semi-random name on GitHub for certain {@code gitHubUsername}. Waits
|
||||
* until repository is really created.
|
||||
*
|
||||
* @param gitHubUsername github user name
|
||||
* @param gitHubPassword github user password
|
||||
* @throws IOException
|
||||
*/
|
||||
@Inject
|
||||
public TestGitHubRepository(
|
||||
@Named("github.username") String gitHubUsername,
|
||||
@Named("github.password") String gitHubPassword)
|
||||
throws IOException {
|
||||
gitHub = GitHub.connectUsingPassword(gitHubUsername, gitHubPassword);
|
||||
ghRepo = create();
|
||||
|
||||
this.gitHubUsername = gitHubUsername;
|
||||
this.gitHubPassword = gitHubPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets repository on GitHub with predefined name for certain {@code gitHubUsername}.
|
||||
*
|
||||
* @param gitHubUsername github user name
|
||||
* @param gitHubPassword github user password
|
||||
* @param repoName name of repo on GitHub
|
||||
* @throws IOException
|
||||
*/
|
||||
public TestGitHubRepository(String gitHubUsername, String gitHubPassword, String repoName)
|
||||
throws IOException {
|
||||
gitHub = GitHub.connectUsingPassword(gitHubUsername, gitHubPassword);
|
||||
ghRepo = gitHub.getRepository(gitHubUsername + "/" + repoName);
|
||||
|
||||
this.gitHubUsername = gitHubUsername;
|
||||
this.gitHubPassword = gitHubPassword;
|
||||
}
|
||||
|
||||
public enum TreeElementMode {
|
||||
BLOB("100644"),
|
||||
EXECUTABLE_BLOB("100755"),
|
||||
SUBDIRECTORY("040000"),
|
||||
SUBMODULE("160000"),
|
||||
BLOB_SYMLINK("120000");
|
||||
|
||||
private final String mode;
|
||||
|
||||
TreeElementMode(String mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
public String get() {
|
||||
return this.mode;
|
||||
}
|
||||
}
|
||||
|
||||
public enum GitNodeType {
|
||||
BLOB("blob"),
|
||||
TREE("tree"),
|
||||
COMMIT("commit");
|
||||
|
||||
private final String nodeType;
|
||||
|
||||
GitNodeType(String nodeType) {
|
||||
this.nodeType = nodeType;
|
||||
}
|
||||
|
||||
public String get() {
|
||||
return this.nodeType;
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return repoName;
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
return ghRepo.getFullName();
|
||||
}
|
||||
|
||||
public String getSha1(String branchName) throws IOException {
|
||||
return ghRepo.getBranch(branchName).getSHA1();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates reference to the new branch with {@code branch} from default branch.
|
||||
*
|
||||
* @param branchName name of the branch which should be created
|
||||
* @return reference to the new branch
|
||||
* @throws IOException
|
||||
*/
|
||||
public GHRef createBranch(String branchName) throws IOException {
|
||||
GHRef defaultBranch = getReferenceToDefaultBranch();
|
||||
return ghRepo.createRef("refs/heads/" + branchName, defaultBranch.getObject().getSha());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates reference to the new tag with {@code tagName} from default branch.
|
||||
*
|
||||
* @param tagName is a name of new tag
|
||||
* @return reference to the new tag
|
||||
* @throws IOException
|
||||
*/
|
||||
public GHRef createTag(String tagName) throws IOException {
|
||||
GHRef defaultBranch = getReferenceToDefaultBranch();
|
||||
return ghRepo.createRef("refs/tags/" + tagName, defaultBranch.getObject().getSha());
|
||||
}
|
||||
|
||||
private GHRef getReferenceToDefaultBranch() throws IOException {
|
||||
return ghRepo.getRef("heads/" + ghRepo.getDefaultBranch());
|
||||
}
|
||||
|
||||
public void setDefaultBranch(String branchName) throws IOException {
|
||||
ghRepo.setDefaultBranch(branchName);
|
||||
ghRepo = gitHub.getRepository(ghRepo.getFullName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies content of directory {@code pathToRootContentDirectory} to the GitHub repository. It
|
||||
* tries to recreate the file ones again in case of FileNotFoundException occurs.
|
||||
*
|
||||
* @param pathToRootContentDirectory path to the directory with content
|
||||
* @throws IOException
|
||||
*/
|
||||
public void addContent(Path pathToRootContentDirectory) throws IOException {
|
||||
addContent(pathToRootContentDirectory, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies content of directory {@code pathToRootContentDirectory} to the specified branch in the
|
||||
* GitHub repository. It tries to recreate the file ones again in case of FileNotFoundException
|
||||
* occurs.
|
||||
*
|
||||
* @param pathToRootContentDirectory path to the directory with content
|
||||
* @param branch name of the target branch
|
||||
* @throws IOException
|
||||
*/
|
||||
public void addContent(Path pathToRootContentDirectory, String branch) throws IOException {
|
||||
Files.walk(pathToRootContentDirectory)
|
||||
.filter(Files::isRegularFile)
|
||||
.forEach(
|
||||
pathToFile -> {
|
||||
try {
|
||||
createFile(pathToRootContentDirectory, pathToFile, branch);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes content of the file
|
||||
*
|
||||
* @param pathToFile path to specified file
|
||||
* @param content content to change
|
||||
* @throws IOException
|
||||
*/
|
||||
public void changeFileContent(String pathToFile, String content) throws IOException {
|
||||
changeFileContent(pathToFile, content, format("Change file %s", pathToFile));
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes content of the file
|
||||
*
|
||||
* @param pathToFile path to specified file
|
||||
* @param content content to change
|
||||
* @param commitMessage message to commit
|
||||
* @throws IOException
|
||||
*/
|
||||
public void changeFileContent(String pathToFile, String content, String commitMessage)
|
||||
throws IOException {
|
||||
ghRepo.getFileContent(String.format("/%s", pathToFile)).update(content, commitMessage);
|
||||
}
|
||||
|
||||
public void deleteFile(String pathToFile) throws IOException {
|
||||
ghRepo.getFileContent(pathToFile).delete("Delete file " + pathToFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete folder with content inside the repository on GitHub.
|
||||
*
|
||||
* @param folder folder to delete
|
||||
* @param deleteCommitMessage commit message which is used to delete the message
|
||||
* @throws IOException
|
||||
*/
|
||||
public void deleteFolder(Path folder, String deleteCommitMessage) throws IOException {
|
||||
for (GHContent ghContent : ghRepo.getDirectoryContent(folder.toString())) {
|
||||
ghContent.delete(deleteCommitMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void delete() {
|
||||
try {
|
||||
ghRepo.delete();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
submodules.forEach(TestGitHubRepository::delete);
|
||||
LOG.info("GitHub repo {} has been removed", ghRepo.getHtmlUrl());
|
||||
}
|
||||
|
||||
public static void deleteAllRepos(String repoPrefix, String gitHubUsername, String gitHubPassword)
|
||||
throws IOException {
|
||||
GitHub gitHub = GitHub.connectUsingPassword(gitHubUsername, gitHubPassword);
|
||||
|
||||
gitHub
|
||||
.getMyself()
|
||||
.getAllRepositories()
|
||||
.keySet()
|
||||
.stream()
|
||||
.filter(repoName -> repoName.startsWith(repoPrefix))
|
||||
.forEach(
|
||||
repoName -> {
|
||||
String repoAddress = gitHubUsername + "/" + repoName;
|
||||
LOG.info("Removing repo " + repoAddress + "...");
|
||||
try {
|
||||
gitHub.getRepository(repoAddress).delete();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String getHtmlUrl() {
|
||||
return ghRepo.getHtmlUrl().toString();
|
||||
}
|
||||
|
||||
public String getHttpsTransportUrl() {
|
||||
return ghRepo.gitHttpTransportUrl();
|
||||
}
|
||||
|
||||
public String getSshUrl() {
|
||||
return ghRepo.getSshUrl();
|
||||
}
|
||||
|
||||
private GHRepository create() throws IOException {
|
||||
GHRepository repo = gitHub.createRepository(repoName).create();
|
||||
ensureRepositoryCreated(repo, System.currentTimeMillis());
|
||||
|
||||
LOG.info("GitHub repo {} has been created", repo.getHtmlUrl());
|
||||
return repo;
|
||||
}
|
||||
|
||||
private void ensureRepositoryCreated(GHRepository repo, long startCreationTimeInMillisec)
|
||||
throws IOException {
|
||||
Throwable lastIOException = null;
|
||||
for (int i = 0; i < REPO_CREATION_ATTEMPTS; i++) {
|
||||
try {
|
||||
gitHub.getRepository(repo.getFullName());
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
lastIOException = e;
|
||||
LOG.info("Waiting for {} to be created", repo.getHtmlUrl());
|
||||
sleepQuietly(GITHUB_OPERATION_TIMEOUT_SEC); // sleep one second
|
||||
}
|
||||
}
|
||||
|
||||
long durationOfRepoCreationInSec =
|
||||
(System.currentTimeMillis() - startCreationTimeInMillisec) / 1000;
|
||||
|
||||
throw new IOException(
|
||||
format(
|
||||
"GitHub repo %s hasn't been created in %s seconds",
|
||||
repo.getHtmlUrl(), durationOfRepoCreationInSec),
|
||||
lastIOException);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates file in GitHub repository in the specified {@code branch}.
|
||||
*
|
||||
* @param pathToRootContentDirectory path to the root directory of file locally
|
||||
* @param pathToFile path to file locally
|
||||
* @param branch name of the target branch
|
||||
* @throws IOException
|
||||
*/
|
||||
private void createFile(Path pathToRootContentDirectory, Path pathToFile, String branch)
|
||||
throws IOException {
|
||||
byte[] contentBytes = Files.readAllBytes(pathToFile);
|
||||
String relativePath = pathToRootContentDirectory.relativize(pathToFile).toString();
|
||||
String commitMessage = String.format("Add file %s", relativePath);
|
||||
|
||||
try {
|
||||
ghRepo.createContent(contentBytes, commitMessage, relativePath, branch);
|
||||
} catch (GHFileNotFoundException e) {
|
||||
// try to create content once again
|
||||
LOG.warn(
|
||||
"Error of creation of {} occurred. Is trying to create it once again...",
|
||||
ghRepo.getHtmlUrl() + "/" + relativePath);
|
||||
sleepQuietly(GITHUB_OPERATION_TIMEOUT_SEC);
|
||||
ghRepo.createContent(contentBytes, commitMessage, relativePath);
|
||||
}
|
||||
}
|
||||
|
||||
public String getFileContent(String pathToFile) throws IOException {
|
||||
return IOUtils.toString(ghRepo.getFileContent(pathToFile).read(), "UTF-8");
|
||||
}
|
||||
|
||||
public String getDefaultBranchSha() throws IOException {
|
||||
return getReferenceToDefaultBranch().getObject().getSha();
|
||||
}
|
||||
|
||||
public void addSubmodule(Path pathToRootContentDirectory, String submoduleName)
|
||||
throws IOException {
|
||||
|
||||
TestGitHubRepository submodule = new TestGitHubRepository(gitHubUsername, gitHubPassword);
|
||||
submodule.addContent(pathToRootContentDirectory);
|
||||
createSubmodule(submodule, submoduleName);
|
||||
submodules.add(submodule);
|
||||
}
|
||||
|
||||
private void createSubmodule(
|
||||
TestGitHubRepository pathToRootContentDirectory, String pathForSubmodule) throws IOException {
|
||||
String submoduleSha = createTreeWithSubmodule(pathToRootContentDirectory, pathForSubmodule);
|
||||
|
||||
GHCommit treeCommit =
|
||||
ghRepo.createCommit().tree(submoduleSha).message("Create submodule").create();
|
||||
|
||||
getReferenceToDefaultBranch().updateTo(treeCommit.getSHA1(), true);
|
||||
setupSubmoduleConfig(pathToRootContentDirectory, pathForSubmodule);
|
||||
}
|
||||
|
||||
private boolean isGitmodulesFileExist() throws IOException {
|
||||
return 0
|
||||
< ghRepo
|
||||
.getDirectoryContent("")
|
||||
.stream()
|
||||
.filter(item -> item.getName().equals(".gitmodules"))
|
||||
.count();
|
||||
}
|
||||
|
||||
private String createTreeWithSubmodule(TestGitHubRepository submodule, String pathForSubmodule)
|
||||
throws IOException {
|
||||
return ghRepo
|
||||
.createTree()
|
||||
.baseTree(this.getDefaultBranchSha())
|
||||
.entry(
|
||||
pathForSubmodule,
|
||||
TreeElementMode.SUBMODULE.get(),
|
||||
GitNodeType.COMMIT.get(),
|
||||
submodule.getDefaultBranchSha(),
|
||||
null)
|
||||
.create()
|
||||
.getSha();
|
||||
}
|
||||
|
||||
private String getSubmoduleConfig(TestGitHubRepository submodule, String pathToSubmoduleContent) {
|
||||
String repoName = Paths.get(pathToSubmoduleContent).getFileName().toString();
|
||||
String repoUrl = submodule.getHtmlUrl() + ".git";
|
||||
String modulePattern = "[submodule \"%s\"]\n\tpath = %s\n\turl = %s";
|
||||
|
||||
return String.format(modulePattern, repoName, pathToSubmoduleContent, repoUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates ".gitmodules" file or updates if it already exist.
|
||||
*
|
||||
* @see <a href="https://git-scm.com/docs/gitmodules">gitmodules </a>
|
||||
*/
|
||||
private void setupSubmoduleConfig(TestGitHubRepository submodule, String pathToSubmoduleContent)
|
||||
throws IOException {
|
||||
final String gitmodulesFileName = ".gitmodules";
|
||||
String submoduleConfig = getSubmoduleConfig(submodule, pathToSubmoduleContent);
|
||||
|
||||
if (isGitmodulesFileExist()) {
|
||||
GHContent submoduleFileContent = ghRepo.getFileContent(gitmodulesFileName);
|
||||
String newFileContent = getFileContent(gitmodulesFileName) + "\n" + submoduleConfig;
|
||||
|
||||
submoduleFileContent.update(newFileContent, "Update " + gitmodulesFileName);
|
||||
return;
|
||||
}
|
||||
|
||||
ghRepo.createContent(submoduleConfig, "Add " + gitmodulesFileName, gitmodulesFileName);
|
||||
}
|
||||
|
||||
public String getPullRequestTitle(int requestNumber) throws IOException {
|
||||
return ghRepo.getPullRequest(requestNumber).getTitle();
|
||||
}
|
||||
|
||||
public String getPullRequestBaseBranchName(int requestNumber) throws IOException {
|
||||
return ghRepo.getPullRequest(requestNumber).getBase().getRef();
|
||||
}
|
||||
|
||||
public String getPullRequestHeadBranchName(int requestNumber) throws IOException {
|
||||
return ghRepo.getPullRequest(requestNumber).getHead().getRef();
|
||||
}
|
||||
|
||||
public String getPullRequestBody(int requestNumber) throws IOException {
|
||||
return ghRepo.getPullRequest(requestNumber).getBody();
|
||||
}
|
||||
|
||||
public String getPullRequestUserName(int requestNumber) throws IOException {
|
||||
return ghRepo.getPullRequest(requestNumber).getUser().getLogin();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,228 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.eclipse.che.dto.server.DtoFactory.newDto;
|
||||
import static org.slf4j.LoggerFactory.getLogger;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.eclipse.che.api.core.ApiException;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonRequestFactory;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonResponse;
|
||||
import org.eclipse.che.dto.server.JsonStringMapImpl;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
/** @author Mihail Kuznyetsov. */
|
||||
@Singleton
|
||||
public class TestGitHubServiceClient {
|
||||
private static final Logger LOG = getLogger(TestGitHubServiceClient.class);
|
||||
|
||||
private final HttpJsonRequestFactory requestFactory;
|
||||
|
||||
@Inject
|
||||
public TestGitHubServiceClient(HttpJsonRequestFactory requestFactory) {
|
||||
this.requestFactory = requestFactory;
|
||||
}
|
||||
|
||||
public void deletePublicKeys(final String username, final String password, final String keyTitle)
|
||||
throws Exception {
|
||||
List<GitHubKey> keys = getPublicKeys(username, password, keyTitle);
|
||||
for (GitHubKey key : keys) {
|
||||
requestFactory
|
||||
.fromUrl(key.getUrl())
|
||||
.setAuthorizationHeader(createBasicAuthHeader(username, password))
|
||||
.useDeleteMethod()
|
||||
.request();
|
||||
}
|
||||
}
|
||||
|
||||
public void createPublicKey(final String username, final String password, final GitHubKey key)
|
||||
throws Exception {
|
||||
requestFactory
|
||||
.fromUrl("https://api.github.com/user/keys")
|
||||
.setAuthorizationHeader(createBasicAuthHeader(username, password))
|
||||
.usePostMethod()
|
||||
.setBody(key)
|
||||
.request();
|
||||
}
|
||||
|
||||
public void uploadPublicKey(
|
||||
final String username, final String password, final String key, String keyTitle)
|
||||
throws Exception {
|
||||
|
||||
GitHubKey publicSshKey = newDto(GitHubKey.class);
|
||||
publicSshKey.setTitle(keyTitle);
|
||||
publicSshKey.setKey(key);
|
||||
|
||||
deletePublicKeys(username, password, keyTitle);
|
||||
createPublicKey(username, password, publicSshKey);
|
||||
}
|
||||
|
||||
public List<GitHubKey> getPublicKeys(
|
||||
final String username, final String password, final String title) throws Exception {
|
||||
List<GitHubKey> keys =
|
||||
requestFactory
|
||||
.fromUrl("https://api.github.com/user/keys")
|
||||
.setAuthorizationHeader(createBasicAuthHeader(username, password))
|
||||
.useGetMethod()
|
||||
.request()
|
||||
.asList(GitHubKey.class);
|
||||
|
||||
return keys.stream().filter(key -> title.equals(key.getTitle())).collect(toList());
|
||||
}
|
||||
|
||||
public void hardResetHeadToCommit(
|
||||
final String repository, final String commitSha, final String username, final String password)
|
||||
throws Exception {
|
||||
ImmutableMap<String, Object> m = ImmutableMap.of("sha", commitSha, "force", true);
|
||||
|
||||
String url =
|
||||
"https://api.github.com/repos/" + username + "/" + repository + "/git/refs/heads/master";
|
||||
requestFactory
|
||||
.fromUrl(url)
|
||||
.usePostMethod()
|
||||
.setAuthorizationHeader(createBasicAuthHeader(username, password))
|
||||
.setBody(new JsonStringMapImpl<Object>(m))
|
||||
.request();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<String> getNumbersOfOpenedPullRequests(
|
||||
final String repository, final String username, final String password) throws Exception {
|
||||
String url = "https://api.github.com/repos/" + username + "/" + repository + "/pulls";
|
||||
HttpJsonResponse response =
|
||||
requestFactory
|
||||
.fromUrl(url)
|
||||
.useGetMethod()
|
||||
.setAuthorizationHeader(createBasicAuthHeader(username, password))
|
||||
.request();
|
||||
List<Map<String, String>> prs =
|
||||
response.as(List.class, new TypeToken<List<Map<String, String>>>() {}.getType());
|
||||
return prs.stream()
|
||||
.filter(g -> g.get("state").equals("open"))
|
||||
.map(g -> g.get("number"))
|
||||
.collect(toList());
|
||||
}
|
||||
|
||||
public void closePullRequest(
|
||||
final String repo, final String number, final String username, final String password)
|
||||
throws Exception {
|
||||
String url = "https://api.github.com/repos/" + username + "/" + repo + "/pulls/" + number;
|
||||
requestFactory
|
||||
.fromUrl(url)
|
||||
.usePostMethod()
|
||||
.setAuthorizationHeader(createBasicAuthHeader(username, password))
|
||||
.setBody(ImmutableMap.of("state", "close"))
|
||||
.request();
|
||||
}
|
||||
|
||||
public void deleteBranch(
|
||||
final String repository,
|
||||
final String branchName,
|
||||
final String username,
|
||||
final String password)
|
||||
throws Exception {
|
||||
String url =
|
||||
"https://api.github.com/repos/"
|
||||
+ username
|
||||
+ "/"
|
||||
+ repository
|
||||
+ "/git/refs/heads/"
|
||||
+ branchName;
|
||||
requestFactory
|
||||
.fromUrl(url)
|
||||
.useDeleteMethod()
|
||||
.setAuthorizationHeader(createBasicAuthHeader(username, password))
|
||||
.request();
|
||||
}
|
||||
|
||||
public void deleteRepo(final String repository, final String username, final String password)
|
||||
throws Exception {
|
||||
String url = "https://api.github.com/repos/" + username + "/" + repository;
|
||||
requestFactory
|
||||
.fromUrl(url)
|
||||
.useDeleteMethod()
|
||||
.setAuthorizationHeader(createBasicAuthHeader(username, password))
|
||||
.request();
|
||||
}
|
||||
|
||||
public List<String> getAllGrants(final String username, final String password) throws Exception {
|
||||
String url = "https://api.github.com/applications/grants";
|
||||
HttpJsonResponse response =
|
||||
requestFactory
|
||||
.fromUrl(url)
|
||||
.useGetMethod()
|
||||
.setAuthorizationHeader(createBasicAuthHeader(username, password))
|
||||
.request();
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, String>> grants =
|
||||
response.as(List.class, new TypeToken<List<Map<String, String>>>() {}.getType());
|
||||
|
||||
return grants.stream().map(g -> g.get("id")).collect(toList());
|
||||
}
|
||||
|
||||
public void deleteAllGrants(final String username, final String password) throws Exception {
|
||||
List<String> grandsId = getAllGrants(username, password);
|
||||
for (String grandId : grandsId) {
|
||||
String url = "https://api.github.com/applications/grants/" + grandId;
|
||||
requestFactory
|
||||
.fromUrl(url)
|
||||
.useDeleteMethod()
|
||||
.setAuthorizationHeader(createBasicAuthHeader(username, password))
|
||||
.request();
|
||||
}
|
||||
|
||||
LOG.debug("Application grants '{}' were removed from github.com", grandsId);
|
||||
}
|
||||
|
||||
public String getName(final String username, final String password)
|
||||
throws IOException, ApiException {
|
||||
String url = "https://api.github.com/users/" + username;
|
||||
HttpJsonResponse response =
|
||||
requestFactory
|
||||
.fromUrl(url)
|
||||
.useGetMethod()
|
||||
.setAuthorizationHeader(createBasicAuthHeader(username, password))
|
||||
.request();
|
||||
|
||||
return obtainNameFromResponse(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain name of github user from github response
|
||||
*
|
||||
* @param response
|
||||
* @return name if it presents in response and != null, or login otherwise.
|
||||
*/
|
||||
private String obtainNameFromResponse(HttpJsonResponse response) throws IOException {
|
||||
Map<String, String> properties = response.asProperties();
|
||||
String login = properties.get("login");
|
||||
return ofNullable(properties.getOrDefault("name", login)).orElse(login);
|
||||
}
|
||||
|
||||
private String createBasicAuthHeader(String username, String password)
|
||||
throws UnsupportedEncodingException {
|
||||
byte[] nameAndPass = (username + ":" + password).getBytes("UTF-8");
|
||||
String base64 = Base64.getEncoder().encodeToString(nameAndPass);
|
||||
return "Basic " + base64;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
/** @author Musienko Maxim */
|
||||
public interface TestMachineServiceClient {
|
||||
|
||||
/**
|
||||
* Returns machine token for current workspace
|
||||
*
|
||||
* @param authToken the authorization token
|
||||
* @param workspaceId the workspace id
|
||||
* @return the machine token for current workspace
|
||||
*/
|
||||
String getMachineApiToken(String workspaceId) throws Exception;
|
||||
}
|
||||
|
|
@ -1,163 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.eclipse.che.dto.server.DtoFactory.newDto;
|
||||
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.google.inject.assistedinject.AssistedInject;
|
||||
import java.util.List;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonRequestFactory;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
import org.eclipse.che.multiuser.api.permission.shared.dto.PermissionsDto;
|
||||
import org.eclipse.che.multiuser.organization.shared.dto.OrganizationDto;
|
||||
import org.eclipse.che.selenium.core.provider.TestApiEndpointUrlProvider;
|
||||
import org.eclipse.che.selenium.core.requestfactory.TestUserHttpJsonRequestFactoryCreator;
|
||||
import org.eclipse.che.selenium.core.user.TestUser;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/** This util is handling the requests to Organization API. */
|
||||
public class TestOrganizationServiceClient {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TestOrganizationServiceClient.class);
|
||||
|
||||
private final String apiEndpoint;
|
||||
private final HttpJsonRequestFactory requestFactory;
|
||||
|
||||
public TestOrganizationServiceClient(
|
||||
TestApiEndpointUrlProvider apiEndpointUrlProvider, HttpJsonRequestFactory requestFactory) {
|
||||
this.apiEndpoint = apiEndpointUrlProvider.get().toString();
|
||||
this.requestFactory = requestFactory;
|
||||
}
|
||||
|
||||
@AssistedInject
|
||||
public TestOrganizationServiceClient(
|
||||
TestApiEndpointUrlProvider apiEndpointUrlProvider,
|
||||
TestUserHttpJsonRequestFactoryCreator testUserHttpJsonRequestFactoryCreator,
|
||||
@Assisted TestUser testUser) {
|
||||
this.apiEndpoint = apiEndpointUrlProvider.get().toString();
|
||||
this.requestFactory = testUserHttpJsonRequestFactoryCreator.create(testUser);
|
||||
}
|
||||
|
||||
public List<OrganizationDto> getAll() throws Exception {
|
||||
return requestFactory.fromUrl(getApiUrl()).request().asList(OrganizationDto.class);
|
||||
}
|
||||
|
||||
public List<OrganizationDto> getAllRoot() throws Exception {
|
||||
List<OrganizationDto> organizations =
|
||||
requestFactory.fromUrl(getApiUrl()).request().asList(OrganizationDto.class);
|
||||
|
||||
organizations.removeIf(o -> o.getParent() != null);
|
||||
return organizations;
|
||||
}
|
||||
|
||||
private String getApiUrl() {
|
||||
return apiEndpoint + "organization/";
|
||||
}
|
||||
|
||||
public OrganizationDto create(String name, @Nullable String parentId) throws Exception {
|
||||
OrganizationDto data = newDto(OrganizationDto.class).withName(name).withParent(parentId);
|
||||
|
||||
OrganizationDto organizationDto =
|
||||
requestFactory
|
||||
.fromUrl(getApiUrl())
|
||||
.setBody(data)
|
||||
.usePostMethod()
|
||||
.request()
|
||||
.asDto(OrganizationDto.class);
|
||||
|
||||
LOG.info(
|
||||
"Organization with name='{}', id='{}', parent's id='{}' created",
|
||||
name,
|
||||
organizationDto.getId(),
|
||||
parentId);
|
||||
|
||||
return organizationDto;
|
||||
}
|
||||
|
||||
public OrganizationDto create(String name) throws Exception {
|
||||
return create(name, null);
|
||||
}
|
||||
|
||||
public void deleteById(String id) throws Exception {
|
||||
String apiUrl = format("%s%s", getApiUrl(), id);
|
||||
|
||||
try {
|
||||
requestFactory.fromUrl(apiUrl).useDeleteMethod().request();
|
||||
LOG.info("Organization with id='{}' removed", id);
|
||||
} catch (NotFoundException e) {
|
||||
// ignore if there is no organization of certain id
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteByName(String name) throws Exception {
|
||||
try {
|
||||
String organizationId = get(name).getId();
|
||||
deleteById(organizationId);
|
||||
} catch (NotFoundException e) {
|
||||
// ignore if there is no organization of certain id
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteAll() throws Exception {
|
||||
getAll()
|
||||
.stream()
|
||||
.filter(organization -> organization.getParent() != null)
|
||||
.forEach(
|
||||
organization -> {
|
||||
try {
|
||||
deleteById(organization.getId());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public OrganizationDto get(String organizationName) throws Exception {
|
||||
String apiUrl = format("%sfind?name=%s", getApiUrl(), organizationName);
|
||||
return requestFactory.fromUrl(apiUrl).request().asDto(OrganizationDto.class);
|
||||
}
|
||||
|
||||
public void addMember(String organizationId, String userId) throws Exception {
|
||||
addMember(organizationId, userId, asList("createWorkspaces"));
|
||||
}
|
||||
|
||||
public void addAdmin(String organizationId, String userId) throws Exception {
|
||||
addMember(
|
||||
organizationId,
|
||||
userId,
|
||||
asList(
|
||||
"update",
|
||||
"setPermissions",
|
||||
"manageResources",
|
||||
"manageWorkspaces",
|
||||
"createWorkspaces",
|
||||
"delete",
|
||||
"manageSuborganizations"));
|
||||
}
|
||||
|
||||
public void addMember(String organizationId, String userId, List<String> actions)
|
||||
throws Exception {
|
||||
String apiUrl = apiEndpoint + "permissions";
|
||||
PermissionsDto data =
|
||||
newDto(PermissionsDto.class)
|
||||
.withDomainId("organization")
|
||||
.withInstanceId(organizationId)
|
||||
.withUserId(userId)
|
||||
.withActions(actions);
|
||||
|
||||
requestFactory.fromUrl(apiUrl).setBody(data).usePostMethod().request();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import org.eclipse.che.selenium.core.user.TestUser;
|
||||
|
||||
/** @author Dmytro Nochevnov */
|
||||
public interface TestOrganizationServiceClientFactory {
|
||||
TestOrganizationServiceClient create(@Assisted TestUser testUser);
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.util.Map;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonRequestFactory;
|
||||
import org.eclipse.che.selenium.core.provider.TestApiEndpointUrlProvider;
|
||||
import org.eclipse.che.selenium.core.user.DefaultTestUser;
|
||||
|
||||
/** @author Musienko Maxim */
|
||||
@Singleton
|
||||
public class TestProfileServiceClient {
|
||||
private final String apiEndpoint;
|
||||
private final HttpJsonRequestFactory requestFactory;
|
||||
private final DefaultTestUser defaultTestUser;
|
||||
|
||||
@Inject
|
||||
public TestProfileServiceClient(
|
||||
TestApiEndpointUrlProvider apiEndpointProvider,
|
||||
HttpJsonRequestFactory requestFactory,
|
||||
DefaultTestUser defaultTestUser) {
|
||||
this.apiEndpoint = apiEndpointProvider.get().toString();
|
||||
this.requestFactory = requestFactory;
|
||||
this.defaultTestUser = defaultTestUser;
|
||||
}
|
||||
|
||||
public void setAttributes(Map<String, String> attributes) throws Exception {
|
||||
requestFactory
|
||||
.fromUrl(apiEndpoint + "profile/attributes")
|
||||
.usePutMethod()
|
||||
.setBody(attributes)
|
||||
.request();
|
||||
}
|
||||
|
||||
public void setUserNames(String name, String lastName) throws Exception {
|
||||
Map<String, String> attributes =
|
||||
ImmutableMap.of(
|
||||
"firstName", name,
|
||||
"lastName", lastName);
|
||||
|
||||
setAttributes(attributes);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,325 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
import static com.google.common.base.Charsets.UTF_8;
|
||||
import static com.google.common.io.Resources.getResource;
|
||||
import static com.google.common.io.Resources.toByteArray;
|
||||
import static java.lang.String.format;
|
||||
import static java.nio.file.Files.createFile;
|
||||
import static java.nio.file.Files.write;
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static org.eclipse.che.dto.server.DtoFactory.getInstance;
|
||||
import static org.eclipse.che.selenium.core.project.ProjectTemplates.PLAIN_JAVA;
|
||||
|
||||
import com.google.common.io.Resources;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
import org.eclipse.che.api.core.model.workspace.config.ProjectConfig;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonRequestFactory;
|
||||
import org.eclipse.che.api.workspace.shared.dto.ProjectConfigDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.SourceStorageDto;
|
||||
import org.eclipse.che.commons.lang.IoUtil;
|
||||
import org.eclipse.che.commons.lang.ZipUtils;
|
||||
import org.eclipse.che.selenium.core.provider.TestWorkspaceAgentApiEndpointUrlProvider;
|
||||
|
||||
/**
|
||||
* @author Musienko Maxim
|
||||
* @author Mykola Morhun
|
||||
*/
|
||||
@Singleton
|
||||
public class TestProjectServiceClient {
|
||||
|
||||
private static final String BEARER_TOKEN_PREFIX = "Bearer ";
|
||||
private final TestMachineServiceClient machineServiceClient;
|
||||
private final HttpJsonRequestFactory requestFactory;
|
||||
private final TestWorkspaceAgentApiEndpointUrlProvider workspaceAgentApiEndpointUrlProvider;
|
||||
|
||||
@Inject
|
||||
public TestProjectServiceClient(
|
||||
TestMachineServiceClient machineServiceClient,
|
||||
HttpJsonRequestFactory requestFactory,
|
||||
TestWorkspaceAgentApiEndpointUrlProvider workspaceAgentApiEndpointUrlProvider) {
|
||||
this.machineServiceClient = machineServiceClient;
|
||||
this.requestFactory = requestFactory;
|
||||
this.workspaceAgentApiEndpointUrlProvider = workspaceAgentApiEndpointUrlProvider;
|
||||
}
|
||||
|
||||
/** Set type for existing project on vfs */
|
||||
public void setProjectType(String workspaceId, String template, String projectName)
|
||||
throws Exception {
|
||||
InputStream in = getClass().getResourceAsStream("/templates/project/" + template);
|
||||
String json = IoUtil.readAndCloseQuietly(in);
|
||||
|
||||
ProjectConfigDto project = getInstance().createDtoFromJson(json, ProjectConfigDto.class);
|
||||
project.setName(projectName);
|
||||
|
||||
requestFactory
|
||||
.fromUrl(workspaceAgentApiEndpointUrlProvider.get(workspaceId) + "project/" + projectName)
|
||||
.usePutMethod()
|
||||
.setAuthorizationHeader(
|
||||
BEARER_TOKEN_PREFIX + machineServiceClient.getMachineApiToken(workspaceId))
|
||||
.setBody(project)
|
||||
.request();
|
||||
}
|
||||
|
||||
/** Delete resource. */
|
||||
public void deleteResource(String workspaceId, String path) throws Exception {
|
||||
requestFactory
|
||||
.fromUrl(workspaceAgentApiEndpointUrlProvider.get(workspaceId) + "project/" + path)
|
||||
.setAuthorizationHeader(
|
||||
BEARER_TOKEN_PREFIX + machineServiceClient.getMachineApiToken(workspaceId))
|
||||
.useDeleteMethod()
|
||||
.request();
|
||||
}
|
||||
|
||||
public void createFolder(String workspaceId, String folder) throws Exception {
|
||||
String url = workspaceAgentApiEndpointUrlProvider.get(workspaceId) + "project/folder/" + folder;
|
||||
requestFactory
|
||||
.fromUrl(url)
|
||||
.setAuthorizationHeader(
|
||||
BEARER_TOKEN_PREFIX + machineServiceClient.getMachineApiToken(workspaceId))
|
||||
.usePostMethod()
|
||||
.request();
|
||||
}
|
||||
|
||||
/** Import zip project from file system into user workspace. */
|
||||
public void importZipProject(
|
||||
String workspaceId, Path zipFile, String projectName, String template) throws Exception {
|
||||
String url =
|
||||
workspaceAgentApiEndpointUrlProvider.get(workspaceId) + "project/import/" + projectName;
|
||||
// createFolder(workspaceId, projectName);
|
||||
|
||||
HttpURLConnection httpConnection = null;
|
||||
try {
|
||||
httpConnection = (HttpURLConnection) new URL(url).openConnection();
|
||||
httpConnection.setRequestMethod("POST");
|
||||
httpConnection.setRequestProperty("Content-Type", "application/zip");
|
||||
httpConnection.addRequestProperty(
|
||||
"Authorization",
|
||||
BEARER_TOKEN_PREFIX + machineServiceClient.getMachineApiToken(workspaceId));
|
||||
httpConnection.setDoOutput(true);
|
||||
|
||||
try (OutputStream outputStream = httpConnection.getOutputStream()) {
|
||||
Files.copy(zipFile, outputStream);
|
||||
if (httpConnection.getResponseCode() != 201) {
|
||||
throw new RuntimeException(
|
||||
"Cannot deploy requested project using ProjectServiceClient REST API. Server response "
|
||||
+ httpConnection.getResponseCode()
|
||||
+ " "
|
||||
+ IoUtil.readStream(httpConnection.getErrorStream())
|
||||
+ "REST url: "
|
||||
+ url);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
ofNullable(httpConnection).ifPresent(HttpURLConnection::disconnect);
|
||||
}
|
||||
|
||||
setProjectType(workspaceId, template, projectName);
|
||||
}
|
||||
|
||||
/** Import project from file system into a user workspace */
|
||||
public void importProject(
|
||||
String workspaceId, Path sourceFolder, String projectName, String template) throws Exception {
|
||||
|
||||
if (!Files.exists(sourceFolder)) {
|
||||
throw new IOException(format("%s not found", sourceFolder));
|
||||
}
|
||||
|
||||
if (!Files.isDirectory(sourceFolder)) {
|
||||
throw new IOException(format("%s not a directory", sourceFolder));
|
||||
}
|
||||
|
||||
Path zip = Files.createTempFile("project", projectName);
|
||||
try (ZipOutputStream out = ZipUtils.stream(zip)) {
|
||||
ZipUtils.add(out, sourceFolder, sourceFolder);
|
||||
if (PLAIN_JAVA.equals(template)) {
|
||||
Path tmpDir = Files.createTempDirectory("TestProject");
|
||||
Path dotClasspath = createFile(tmpDir.resolve(".classpath"));
|
||||
Path dotProject = Files.createFile(tmpDir.resolve(".project"));
|
||||
write(
|
||||
dotProject,
|
||||
format(
|
||||
Resources.toString(getResource("projects/jdt-ls-project-files/project"), UTF_8),
|
||||
projectName)
|
||||
.getBytes(UTF_8));
|
||||
write(dotClasspath, toByteArray(getResource("projects/jdt-ls-project-files/classpath")));
|
||||
ZipUtils.add(out, dotClasspath);
|
||||
ZipUtils.add(out, dotProject);
|
||||
}
|
||||
}
|
||||
|
||||
importZipProject(workspaceId, zip, projectName, template);
|
||||
}
|
||||
|
||||
/** Import project from file system into a user workspace */
|
||||
public void importProject(
|
||||
String workspaceId,
|
||||
String projectName,
|
||||
String location,
|
||||
String type,
|
||||
Map<String, String> parameters)
|
||||
throws Exception {
|
||||
SourceStorageDto source = getInstance().createDto(SourceStorageDto.class);
|
||||
source.setLocation(location);
|
||||
source.setType(type);
|
||||
source.setParameters(parameters);
|
||||
|
||||
importProject(workspaceId, projectName, source);
|
||||
}
|
||||
|
||||
/** Import project from file system into a user workspace */
|
||||
public void importProject(String workspaceId, String projectName, SourceStorageDto source)
|
||||
throws Exception {
|
||||
|
||||
requestFactory
|
||||
.fromUrl(
|
||||
workspaceAgentApiEndpointUrlProvider.get(workspaceId) + "project/import/" + projectName)
|
||||
.usePostMethod()
|
||||
.setAuthorizationHeader(machineServiceClient.getMachineApiToken(workspaceId))
|
||||
.setBody(source)
|
||||
.request();
|
||||
}
|
||||
|
||||
/** Creates file in the project. */
|
||||
public void createFileInProject(
|
||||
String workspaceId, String parentFolder, String fileName, String content) throws Exception {
|
||||
String apiRESTUrl =
|
||||
workspaceAgentApiEndpointUrlProvider.get(workspaceId)
|
||||
+ "project/file/"
|
||||
+ parentFolder
|
||||
+ "?name="
|
||||
+ fileName;
|
||||
|
||||
HttpURLConnection httpConnection = null;
|
||||
try {
|
||||
httpConnection = (HttpURLConnection) new URL(apiRESTUrl).openConnection();
|
||||
httpConnection.setRequestMethod("POST");
|
||||
httpConnection.setRequestProperty("Content-Type", "text/plain");
|
||||
httpConnection.addRequestProperty(
|
||||
"Authorization",
|
||||
BEARER_TOKEN_PREFIX + machineServiceClient.getMachineApiToken(workspaceId));
|
||||
httpConnection.setDoOutput(true);
|
||||
try (OutputStream output = httpConnection.getOutputStream()) {
|
||||
output.write(content.getBytes("UTF-8"));
|
||||
if (httpConnection.getResponseCode() != 201) {
|
||||
throw new RuntimeException(
|
||||
"Cannot create requested content in the current project: "
|
||||
+ apiRESTUrl
|
||||
+ " something went wrong "
|
||||
+ httpConnection.getResponseCode()
|
||||
+ IoUtil.readStream(httpConnection.getErrorStream()));
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
ofNullable(httpConnection).ifPresent(HttpURLConnection::disconnect);
|
||||
}
|
||||
}
|
||||
|
||||
public ProjectConfigDto getFirstProject(String workspaceId) throws Exception {
|
||||
String apiUrl = workspaceAgentApiEndpointUrlProvider.get(workspaceId) + "project";
|
||||
return requestFactory
|
||||
.fromUrl(apiUrl)
|
||||
.setAuthorizationHeader(
|
||||
BEARER_TOKEN_PREFIX + machineServiceClient.getMachineApiToken(workspaceId))
|
||||
.request()
|
||||
.asList(ProjectConfigDto.class)
|
||||
.get(0);
|
||||
}
|
||||
|
||||
/** Updates file content. */
|
||||
public void updateFile(String workspaceId, String pathToFile, String content) throws Exception {
|
||||
String url =
|
||||
workspaceAgentApiEndpointUrlProvider.get(workspaceId) + "project/file/" + pathToFile;
|
||||
|
||||
HttpURLConnection httpConnection = null;
|
||||
try {
|
||||
httpConnection = (HttpURLConnection) new URL(url).openConnection();
|
||||
httpConnection.setRequestMethod("PUT");
|
||||
httpConnection.setRequestProperty("Content-Type", "text/plain");
|
||||
httpConnection.addRequestProperty(
|
||||
"Authorization",
|
||||
BEARER_TOKEN_PREFIX + machineServiceClient.getMachineApiToken(workspaceId));
|
||||
httpConnection.setDoOutput(true);
|
||||
|
||||
try (OutputStream output = httpConnection.getOutputStream()) {
|
||||
output.write(content.getBytes("UTF-8"));
|
||||
if (httpConnection.getResponseCode() != 200) {
|
||||
throw new RuntimeException(
|
||||
"Cannot update content in the current file: "
|
||||
+ url
|
||||
+ " something went wrong "
|
||||
+ httpConnection.getResponseCode()
|
||||
+ IoUtil.readStream(httpConnection.getErrorStream()));
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
ofNullable(httpConnection).ifPresent(HttpURLConnection::disconnect);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean checkProjectType(String wokspaceId, String projectName, String projectType)
|
||||
throws Exception {
|
||||
return getProject(wokspaceId, projectName).getType().equals(projectType);
|
||||
}
|
||||
|
||||
public boolean checkProjectLanguage(String workspaceId, String projectName, String language)
|
||||
throws Exception {
|
||||
|
||||
return getProject(workspaceId, projectName).getAttributes().get("language").contains(language);
|
||||
}
|
||||
|
||||
public boolean checkProjectLanguage(
|
||||
String workspaceId, String projectName, List<String> languages) throws Exception {
|
||||
|
||||
return getProject(workspaceId, projectName)
|
||||
.getAttributes()
|
||||
.get("language")
|
||||
.containsAll(languages);
|
||||
}
|
||||
|
||||
public List<String> getExternalLibraries(String workspaceId, String projectName)
|
||||
throws Exception {
|
||||
return requestFactory
|
||||
.fromUrl(
|
||||
workspaceAgentApiEndpointUrlProvider.get(workspaceId) + "java/navigation/libraries")
|
||||
.useGetMethod()
|
||||
.addQueryParam("projectpath", "/" + projectName)
|
||||
.request()
|
||||
.asList(ProjectConfigDto.class)
|
||||
.stream()
|
||||
.map(e -> e.getName())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private ProjectConfig getProject(String workspaceId, String projectName) throws Exception {
|
||||
return requestFactory
|
||||
.fromUrl(workspaceAgentApiEndpointUrlProvider.get(workspaceId) + "project/" + projectName)
|
||||
.useGetMethod()
|
||||
.setAuthorizationHeader(
|
||||
BEARER_TOKEN_PREFIX + machineServiceClient.getMachineApiToken(workspaceId))
|
||||
.request()
|
||||
.asDto(ProjectConfigDto.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.eclipse.che.dto.server.DtoFactory.newDto;
|
||||
import static org.slf4j.LoggerFactory.getLogger;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.util.List;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonRequestFactory;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonResponse;
|
||||
import org.eclipse.che.api.ssh.shared.dto.GenerateSshPairRequest;
|
||||
import org.eclipse.che.api.ssh.shared.dto.SshPairDto;
|
||||
import org.eclipse.che.selenium.core.provider.TestApiEndpointUrlProvider;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
/** @author Musienko Maxim */
|
||||
@Singleton
|
||||
public class TestSshServiceClient {
|
||||
private static final Logger LOG = getLogger(TestSshServiceClient.class);
|
||||
private static final String MACHINE_SERVICE = "machine";
|
||||
private static final String VCS_SERVICE = "vcs";
|
||||
|
||||
private final String apiEndpoint;
|
||||
private final HttpJsonRequestFactory requestFactory;
|
||||
|
||||
@Inject
|
||||
public TestSshServiceClient(
|
||||
TestApiEndpointUrlProvider apiEndpointProvider, HttpJsonRequestFactory requestFactory) {
|
||||
this.apiEndpoint = apiEndpointProvider.get().toString();
|
||||
this.requestFactory = requestFactory;
|
||||
}
|
||||
|
||||
public String getPrivateMachineKey(String keyName) throws Exception {
|
||||
HttpJsonResponse request =
|
||||
requestFactory
|
||||
.fromUrl(format("%sssh/%s/?name=%s", apiEndpoint, MACHINE_SERVICE, keyName))
|
||||
.useGetMethod()
|
||||
.request();
|
||||
List<SshPairDto> sshPair = request.asList(SshPairDto.class);
|
||||
return sshPair.isEmpty() ? null : sshPair.get(0).getPrivateKey();
|
||||
}
|
||||
|
||||
public String generateVCSKey(String keyName) throws Exception {
|
||||
GenerateSshPairRequest generateSshKeyData =
|
||||
newDto(GenerateSshPairRequest.class).withName(keyName).withService(VCS_SERVICE);
|
||||
|
||||
HttpJsonResponse response =
|
||||
requestFactory
|
||||
.fromUrl(apiEndpoint + "ssh/generate")
|
||||
.usePostMethod()
|
||||
.setBody(generateSshKeyData)
|
||||
.request();
|
||||
return response.asDto(SshPairDto.class).getPublicKey();
|
||||
}
|
||||
|
||||
public void deleteVCSKey(String keyName) throws Exception {
|
||||
deleteKey(VCS_SERVICE, keyName);
|
||||
}
|
||||
|
||||
private void deleteKey(String serviceName, String keyName) throws Exception {
|
||||
try {
|
||||
requestFactory
|
||||
.fromUrl(format("%sssh/%s/?name=%s", apiEndpoint, serviceName, keyName))
|
||||
.useDeleteMethod()
|
||||
.request();
|
||||
} catch (NotFoundException e) {
|
||||
// ignore absence of key
|
||||
LOG.debug("Ssh key for '{}' with name '{}' is absent.", serviceName, keyName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.ForbiddenException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.UnauthorizedException;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonRequestFactory;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonResponse;
|
||||
import org.eclipse.che.selenium.core.provider.TestApiEndpointUrlProvider;
|
||||
|
||||
/** @author Musienko Maxim */
|
||||
@Singleton
|
||||
public class TestUserPreferencesServiceClient {
|
||||
|
||||
private static final String ACTIVATE_CONTRIBUTION_TAB_BY_PROJECT_SELECTION_PROPERTY =
|
||||
"git.contribute.activate.projectSelection";
|
||||
private final String apiEndpoint;
|
||||
private final HttpJsonRequestFactory httpRequestFactory;
|
||||
|
||||
@Inject
|
||||
public TestUserPreferencesServiceClient(
|
||||
TestApiEndpointUrlProvider apiEndpointProvider, HttpJsonRequestFactory httpRequestFactory)
|
||||
throws Exception {
|
||||
this.apiEndpoint = apiEndpointProvider.get().toString();
|
||||
this.httpRequestFactory = httpRequestFactory;
|
||||
|
||||
// Set application.confirmExit property to 'never' to avoid web page closing confirmation pop-up
|
||||
this.setProperty("theia-user-preferences", "{\"application.confirmExit\":\"never\"}");
|
||||
}
|
||||
|
||||
public void addGitCommitter(String committerName, String committerEmail) throws Exception {
|
||||
httpRequestFactory
|
||||
.fromUrl(apiEndpoint + "preferences")
|
||||
.usePutMethod()
|
||||
.setBody(
|
||||
ImmutableMap.of(
|
||||
"git.committer.name", committerName,
|
||||
"git.committer.email", committerEmail))
|
||||
.request();
|
||||
}
|
||||
|
||||
public HttpJsonResponse setProperty(String propertyName, String propertyValue) throws Exception {
|
||||
return httpRequestFactory
|
||||
.fromUrl(apiEndpoint + "preferences")
|
||||
.usePutMethod()
|
||||
.setBody(ImmutableMap.of(propertyName, propertyValue))
|
||||
.request();
|
||||
}
|
||||
|
||||
public String getPreferences() throws Exception {
|
||||
return httpRequestFactory
|
||||
.fromUrl(apiEndpoint + "preferences")
|
||||
.useGetMethod()
|
||||
.request()
|
||||
.asString();
|
||||
}
|
||||
|
||||
public void restoreDefaultContributionTabPreference()
|
||||
throws ForbiddenException, BadRequestException, IOException, ConflictException,
|
||||
NotFoundException, ServerException, UnauthorizedException {
|
||||
httpRequestFactory
|
||||
.fromUrl(apiEndpoint + "preferences")
|
||||
.useDeleteMethod()
|
||||
.setBody(ImmutableList.of(ACTIVATE_CONTRIBUTION_TAB_BY_PROJECT_SELECTION_PROPERTY))
|
||||
.request();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.model.user.User;
|
||||
|
||||
/**
|
||||
* @author Mihail Kuznyetsov
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
public interface TestUserServiceClient {
|
||||
|
||||
/**
|
||||
* Creates user form provided data.
|
||||
*
|
||||
* @param name user name
|
||||
* @param email user email
|
||||
* @param password user password
|
||||
* @throws BadRequestException when user data validation failed
|
||||
* @throws ConflictException when user with given email/name exists
|
||||
* @throws ServerException when any other exception occurs
|
||||
*/
|
||||
void create(String name, String email, String password)
|
||||
throws BadRequestException, ConflictException, ServerException;
|
||||
|
||||
/**
|
||||
* Gets user by id.
|
||||
*
|
||||
* @param id user identifier
|
||||
* @return user with given identifier
|
||||
* @throws NotFoundException when user with given id not found
|
||||
* @throws ServerException when any other exception occurs
|
||||
*/
|
||||
User getById(String id) throws NotFoundException, ServerException;
|
||||
|
||||
/**
|
||||
* Gets user by email.
|
||||
*
|
||||
* @param email user email
|
||||
* @return user with given email
|
||||
* @throws BadRequestException when specified email is null or empty
|
||||
* @throws NotFoundException User with requested email not found
|
||||
* @throws ServerException when any other exception occurs
|
||||
*/
|
||||
User findByEmail(String email) throws NotFoundException, ServerException, BadRequestException;
|
||||
|
||||
/**
|
||||
* Gets user by name.
|
||||
*
|
||||
* @param name user name
|
||||
* @return user with given name
|
||||
* @throws BadRequestException when specified name is null or empty
|
||||
* @throws NotFoundException User with requested name not found
|
||||
* @throws ServerException when any other exception occurs
|
||||
*/
|
||||
User findByName(String name) throws NotFoundException, ServerException, BadRequestException;
|
||||
|
||||
/**
|
||||
* Deletes user by its id.
|
||||
*
|
||||
* @param id user identifier
|
||||
* @throws ConflictException when conflicts occurs e.g. user has related entities
|
||||
* @throws ServerException when any other exception occurs
|
||||
*/
|
||||
void remove(String id) throws ServerException, ConflictException;
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import org.eclipse.che.selenium.core.user.TestUser;
|
||||
|
||||
/** @author Dmytro Nochevnov */
|
||||
public interface TestUserServiceClientFactory {
|
||||
TestUserServiceClientImpl create(@Assisted TestUser testUser);
|
||||
}
|
||||
|
|
@ -1,128 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
import static org.eclipse.che.dto.server.DtoFactory.newDto;
|
||||
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.google.inject.assistedinject.AssistedInject;
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.ForbiddenException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.UnauthorizedException;
|
||||
import org.eclipse.che.api.core.model.user.User;
|
||||
import org.eclipse.che.api.user.shared.dto.UserDto;
|
||||
import org.eclipse.che.selenium.core.provider.TestApiEndpointUrlProvider;
|
||||
import org.eclipse.che.selenium.core.requestfactory.TestHttpJsonRequestFactory;
|
||||
import org.eclipse.che.selenium.core.requestfactory.TestUserHttpJsonRequestFactory;
|
||||
import org.eclipse.che.selenium.core.requestfactory.TestUserHttpJsonRequestFactoryCreator;
|
||||
import org.eclipse.che.selenium.core.user.TestUser;
|
||||
|
||||
/** @author Musienko Maxim */
|
||||
public class TestUserServiceClientImpl implements TestUserServiceClient {
|
||||
|
||||
private final String userServiceEndpoint;
|
||||
private final TestHttpJsonRequestFactory requestFactory;
|
||||
|
||||
public TestUserServiceClientImpl(
|
||||
TestApiEndpointUrlProvider apiEndpointProvider,
|
||||
TestUserHttpJsonRequestFactory userHttpJsonRequestFactory) {
|
||||
this.userServiceEndpoint = apiEndpointProvider.get().toString() + "user/";
|
||||
this.requestFactory = userHttpJsonRequestFactory;
|
||||
}
|
||||
|
||||
@AssistedInject
|
||||
public TestUserServiceClientImpl(
|
||||
TestApiEndpointUrlProvider apiEndpointProvider,
|
||||
TestUserHttpJsonRequestFactoryCreator userHttpJsonRequestFactoryCreator,
|
||||
@Assisted TestUser testUser) {
|
||||
this(apiEndpointProvider, userHttpJsonRequestFactoryCreator.create(testUser));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create(String name, String email, String password)
|
||||
throws BadRequestException, ConflictException, ServerException {
|
||||
try {
|
||||
requestFactory
|
||||
.fromUrl(userServiceEndpoint)
|
||||
.usePostMethod()
|
||||
.setBody(newDto(UserDto.class).withEmail(email).withName(name).withPassword(password))
|
||||
.request();
|
||||
} catch (IOException | UnauthorizedException | NotFoundException | ForbiddenException ex) {
|
||||
throw new ServerException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getById(String id) throws NotFoundException, ServerException {
|
||||
try {
|
||||
return requestFactory
|
||||
.fromUrl(userServiceEndpoint + id)
|
||||
.useGetMethod()
|
||||
.request()
|
||||
.asDto(UserDto.class);
|
||||
} catch (IOException
|
||||
| BadRequestException
|
||||
| UnauthorizedException
|
||||
| ForbiddenException
|
||||
| ConflictException ex) {
|
||||
throw new ServerException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public User findByEmail(String email)
|
||||
throws BadRequestException, NotFoundException, ServerException {
|
||||
try {
|
||||
return requestFactory
|
||||
.fromUrl(userServiceEndpoint + "find")
|
||||
.useGetMethod()
|
||||
.addQueryParam("email", URLEncoder.encode(email, "UTF-8"))
|
||||
.request()
|
||||
.asDto(UserDto.class);
|
||||
} catch (IOException | UnauthorizedException | ForbiddenException | ConflictException ex) {
|
||||
throw new ServerException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public User findByName(String name)
|
||||
throws BadRequestException, NotFoundException, ServerException {
|
||||
try {
|
||||
return requestFactory
|
||||
.fromUrl(userServiceEndpoint + "find")
|
||||
.useGetMethod()
|
||||
.addQueryParam("name", name)
|
||||
.request()
|
||||
.asDto(UserDto.class);
|
||||
} catch (IOException | UnauthorizedException | ForbiddenException | ConflictException ex) {
|
||||
throw new ServerException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(String id) throws ConflictException, ServerException {
|
||||
try {
|
||||
requestFactory.fromUrl(userServiceEndpoint + id).useDeleteMethod().request();
|
||||
} catch (IOException
|
||||
| BadRequestException
|
||||
| NotFoundException
|
||||
| UnauthorizedException
|
||||
| ForbiddenException ex) {
|
||||
throw new ServerException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
import java.util.List;
|
||||
import org.eclipse.che.api.core.model.workspace.Workspace;
|
||||
import org.eclipse.che.api.core.model.workspace.WorkspaceStatus;
|
||||
import org.eclipse.che.api.core.model.workspace.runtime.Server;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceConfigDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceDto;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
import org.eclipse.che.selenium.core.user.TestUser;
|
||||
import org.eclipse.che.selenium.core.workspace.MemoryMeasure;
|
||||
|
||||
public interface TestWorkspaceServiceClient {
|
||||
|
||||
List<String> getAll() throws Exception;
|
||||
|
||||
int getWorkspacesCount() throws Exception;
|
||||
|
||||
void stop(String workspaceName, String userName) throws Exception;
|
||||
|
||||
Workspace getByName(String workspace, String username) throws Exception;
|
||||
|
||||
boolean exists(String workspace, String username) throws Exception;
|
||||
|
||||
void delete(String workspaceName, String userName) throws Exception;
|
||||
|
||||
void waitStatus(String workspaceName, String userName, WorkspaceStatus expectedStatus)
|
||||
throws Exception;
|
||||
|
||||
void waitWorkspaceStart(String workspaceName, String userName) throws Exception;
|
||||
|
||||
/** Creates a new workspace. */
|
||||
Workspace createWorkspace(
|
||||
String workspaceName, int memory, MemoryMeasure memoryUnit, WorkspaceConfigDto workspace)
|
||||
throws Exception;
|
||||
|
||||
void sendStartRequest(String workspaceId, String workspaceName) throws Exception;
|
||||
|
||||
/** Starts workspace. */
|
||||
void start(String workspaceId, String workspaceName, TestUser workspaceOwner) throws Exception;
|
||||
|
||||
WorkspaceDto getById(String workspaceId) throws Exception;
|
||||
|
||||
WorkspaceStatus getStatus(String workspaceId) throws Exception;
|
||||
|
||||
@Deprecated
|
||||
@Nullable
|
||||
String getServerAddressByPort(String workspaceId, int port) throws Exception;
|
||||
|
||||
@Nullable
|
||||
Server getServerFromDevMachineBySymbolicName(String workspaceId, String serverName)
|
||||
throws Exception;
|
||||
|
||||
void ensureRunningStatus(Workspace workspace) throws IllegalStateException;
|
||||
|
||||
void deleteFactoryWorkspaces(String originalName, String username) throws Exception;
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.client;
|
||||
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import org.eclipse.che.selenium.core.user.TestUser;
|
||||
|
||||
/** @author Dmytro Nochevnov */
|
||||
public interface TestWorkspaceServiceClientFactory {
|
||||
TestWorkspaceServiceClient create(@Assisted TestUser testUser);
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.configuration;
|
||||
|
||||
/**
|
||||
* Exception happen in case of some problems with configuration.
|
||||
*
|
||||
* @author Sergii Kabashniuk
|
||||
*/
|
||||
public class ConfigurationException extends RuntimeException {
|
||||
public ConfigurationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.configuration;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import org.eclipse.che.inject.CheBootstrap;
|
||||
|
||||
/** In memory storage of TestConfiguration based on Map<String, String> config */
|
||||
public class InMemoryTestConfiguration implements TestConfiguration {
|
||||
|
||||
private final Map<String, String> config;
|
||||
|
||||
public InMemoryTestConfiguration() {
|
||||
this(new HashMap<>());
|
||||
}
|
||||
|
||||
public InMemoryTestConfiguration(TestConfiguration... configuration) {
|
||||
this();
|
||||
for (TestConfiguration testConfiguration : configuration) {
|
||||
addAll(testConfiguration.getMap());
|
||||
}
|
||||
// convert value of CHE_INFRASTRUCTURE to upper case to comply with Infrastructure
|
||||
// enumeration;
|
||||
config.put("che.infrastructure", config.get("che.infrastructure").toUpperCase());
|
||||
}
|
||||
|
||||
public InMemoryTestConfiguration(Map<String, String> config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
void addAll(Map<String, String> config) {
|
||||
this.config.putAll(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConfigured(String key) {
|
||||
return config.containsKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(String key) {
|
||||
String value = config.get(key);
|
||||
if (value == null) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder
|
||||
.append("\n")
|
||||
.append("======== IMPORTANT =========\n")
|
||||
.append("Key ")
|
||||
.append(key)
|
||||
.append(" is not configured\n")
|
||||
.append("You can configure it as :\n")
|
||||
.append("1. System property. Example: \t-D")
|
||||
.append(key)
|
||||
.append("=yourvalue \n")
|
||||
.append("2. Environment variable. Example: \texport CODENVY_")
|
||||
.append(key.toUpperCase().replace("_", "=").replace('.', '_').replace("=", "__"))
|
||||
.append("=yourvalue \n")
|
||||
.append("3. Or configured it in a property file in folder declared as ")
|
||||
.append(CheBootstrap.CHE_LOCAL_CONF_DIR)
|
||||
.append(" environment variable\n")
|
||||
.append("============================\n");
|
||||
throw new ConfigurationException(builder.toString());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getBoolean(String key) {
|
||||
return Boolean.parseBoolean(config.get(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getInt(String key) {
|
||||
return Integer.parseInt(config.get(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getLong(String key) {
|
||||
return Long.parseLong(config.get(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getMap() {
|
||||
return ImmutableMap.copyOf(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getMap(String keyPrefix) {
|
||||
return config
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(e -> e.getKey().startsWith(keyPrefix))
|
||||
.collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue()));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,177 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.configuration;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Properties;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import org.eclipse.che.inject.CheBootstrap;
|
||||
|
||||
/**
|
||||
* Represents in memory based storage of the test configuration.
|
||||
*
|
||||
* <p>Values of configuration are loaded in the following sequence:<br>
|
||||
* 1. Default configuration from target/conf/selenium.properties file.<br>
|
||||
* 2. All properties from CHE_LOCAL_CONF_DIR directory.<br>
|
||||
* 3. From java system properties (will be given prefix "sys.").<br>
|
||||
* 4. From environment variables (will be given prefix "env."). Symbol "_" is replaced by "." and
|
||||
* "__" is replaced by "_" in names of environment variables.<br>
|
||||
* Variables which start from "che." or "codenvy." don't have an additional prefix "sys." or "env.".
|
||||
*
|
||||
* @author Sergii Kabashniuk
|
||||
*/
|
||||
@Singleton
|
||||
public class SeleniumTestConfiguration extends InMemoryTestConfiguration {
|
||||
|
||||
@Inject
|
||||
public SeleniumTestConfiguration() {
|
||||
super(
|
||||
new DefaultConfiguration(),
|
||||
new PropertiesConfiguration(),
|
||||
new SystemPropertiesConfiguration(),
|
||||
new EnvironmentVariablesConfiguration());
|
||||
}
|
||||
|
||||
static class SystemPropertiesConfiguration extends InMemoryTestConfiguration {
|
||||
|
||||
SystemPropertiesConfiguration() {
|
||||
super();
|
||||
addAll(
|
||||
System.getProperties()
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(new PropertyNamePrefixPredicate<>("che.", "codenvy."))
|
||||
.map(e -> new AbstractMap.SimpleEntry<>((String) e.getKey(), ((String) e.getValue())))
|
||||
.collect(Collectors.toMap(SimpleEntry::getKey, SimpleEntry::getValue)));
|
||||
addAll(
|
||||
System.getProperties()
|
||||
.entrySet()
|
||||
.stream()
|
||||
.map(e -> new AbstractMap.SimpleEntry<>("sys." + e.getKey(), ((String) e.getValue())))
|
||||
.collect(Collectors.toMap(SimpleEntry::getKey, SimpleEntry::getValue)));
|
||||
}
|
||||
}
|
||||
|
||||
static class EnvironmentVariablesConfiguration extends InMemoryTestConfiguration {
|
||||
|
||||
EnvironmentVariablesConfiguration() {
|
||||
super();
|
||||
addAll(
|
||||
System.getenv()
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(new PropertyNamePrefixPredicate<>("CHE_", "CODENVY_"))
|
||||
.map(new EnvironmentVariableToSystemPropertyFormatNameConverter())
|
||||
.collect(Collectors.toMap(Entry::getKey, Entry::getValue)));
|
||||
addAll(
|
||||
System.getenv()
|
||||
.entrySet()
|
||||
.stream()
|
||||
.map(new EnvironmentVariableToSystemPropertyFormatNameConverter())
|
||||
.map(e -> new AbstractMap.SimpleEntry<>("env." + e.getKey(), e.getValue()))
|
||||
.collect(Collectors.toMap(SimpleEntry::getKey, SimpleEntry::getValue)));
|
||||
}
|
||||
}
|
||||
|
||||
static class PropertyNamePrefixPredicate<K, V> implements Predicate<Map.Entry<K, V>> {
|
||||
final String[] prefixes;
|
||||
|
||||
PropertyNamePrefixPredicate(String... prefix) {
|
||||
this.prefixes = prefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Map.Entry<K, V> entry) {
|
||||
for (String prefix : prefixes) {
|
||||
if (((String) entry.getKey()).startsWith(prefix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static class EnvironmentVariableToSystemPropertyFormatNameConverter
|
||||
implements Function<Map.Entry<String, String>, Map.Entry<String, String>> {
|
||||
@Override
|
||||
public Map.Entry<String, String> apply(Map.Entry<String, String> entry) {
|
||||
String name = entry.getKey();
|
||||
name = name.toLowerCase();
|
||||
// replace single underscore with dot and double underscores with single underscore
|
||||
// at first replace double underscores with equal sign which is forbidden in env variable name
|
||||
// then replace single underscores
|
||||
// then recover underscore from equal sign
|
||||
name = name.replace("__", "=");
|
||||
name = name.replace('_', '.');
|
||||
name = name.replace("=", "_");
|
||||
|
||||
return new AbstractMap.SimpleEntry<>(name, entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
static class DefaultConfiguration extends PropertiesConfiguration {
|
||||
DefaultConfiguration() {
|
||||
URL defaultConfig = getClass().getClassLoader().getResource("conf/selenium.properties");
|
||||
if (defaultConfig != null) {
|
||||
addFile(new File(defaultConfig.getFile()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Implementation of TestConfiguration based on folder with properties files inside. */
|
||||
static class PropertiesConfiguration extends InMemoryTestConfiguration {
|
||||
|
||||
PropertiesConfiguration() {
|
||||
String extConfig = System.getenv(CheBootstrap.CHE_LOCAL_CONF_DIR);
|
||||
if (extConfig != null) {
|
||||
File extConfigFile = new File(extConfig);
|
||||
if (extConfigFile.isDirectory() && extConfigFile.exists()) {
|
||||
final File[] files = extConfigFile.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
addFile(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addFile(File file) {
|
||||
if (!file.isDirectory()) {
|
||||
if ("properties".equals(Files.getFileExtension(file.getName()))) {
|
||||
Properties properties = new Properties();
|
||||
try (Reader reader = Files.newReader(file, Charset.forName("UTF-8"))) {
|
||||
properties.load(reader);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(
|
||||
String.format("Unable to read configuration file %s", file), e);
|
||||
}
|
||||
addAll(Maps.fromProperties(properties));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.configuration;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents configuration of testing framework
|
||||
*
|
||||
* @author Sergii Kabashniuk
|
||||
*/
|
||||
public interface TestConfiguration {
|
||||
|
||||
/**
|
||||
* Test if configuration contains parameter.
|
||||
*
|
||||
* @param key configuration key.
|
||||
* @return - true if key is configured.
|
||||
*/
|
||||
boolean isConfigured(String key);
|
||||
|
||||
/**
|
||||
* @param key - configuration key.
|
||||
* @return String based value of configuration property.
|
||||
* @throws ConfigurationException if kys is not configured
|
||||
*/
|
||||
String getString(String key) throws ConfigurationException;
|
||||
|
||||
/**
|
||||
* @param key - configuration key.
|
||||
* @return Boolean based value of configuration property.
|
||||
* @throws ConfigurationException if kys is not configured
|
||||
*/
|
||||
Boolean getBoolean(String key) throws ConfigurationException;
|
||||
|
||||
/**
|
||||
* @param key - configuration key.
|
||||
* @return Integer based value of configuration property.
|
||||
* @throws ConfigurationException if kys is not configured
|
||||
*/
|
||||
Integer getInt(String key) throws ConfigurationException;
|
||||
|
||||
/**
|
||||
* @param key - configuration key.
|
||||
* @return Long based value of configuration property.
|
||||
* @throws ConfigurationException if kys is not configured
|
||||
*/
|
||||
Long getLong(String key) throws ConfigurationException;
|
||||
|
||||
/** @return all configuration parameters. */
|
||||
Map<String, String> getMap();
|
||||
|
||||
/**
|
||||
* @param keyPrefix - filter all properties with given prefix
|
||||
* @return - key/value map of configuration.
|
||||
*/
|
||||
Map<String, String> getMap(String keyPrefix);
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.constant;
|
||||
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
/**
|
||||
* Reflects values of environment variable CHE_INFRASTRUCTURE
|
||||
*
|
||||
* @author Dmytro Nochevnov
|
||||
*/
|
||||
@Singleton
|
||||
public enum Infrastructure {
|
||||
DOCKER,
|
||||
OPENSHIFT,
|
||||
K8S,
|
||||
OSIO
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.constant;
|
||||
|
||||
/** @author Aleksandr Shmaraev */
|
||||
public enum TestBrowser {
|
||||
GOOGLE_CHROME
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.constant;
|
||||
|
||||
/** Represent of main constants for tests in seconds */
|
||||
public final class TestTimeoutsConstants {
|
||||
public static final int MULTIPLE = 1;
|
||||
public static final int APPLICATION_START_TIMEOUT_SEC = 300 * MULTIPLE;
|
||||
public static final int PREPARING_WS_TIMEOUT_SEC = 240 * MULTIPLE;
|
||||
public static final int UPDATING_PROJECT_TIMEOUT_SEC = 180 * MULTIPLE;
|
||||
public static final int EXPECTED_MESS_IN_CONSOLE_SEC = 120 * MULTIPLE;
|
||||
public static final int LOADER_TIMEOUT_SEC = 60 * MULTIPLE;
|
||||
public static final int WIDGET_TIMEOUT_SEC = 40 * MULTIPLE;
|
||||
public static final int ELEMENT_TIMEOUT_SEC = 20 * MULTIPLE;
|
||||
public static final int LOAD_PAGE_TIMEOUT_SEC = 10 * MULTIPLE;
|
||||
public static final int REDRAW_UI_ELEMENTS_TIMEOUT_SEC = 5 * MULTIPLE;
|
||||
public static final int ATTACHING_ELEM_TO_DOM_SEC = 3 * MULTIPLE;
|
||||
public static final int MINIMUM_SEC = MULTIPLE;
|
||||
public static final int DEFAULT_TIMEOUT = LOAD_PAGE_TIMEOUT_SEC;
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.entrance;
|
||||
|
||||
import org.eclipse.che.selenium.core.user.TestUser;
|
||||
|
||||
/** @author Dmytro Nochevnov */
|
||||
public interface Entrance {
|
||||
/**
|
||||
* Login to product.
|
||||
*
|
||||
* @param user user to login
|
||||
*/
|
||||
void login(TestUser user);
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.factory;
|
||||
|
||||
/**
|
||||
* Factory templates.
|
||||
*
|
||||
* @author Anatolii Bazko
|
||||
*/
|
||||
public class FactoryTemplate {
|
||||
public static final String MINIMAL = "minimal.json";
|
||||
|
||||
private FactoryTemplate() {}
|
||||
}
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.factory;
|
||||
|
||||
import org.eclipse.che.api.core.model.workspace.WorkspaceStatus;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
import org.eclipse.che.selenium.core.SeleniumWebDriver;
|
||||
import org.eclipse.che.selenium.core.client.TestFactoryServiceClient;
|
||||
import org.eclipse.che.selenium.core.client.TestWorkspaceServiceClient;
|
||||
import org.eclipse.che.selenium.core.entrance.Entrance;
|
||||
import org.eclipse.che.selenium.core.provider.TestDashboardUrlProvider;
|
||||
import org.eclipse.che.selenium.core.user.DefaultTestUser;
|
||||
import org.eclipse.che.selenium.core.webdriver.SeleniumWebDriverHelper;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
|
||||
/** @author Anatolii Bazko */
|
||||
public class TestFactory {
|
||||
private final DefaultTestUser owner;
|
||||
private final FactoryDto factoryDto;
|
||||
private final TestDashboardUrlProvider dashboardUrl;
|
||||
private final TestFactoryServiceClient testFactoryServiceClient;
|
||||
private final TestWorkspaceServiceClient workspaceServiceClient;
|
||||
private final Entrance entrance;
|
||||
private final String factoryUrl;
|
||||
private final SeleniumWebDriver seleniumWebDriver;
|
||||
private final SeleniumWebDriverHelper seleniumWebDriverHelper;
|
||||
|
||||
public TestFactory(
|
||||
String factoryUrl,
|
||||
DefaultTestUser owner,
|
||||
FactoryDto factoryDto,
|
||||
TestDashboardUrlProvider dashboardUrl,
|
||||
TestFactoryServiceClient factoryServiceClient,
|
||||
TestWorkspaceServiceClient workspaceServiceClient,
|
||||
Entrance entrance,
|
||||
SeleniumWebDriver seleniumWebDriver,
|
||||
SeleniumWebDriverHelper seleniumWebDriverHelper) {
|
||||
this.factoryDto = factoryDto;
|
||||
this.owner = owner;
|
||||
this.factoryUrl = factoryUrl;
|
||||
this.dashboardUrl = dashboardUrl;
|
||||
this.testFactoryServiceClient = factoryServiceClient;
|
||||
this.workspaceServiceClient = workspaceServiceClient;
|
||||
this.entrance = entrance;
|
||||
this.seleniumWebDriver = seleniumWebDriver;
|
||||
this.seleniumWebDriverHelper = seleniumWebDriverHelper;
|
||||
}
|
||||
|
||||
/** Login to factory and open it by url. */
|
||||
public void authenticateAndOpen() {
|
||||
seleniumWebDriver.get(dashboardUrl.get().toString());
|
||||
entrance.login(owner);
|
||||
seleniumWebDriver.get(factoryUrl);
|
||||
}
|
||||
|
||||
/** Opens factory url. */
|
||||
public void open(WebDriver driver) {
|
||||
driver.get(factoryUrl);
|
||||
}
|
||||
|
||||
public void delete() throws Exception {
|
||||
seleniumWebDriver.quit();
|
||||
|
||||
workspaceServiceClient.deleteFactoryWorkspaces(
|
||||
factoryDto.getWorkspace().getName(), owner.getName());
|
||||
deleteFactory();
|
||||
}
|
||||
|
||||
private void deleteFactory() {
|
||||
if (isNamedFactory()) {
|
||||
testFactoryServiceClient.deleteFactory(factoryDto.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isNamedFactory() {
|
||||
return factoryDto.getName() != null;
|
||||
}
|
||||
|
||||
public WorkspaceStatus getWorkspaceStatusAssociatedWithFactory() throws Exception {
|
||||
return workspaceServiceClient
|
||||
.getByName(factoryDto.getWorkspace().getName(), owner.getName())
|
||||
.getStatus();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,307 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.factory;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Collections.singletonMap;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.List;
|
||||
import javax.inject.Named;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonRequest;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonRequestFactory;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonResponse;
|
||||
import org.eclipse.che.api.core.rest.shared.dto.Link;
|
||||
import org.eclipse.che.api.factory.shared.dto.AuthorDto;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
import org.eclipse.che.api.factory.shared.dto.IdeDto;
|
||||
import org.eclipse.che.api.factory.shared.dto.PoliciesDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceConfigDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.devfile.DevfileDto;
|
||||
import org.eclipse.che.commons.lang.IoUtil;
|
||||
import org.eclipse.che.commons.lang.NameGenerator;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
import org.eclipse.che.selenium.core.SeleniumWebDriver;
|
||||
import org.eclipse.che.selenium.core.client.TestFactoryServiceClient;
|
||||
import org.eclipse.che.selenium.core.client.TestUserPreferencesServiceClient;
|
||||
import org.eclipse.che.selenium.core.client.TestWorkspaceServiceClient;
|
||||
import org.eclipse.che.selenium.core.constant.Infrastructure;
|
||||
import org.eclipse.che.selenium.core.entrance.Entrance;
|
||||
import org.eclipse.che.selenium.core.provider.TestApiEndpointUrlProvider;
|
||||
import org.eclipse.che.selenium.core.provider.TestDashboardUrlProvider;
|
||||
import org.eclipse.che.selenium.core.provider.TestIdeUrlProvider;
|
||||
import org.eclipse.che.selenium.core.user.DefaultTestUser;
|
||||
import org.eclipse.che.selenium.core.webdriver.SeleniumWebDriverHelper;
|
||||
|
||||
/** @author Anatolii Bazko */
|
||||
@Singleton
|
||||
public class TestFactoryInitializer {
|
||||
|
||||
@Inject private DefaultTestUser defaultUser;
|
||||
@Inject private TestIdeUrlProvider ideUrlProvider;
|
||||
@Inject private TestDashboardUrlProvider dashboardUrlProvider;
|
||||
@Inject private TestApiEndpointUrlProvider apiEndpointProvider;
|
||||
@Inject private HttpJsonRequestFactory requestFactory;
|
||||
@Inject private TestFactoryServiceClient testFactoryServiceClient;
|
||||
@Inject private TestWorkspaceServiceClient workspaceServiceClient;
|
||||
@Inject private Entrance entrance;
|
||||
@Inject private SeleniumWebDriver seleniumWebDriver;
|
||||
@Inject private SeleniumWebDriverHelper seleniumWebDriverHelper;
|
||||
@Inject private TestUserPreferencesServiceClient testUserPreferencesServiceClient;
|
||||
|
||||
@Inject
|
||||
@Named("che.infrastructure")
|
||||
private Infrastructure infrastructure;
|
||||
|
||||
/**
|
||||
* Initialize {@link TestFactory} base upon template.
|
||||
*
|
||||
* @see FactoryTemplate
|
||||
*/
|
||||
public TestFactoryBuilder fromTemplate(String template) throws Exception {
|
||||
String name = NameGenerator.generate("factory", 6);
|
||||
InputStream resource = TestFactory.class.getResourceAsStream(getTemplateDirectory(template));
|
||||
if (resource == null) {
|
||||
throw new IOException(format("Factory template '%s' not found", template));
|
||||
}
|
||||
|
||||
String factoryTemplate = IoUtil.readStream(resource);
|
||||
FactoryDto factoryDto =
|
||||
DtoFactory.getInstance()
|
||||
.createDtoFromJson(factoryTemplate, FactoryDto.class)
|
||||
.withName(name);
|
||||
factoryDto.getWorkspace().setName(name);
|
||||
return new TestFactoryBuilder(factoryDto);
|
||||
}
|
||||
|
||||
private String getTemplateDirectory(String template) {
|
||||
String templateDirectoryName;
|
||||
switch (infrastructure) {
|
||||
case OSIO:
|
||||
templateDirectoryName = Infrastructure.OPENSHIFT.toString().toLowerCase();
|
||||
break;
|
||||
|
||||
default:
|
||||
templateDirectoryName = infrastructure.toString().toLowerCase();
|
||||
}
|
||||
|
||||
return String.format("/templates/factory/%s/%s", templateDirectoryName, template);
|
||||
}
|
||||
|
||||
/** Initialize {@link TestFactory} base upon url. Can't be modified. */
|
||||
public TestFactory fromUrl(String url) throws Exception {
|
||||
HttpJsonRequest httpJsonRequest =
|
||||
requestFactory.fromUrl(apiEndpointProvider.get() + "factory/resolver");
|
||||
httpJsonRequest.setBody(singletonMap("url", url));
|
||||
HttpJsonResponse response = httpJsonRequest.request();
|
||||
|
||||
FactoryDto factoryDto = response.asDto(FactoryDto.class);
|
||||
String factoryUrl = ideUrlProvider.get() + "f?url=" + URLEncoder.encode(url, "UTF8");
|
||||
return new TestFactory(
|
||||
factoryUrl,
|
||||
defaultUser,
|
||||
factoryDto,
|
||||
dashboardUrlProvider,
|
||||
testFactoryServiceClient,
|
||||
workspaceServiceClient,
|
||||
entrance,
|
||||
seleniumWebDriver,
|
||||
seleniumWebDriverHelper);
|
||||
}
|
||||
|
||||
/** Builder for {@link TestFactory}. */
|
||||
public class TestFactoryBuilder implements FactoryDto {
|
||||
private final FactoryDto factoryDto;
|
||||
|
||||
private TestFactoryBuilder(FactoryDto factoryDto) {
|
||||
this.factoryDto = factoryDto;
|
||||
}
|
||||
|
||||
public TestFactory build() throws Exception {
|
||||
String factoryUrl = testFactoryServiceClient.createFactory(factoryDto);
|
||||
return new TestFactory(
|
||||
factoryUrl,
|
||||
defaultUser,
|
||||
factoryDto,
|
||||
dashboardUrlProvider,
|
||||
testFactoryServiceClient,
|
||||
workspaceServiceClient,
|
||||
entrance,
|
||||
seleniumWebDriver,
|
||||
seleniumWebDriverHelper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Link> getLinks() {
|
||||
return factoryDto.getLinks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLinks(List<Link> links) {
|
||||
factoryDto.setLinks(links);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Link> getLinks(String rel) {
|
||||
return factoryDto.getLinks(rel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Link getLink(String rel) {
|
||||
return factoryDto.getLink(rel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getV() {
|
||||
return factoryDto.getV();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setV(String v) {
|
||||
factoryDto.setV(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FactoryDto withV(String v) {
|
||||
return factoryDto.withV(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DevfileDto getDevfile() {
|
||||
return factoryDto.getDevfile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDevfile(DevfileDto workspace) {
|
||||
factoryDto.setDevfile(workspace);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FactoryDto withDevfile(DevfileDto devfileDto) {
|
||||
return factoryDto.withDevfile(devfileDto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorkspaceConfigDto getWorkspace() {
|
||||
return factoryDto.getWorkspace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWorkspace(WorkspaceConfigDto workspace) {
|
||||
factoryDto.setWorkspace(workspace);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FactoryDto withWorkspace(WorkspaceConfigDto workspace) {
|
||||
return factoryDto.withWorkspace(workspace);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PoliciesDto getPolicies() {
|
||||
return factoryDto.getPolicies();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPolicies(PoliciesDto policies) {
|
||||
factoryDto.setPolicies(policies);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FactoryDto withPolicies(PoliciesDto policies) {
|
||||
return factoryDto.withPolicies(policies);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthorDto getCreator() {
|
||||
return factoryDto.getCreator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreator(AuthorDto creator) {
|
||||
factoryDto.setCreator(creator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FactoryDto withCreator(AuthorDto creator) {
|
||||
return factoryDto.withCreator(creator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdeDto getIde() {
|
||||
return factoryDto.getIde();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIde(IdeDto ide) {
|
||||
factoryDto.setIde(ide);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FactoryDto withIde(IdeDto ide) {
|
||||
return factoryDto.withIde(ide);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return factoryDto.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
factoryDto.setId(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FactoryDto withId(String id) {
|
||||
return factoryDto.withId(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return factoryDto.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
factoryDto.setName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FactoryDto withName(String name) {
|
||||
return factoryDto.withName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FactoryDto withLinks(List<Link> links) {
|
||||
return factoryDto.withLinks(links);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSource() {
|
||||
return factoryDto.getSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSource(String source) {
|
||||
factoryDto.setSource(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FactoryDto withSource(String source) {
|
||||
return factoryDto.withSource(source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.inject;
|
||||
|
||||
import static com.google.inject.matcher.Matchers.any;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.spi.TypeEncounter;
|
||||
import com.google.inject.spi.TypeListener;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.function.Consumer;
|
||||
import org.eclipse.che.selenium.core.SeleniumWebDriver;
|
||||
import org.eclipse.che.selenium.core.organization.InjectTestOrganization;
|
||||
import org.eclipse.che.selenium.core.organization.TestOrganization;
|
||||
import org.eclipse.che.selenium.core.organization.TestOrganizationInjector;
|
||||
import org.eclipse.che.selenium.core.workspace.InjectTestWorkspace;
|
||||
import org.eclipse.che.selenium.core.workspace.TestWorkspace;
|
||||
import org.eclipse.che.selenium.core.workspace.TestWorkspaceInjector;
|
||||
|
||||
/**
|
||||
* Guice module per test class.
|
||||
*
|
||||
* @author Anatolii Bazko
|
||||
*/
|
||||
public class SeleniumClassModule extends AbstractModule {
|
||||
@Override
|
||||
public void configure() {
|
||||
bind(SeleniumWebDriver.class);
|
||||
|
||||
bindListener(any(), new WorkspaceTypeListener(binder().getProvider(Injector.class)));
|
||||
bindListener(any(), new OrganizationTypeListener(binder().getProvider(Injector.class)));
|
||||
}
|
||||
|
||||
private class WorkspaceTypeListener implements TypeListener {
|
||||
private final Provider<Injector> injectorProvider;
|
||||
|
||||
public WorkspaceTypeListener(Provider<Injector> injector) {
|
||||
this.injectorProvider = injector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
|
||||
traverseClassHierarchy(
|
||||
type.getRawType(),
|
||||
(clazz) -> {
|
||||
for (Field field : clazz.getDeclaredFields()) {
|
||||
if (field.getType() == TestWorkspace.class
|
||||
&& field.isAnnotationPresent(InjectTestWorkspace.class)) {
|
||||
encounter.register(
|
||||
new TestWorkspaceInjector<>(
|
||||
field,
|
||||
field.getAnnotation(InjectTestWorkspace.class),
|
||||
injectorProvider.get()));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void traverseClassHierarchy(Class clazz, Consumer<Class> handler) {
|
||||
if (clazz == null || clazz.equals(Object.class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
traverseClassHierarchy(clazz.getSuperclass(), handler);
|
||||
handler.accept(clazz);
|
||||
}
|
||||
}
|
||||
|
||||
private class OrganizationTypeListener implements TypeListener {
|
||||
private final Provider<Injector> injectorProvider;
|
||||
|
||||
public OrganizationTypeListener(Provider<Injector> injector) {
|
||||
this.injectorProvider = injector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
|
||||
Class<?> clazz = type.getRawType();
|
||||
for (Field field : clazz.getDeclaredFields()) {
|
||||
if (field.getType() == TestOrganization.class
|
||||
&& field.isAnnotationPresent(InjectTestOrganization.class)) {
|
||||
encounter.register(
|
||||
new TestOrganizationInjector<>(
|
||||
field, field.getAnnotation(InjectTestOrganization.class), injectorProvider));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,721 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.inject;
|
||||
|
||||
import static com.google.inject.Guice.createInjector;
|
||||
import static java.lang.Runtime.getRuntime;
|
||||
import static java.lang.String.format;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.name.Named;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.eclipse.che.commons.json.JsonParseException;
|
||||
import org.eclipse.che.commons.lang.ZipUtils;
|
||||
import org.eclipse.che.selenium.core.SeleniumWebDriver;
|
||||
import org.eclipse.che.selenium.core.TestGroup;
|
||||
import org.eclipse.che.selenium.core.client.TestGitHubServiceClient;
|
||||
import org.eclipse.che.selenium.core.organization.InjectTestOrganization;
|
||||
import org.eclipse.che.selenium.core.pageobject.InjectPageObject;
|
||||
import org.eclipse.che.selenium.core.pageobject.PageObjectsInjector;
|
||||
import org.eclipse.che.selenium.core.user.DefaultTestUser;
|
||||
import org.eclipse.che.selenium.core.webdriver.SeleniumWebDriverFactory;
|
||||
import org.eclipse.che.selenium.core.webdriver.log.WebDriverLogsReaderFactory;
|
||||
import org.eclipse.che.selenium.core.workspace.InjectTestWorkspace;
|
||||
import org.eclipse.che.selenium.core.workspace.TestWorkspace;
|
||||
import org.eclipse.che.selenium.core.workspace.TestWorkspaceLogsReader;
|
||||
import org.eclipse.che.selenium.core.workspace.TestWorkspaceProvider;
|
||||
import org.openqa.selenium.OutputType;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebDriverException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.testng.IAnnotationTransformer2;
|
||||
import org.testng.IConfigurationListener;
|
||||
import org.testng.IExecutionListener;
|
||||
import org.testng.IInvokedMethod;
|
||||
import org.testng.IInvokedMethodListener;
|
||||
import org.testng.ISuite;
|
||||
import org.testng.ISuiteListener;
|
||||
import org.testng.ITestContext;
|
||||
import org.testng.ITestListener;
|
||||
import org.testng.ITestNGMethod;
|
||||
import org.testng.ITestResult;
|
||||
import org.testng.SkipException;
|
||||
import org.testng.TestException;
|
||||
import org.testng.annotations.IConfigurationAnnotation;
|
||||
import org.testng.annotations.IDataProviderAnnotation;
|
||||
import org.testng.annotations.IFactoryAnnotation;
|
||||
import org.testng.annotations.ITestAnnotation;
|
||||
|
||||
/**
|
||||
* Tests lifecycle handler.
|
||||
*
|
||||
* <p>Adding {@link IConfigurationListener} brings bug when all methods of the listener will be
|
||||
* invoked twice.
|
||||
*
|
||||
* @author Anatolii Bazko
|
||||
* @author Dmytro Nochevnov
|
||||
*/
|
||||
public abstract class SeleniumTestHandler
|
||||
implements ITestListener,
|
||||
ISuiteListener,
|
||||
IInvokedMethodListener,
|
||||
IExecutionListener,
|
||||
IAnnotationTransformer2,
|
||||
IConfigurationListener {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SeleniumTestHandler.class);
|
||||
private static final AtomicBoolean isCleanUpCompleted = new AtomicBoolean();
|
||||
|
||||
@Inject private SeleniumWebDriverFactory seleniumWebDriverFactory;
|
||||
|
||||
@Inject
|
||||
@Named("tests.screenshots_dir")
|
||||
private String screenshotsDir;
|
||||
|
||||
@Inject
|
||||
@Named("tests.htmldumps_dir")
|
||||
private String htmldumpsDir;
|
||||
|
||||
@Inject
|
||||
@Named("tests.webdriverlogs_dir")
|
||||
private String webDriverLogsDir;
|
||||
|
||||
@Inject
|
||||
@Named("tests.workspacelogs_dir")
|
||||
private String workspaceLogsDir;
|
||||
|
||||
@Inject private PageObjectsInjector pageObjectsInjector;
|
||||
|
||||
@Inject
|
||||
@Named("github.username")
|
||||
private String gitHubUsername;
|
||||
|
||||
@Inject
|
||||
@Named("github.password")
|
||||
private String gitHubPassword;
|
||||
|
||||
@Inject
|
||||
@Named("sys.excludedGroups")
|
||||
private String excludedGroups;
|
||||
|
||||
@Inject private DefaultTestUser defaultTestUser;
|
||||
@Inject private TestWorkspaceProvider testWorkspaceProvider;
|
||||
@Inject private TestGitHubServiceClient gitHubClientService;
|
||||
@Inject private TestWorkspaceLogsReader testWorkspaceLogsReader;
|
||||
@Inject private SeleniumTestStatistics seleniumTestStatistics;
|
||||
@Inject private WebDriverLogsReaderFactory webDriverLogsReaderFactory;
|
||||
@Inject private TestFilter testFilter;
|
||||
|
||||
private final Injector injector;
|
||||
|
||||
// this is the map {thread ID} -> {test instance}
|
||||
private final Map<Long, Object> runningTests = new ConcurrentHashMap<>();
|
||||
|
||||
// this is the map {test class FQN} -> {failed test method}
|
||||
private final Map<String, ITestResult> testsWithFailure = new ConcurrentHashMap<>();
|
||||
|
||||
public SeleniumTestHandler() {
|
||||
injector = createInjector(getParentModules());
|
||||
injector.injectMembers(this);
|
||||
|
||||
getRuntime().addShutdownHook(new Thread(this::shutdown));
|
||||
|
||||
revokeGithubOauthToken();
|
||||
checkWebDriverSessionCreation();
|
||||
}
|
||||
|
||||
private void revokeGithubOauthToken() {
|
||||
// do not revoke if github tests are not being executed
|
||||
if (excludedGroups != null && excludedGroups.contains(TestGroup.GITHUB)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
gitHubClientService.deleteAllGrants(gitHubUsername, gitHubPassword);
|
||||
} catch (Exception e) {
|
||||
LOG.warn("There was an error of revoking the github oauth token.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTestStart(ITestResult result) {
|
||||
LOG.info(
|
||||
"Starting test #{} {}. {}",
|
||||
seleniumTestStatistics.hitStart(),
|
||||
getStartingTestLabel(result.getMethod()),
|
||||
seleniumTestStatistics.toString());
|
||||
|
||||
skipTestIfNeeded(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTestSuccess(ITestResult result) {
|
||||
seleniumTestStatistics.hitPass();
|
||||
onTestFinish(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTestFailure(ITestResult result) {
|
||||
seleniumTestStatistics.hitFail();
|
||||
onTestFinish(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTestSkipped(ITestResult result) {
|
||||
seleniumTestStatistics.hitSkip();
|
||||
onTestFinish(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
|
||||
seleniumTestStatistics.hitFail();
|
||||
onTestFinish(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(ITestContext context) {}
|
||||
|
||||
@Override
|
||||
public void onFinish(ITestContext context) {}
|
||||
|
||||
@Override
|
||||
public void onStart(ISuite suite) {
|
||||
suite.setParentInjector(injector);
|
||||
long numberOfEnabledTests =
|
||||
suite.getAllMethods().parallelStream().filter(ITestNGMethod::getEnabled).count();
|
||||
LOG.info("Starting suite '{}' with {} test methods.", suite.getName(), numberOfEnabledTests);
|
||||
}
|
||||
|
||||
/** Check if webdriver session can be created without errors. */
|
||||
private void checkWebDriverSessionCreation() {
|
||||
SeleniumWebDriver seleniumWebDriver = null;
|
||||
try {
|
||||
seleniumWebDriver = seleniumWebDriverFactory.create();
|
||||
} finally {
|
||||
Optional.ofNullable(seleniumWebDriver)
|
||||
.ifPresent(SeleniumWebDriver::quit); // finish webdriver session
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish(ISuite suite) {}
|
||||
|
||||
@Override
|
||||
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
|
||||
Object invokingTestInstance = method.getTestMethod().getInstance();
|
||||
if (runningTests.containsValue(invokingTestInstance)) {
|
||||
return;
|
||||
}
|
||||
|
||||
long currentThreadId = Thread.currentThread().getId();
|
||||
if (isNewTestInProgress(invokingTestInstance)) {
|
||||
Object previousTestInstance = runningTests.remove(currentThreadId);
|
||||
preDestroy(previousTestInstance);
|
||||
testsWithFailure.remove(previousTestInstance.getClass().getName());
|
||||
}
|
||||
|
||||
String testName = invokingTestInstance.getClass().getName();
|
||||
|
||||
try {
|
||||
LOG.info("Dependencies injection in {}", testName);
|
||||
injectDependencies(testResult.getTestContext(), invokingTestInstance);
|
||||
} catch (Exception e) {
|
||||
String errorMessage = "Failed to inject fields in " + testName;
|
||||
LOG.error(errorMessage, e);
|
||||
throw new TestException(errorMessage, e);
|
||||
} finally {
|
||||
runningTests.put(currentThreadId, invokingTestInstance);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isNewTestInProgress(Object testInstance) {
|
||||
Thread currentThread = Thread.currentThread();
|
||||
|
||||
return runningTests.containsKey(currentThread.getId())
|
||||
&& runningTests.get(currentThread.getId()) != testInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterInvocation(IInvokedMethod method, ITestResult result) {}
|
||||
|
||||
@Override
|
||||
public void onExecutionStart() {}
|
||||
|
||||
@Override
|
||||
public void onExecutionFinish() {
|
||||
shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transform(
|
||||
ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
|
||||
testFilter.excludeTestOfImproperGroup(annotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transform(
|
||||
IConfigurationAnnotation annotation,
|
||||
Class testClass,
|
||||
Constructor testConstructor,
|
||||
Method testMethod) {
|
||||
testFilter.excludeTestOfImproperGroup(annotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transform(IDataProviderAnnotation annotation, Method method) {}
|
||||
|
||||
@Override
|
||||
public void transform(IFactoryAnnotation annotation, Method method) {}
|
||||
|
||||
@Override
|
||||
public void onConfigurationSuccess(ITestResult result) {}
|
||||
|
||||
@Override
|
||||
public void onConfigurationFailure(ITestResult result) {
|
||||
onTestFinish(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationSkip(ITestResult result) {
|
||||
onTestFinish(result);
|
||||
}
|
||||
|
||||
/** Injects dependencies into the given test class using {@link Guice} and custom injectors. */
|
||||
private void injectDependencies(ITestContext testContext, Object testInstance) throws Exception {
|
||||
Injector injector = testContext.getSuite().getParentInjector();
|
||||
|
||||
List<Module> childModules = new ArrayList<>(getChildModules());
|
||||
childModules.add(new SeleniumClassModule());
|
||||
|
||||
Injector classInjector = injector.createChildInjector(childModules);
|
||||
classInjector.injectMembers(testInstance);
|
||||
|
||||
pageObjectsInjector.injectMembers(testInstance, classInjector);
|
||||
}
|
||||
|
||||
/** Is invoked when test or configuration is finished. */
|
||||
private void onTestFinish(ITestResult result) {
|
||||
// do not treat SeleniumTestHandler error as test failure
|
||||
if (testsWithFailure.containsKey(result.getTestClass().getRealClass().getName())
|
||||
&& testsWithFailure
|
||||
.get(result.getTestClass().getRealClass().getName())
|
||||
.getMethod()
|
||||
.equals(result.getMethod())
|
||||
&& result.getMethod().getCurrentInvocationCount() == 1) {
|
||||
// restore initial test exception
|
||||
result.setThrowable(
|
||||
testsWithFailure.get(result.getTestClass().getRealClass().getName()).getThrowable());
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.getStatus() == ITestResult.FAILURE || result.getStatus() == ITestResult.SKIP) {
|
||||
switch (result.getStatus()) {
|
||||
case ITestResult.FAILURE:
|
||||
if (result.getMethod().isTest()) {
|
||||
String errorDetails =
|
||||
result.getThrowable() != null
|
||||
? " Error: " + result.getThrowable().getLocalizedMessage()
|
||||
: "";
|
||||
|
||||
LOG.error("Test {} failed.{}", getCompletedTestLabel(result.getMethod()), errorDetails);
|
||||
LOG.debug(result.getThrowable().getLocalizedMessage(), result.getThrowable());
|
||||
|
||||
testsWithFailure.put(result.getTestClass().getRealClass().getName(), result);
|
||||
}
|
||||
|
||||
captureWebDriver(result);
|
||||
captureTestWorkspaceLogs(result);
|
||||
|
||||
break;
|
||||
|
||||
case ITestResult.SKIP:
|
||||
String skipReasonDetails =
|
||||
result.getThrowable() != null
|
||||
? " The reason: " + result.getThrowable().getLocalizedMessage()
|
||||
: "";
|
||||
if (result.getMethod().isTest()) {
|
||||
LOG.warn(
|
||||
"Test {} skipped.{}", getCompletedTestLabel(result.getMethod()), skipReasonDetails);
|
||||
}
|
||||
|
||||
// don't capture test data if test is skipped because of previous test with higher
|
||||
// priority failed
|
||||
if (testsWithFailure.containsKey(result.getMethod().getInstance().getClass().getName())) {
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void captureTestWorkspaceLogs(ITestResult result) {
|
||||
Object testInstance = result.getInstance();
|
||||
traverseClassHierarchy(
|
||||
testInstance.getClass(),
|
||||
(clazz) -> {
|
||||
for (Field field : clazz.getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
|
||||
Object obj;
|
||||
try {
|
||||
obj = field.get(testInstance);
|
||||
} catch (IllegalAccessException e) {
|
||||
LOG.error(
|
||||
"Field {} is inaccessible in {}.",
|
||||
field.getName(),
|
||||
testInstance.getClass().getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(obj instanceof TestWorkspace)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
if (((TestWorkspace) obj).getId() == null) {
|
||||
continue;
|
||||
}
|
||||
} catch (ExecutionException | InterruptedException e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String testReference = getTestReference(result);
|
||||
Path pathToStoreWorkspaceLogs = Paths.get(workspaceLogsDir, testReference);
|
||||
testWorkspaceLogsReader.store((TestWorkspace) obj, pathToStoreWorkspaceLogs, false);
|
||||
Path pathToZipWithWorkspaceLogs =
|
||||
pathToStoreWorkspaceLogs
|
||||
.getParent()
|
||||
.resolve(getTestResultFilename(testReference, "zip"));
|
||||
|
||||
if (!Files.exists(pathToStoreWorkspaceLogs)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Path zip = Files.createFile(pathToZipWithWorkspaceLogs);
|
||||
try (ZipOutputStream out = ZipUtils.stream(zip)) {
|
||||
ZipUtils.add(out, pathToStoreWorkspaceLogs);
|
||||
}
|
||||
|
||||
FileUtils.deleteQuietly(pathToStoreWorkspaceLogs.toFile());
|
||||
} catch (IOException | IllegalArgumentException e) {
|
||||
LOG.warn("Error of creation zip-file with workspace logs.", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean isInjectedWorkspace(Field field) {
|
||||
return field.isAnnotationPresent(com.google.inject.Inject.class)
|
||||
|| field.isAnnotationPresent(javax.inject.Inject.class)
|
||||
|| field.isAnnotationPresent(InjectTestWorkspace.class);
|
||||
}
|
||||
|
||||
/** Releases resources by invoking methods annotated with {@link PreDestroy} */
|
||||
private void preDestroy(Object testInstance) {
|
||||
LOG.info("Processing @PreDestroy annotation in {}", testInstance.getClass().getName());
|
||||
|
||||
traverseClassHierarchy(
|
||||
testInstance.getClass(),
|
||||
(clazz) -> {
|
||||
for (Field field : clazz.getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
|
||||
Object obj;
|
||||
try {
|
||||
obj = field.get(testInstance);
|
||||
} catch (IllegalAccessException e) {
|
||||
LOG.error(
|
||||
"Field {} is inaccessible in {}.",
|
||||
field.getName(),
|
||||
testInstance.getClass().getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (obj == null || !hasInjectAnnotation(field)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (Method m : obj.getClass().getMethods()) {
|
||||
if (m.isAnnotationPresent(PreDestroy.class)) {
|
||||
try {
|
||||
m.invoke(obj);
|
||||
} catch (Exception e) {
|
||||
LOG.error(
|
||||
format(
|
||||
"Failed to invoke method %s annotated with @PreDestroy in %s. Test instance: %s",
|
||||
m.getName(), obj.getClass().getName(), testInstance.getClass().getName()),
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean hasInjectAnnotation(AccessibleObject f) {
|
||||
return f.isAnnotationPresent(com.google.inject.Inject.class)
|
||||
|| f.isAnnotationPresent(javax.inject.Inject.class)
|
||||
|| f.isAnnotationPresent(InjectTestWorkspace.class)
|
||||
|| f.isAnnotationPresent(InjectTestOrganization.class)
|
||||
|| f.isAnnotationPresent(InjectPageObject.class);
|
||||
}
|
||||
|
||||
private void captureWebDriver(ITestResult result) {
|
||||
Set<SeleniumWebDriver> webDrivers = new HashSet<>();
|
||||
Object testInstance = result.getInstance();
|
||||
|
||||
collectInjectedWebDrivers(testInstance, webDrivers);
|
||||
webDrivers.forEach(webDriver -> captureWebDriver(result, webDriver));
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates recursively throw all fields and collects instances of {@link SeleniumWebDriver}.
|
||||
*
|
||||
* @param testInstance the based object to examine
|
||||
* @param webDrivers as the result of the method will contain all {@link WebDriver}
|
||||
*/
|
||||
private void collectInjectedWebDrivers(Object testInstance, Set<SeleniumWebDriver> webDrivers) {
|
||||
traverseClassHierarchy(
|
||||
testInstance.getClass(),
|
||||
(clazz) -> {
|
||||
for (Field field : clazz.getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
|
||||
Object obj;
|
||||
try {
|
||||
obj = field.get(testInstance);
|
||||
} catch (IllegalAccessException e) {
|
||||
LOG.error(
|
||||
"Field {} is inaccessible in {}.",
|
||||
field.getName(),
|
||||
testInstance.getClass().getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (obj == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Optional<Constructor<?>> injectedConstructor =
|
||||
Stream.of(obj.getClass().getConstructors())
|
||||
.filter(this::hasInjectAnnotation)
|
||||
.findAny();
|
||||
|
||||
if (!hasInjectAnnotation(field) && !injectedConstructor.isPresent()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (obj instanceof com.google.inject.Provider || obj instanceof javax.inject.Provider) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (obj instanceof SeleniumWebDriver) {
|
||||
webDrivers.add((SeleniumWebDriver) obj);
|
||||
} else {
|
||||
collectInjectedWebDrivers(obj, webDrivers);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void traverseClassHierarchy(Class clazz, Consumer<Class> handler) {
|
||||
if (clazz == null || clazz.equals(Object.class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
traverseClassHierarchy(clazz.getSuperclass(), handler);
|
||||
handler.accept(clazz);
|
||||
}
|
||||
|
||||
private void captureScreenshotFromCurrentWindow(ITestResult result, SeleniumWebDriver webDriver) {
|
||||
String testReference = getTestReference(result);
|
||||
String filename = getTestResultFilename(testReference, "png");
|
||||
try {
|
||||
byte[] data = webDriver.getScreenshotAs(OutputType.BYTES);
|
||||
Path screenshot = Paths.get(screenshotsDir, filename);
|
||||
Files.createDirectories(screenshot.getParent());
|
||||
Files.copy(new ByteArrayInputStream(data), screenshot);
|
||||
} catch (WebDriverException | IOException e) {
|
||||
LOG.error(format("Can't capture screenshot for test %s", testReference), e);
|
||||
}
|
||||
}
|
||||
|
||||
private String getTestResultFilename(String testReference, String fileExtension) {
|
||||
return format("%s_time-%s-millis.%s", testReference, System.currentTimeMillis(), fileExtension);
|
||||
}
|
||||
|
||||
private String getTestReference(ITestResult result) {
|
||||
return format("%s.%s", result.getTestClass().getName(), result.getMethod().getMethodName());
|
||||
}
|
||||
|
||||
private void captureWebDriver(ITestResult result, SeleniumWebDriver webDriver) {
|
||||
webDriver
|
||||
.getWindowHandles()
|
||||
.forEach(
|
||||
currentWin -> {
|
||||
webDriver.switchTo().window(currentWin);
|
||||
captureScreenshotFromCurrentWindow(result, webDriver);
|
||||
captureHtmlDumpFromCurrentWindow(result, webDriver);
|
||||
storeLogsFromCurrentWindow(result, webDriver);
|
||||
});
|
||||
}
|
||||
|
||||
private void storeLogsFromCurrentWindow(ITestResult result, SeleniumWebDriver webDriver) {
|
||||
String testReference = getTestReference(result);
|
||||
|
||||
try {
|
||||
String filename = getTestResultFilename(testReference, "log");
|
||||
Path webDriverLogsDirectory = Paths.get(webDriverLogsDir, filename);
|
||||
Files.createDirectories(webDriverLogsDirectory.getParent());
|
||||
Files.write(
|
||||
webDriverLogsDirectory,
|
||||
webDriverLogsReaderFactory
|
||||
.create(webDriver)
|
||||
.getAllLogs()
|
||||
.getBytes(Charset.forName("UTF-8")),
|
||||
StandardOpenOption.CREATE);
|
||||
} catch (WebDriverException | IOException | JsonParseException e) {
|
||||
LOG.error(format("Can't store web driver logs related to test %s.", testReference), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void captureHtmlDumpFromCurrentWindow(ITestResult result, SeleniumWebDriver webDriver) {
|
||||
String testReference = getTestReference(result);
|
||||
String filename = getTestResultFilename(testReference, "html");
|
||||
try {
|
||||
String pageSource = webDriver.getPageSource();
|
||||
Path dumpDirectory = Paths.get(htmldumpsDir, filename);
|
||||
Files.createDirectories(dumpDirectory.getParent());
|
||||
Files.write(
|
||||
dumpDirectory, pageSource.getBytes(Charset.forName("UTF-8")), StandardOpenOption.CREATE);
|
||||
} catch (WebDriverException | IOException e) {
|
||||
LOG.error(format("Can't dump of html source for test %s", testReference), e);
|
||||
}
|
||||
}
|
||||
|
||||
/** Cleans up test environment. */
|
||||
private void shutdown() {
|
||||
if (isCleanUpCompleted.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG.info("Cleaning up test environment...");
|
||||
|
||||
for (Object testInstance : runningTests.values()) {
|
||||
preDestroy(testInstance);
|
||||
testsWithFailure.remove(testInstance.getClass().getName());
|
||||
}
|
||||
|
||||
if (testWorkspaceProvider != null) {
|
||||
testWorkspaceProvider.shutdown();
|
||||
}
|
||||
|
||||
if (defaultTestUser != null) {
|
||||
try {
|
||||
defaultTestUser.delete();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
isCleanUpCompleted.set(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip test if preceding test with higher priority from the same test class has failed.
|
||||
*
|
||||
* @param result holds result of test execution
|
||||
* @throws SkipException if test should be skipped
|
||||
*/
|
||||
private void skipTestIfNeeded(ITestResult result) {
|
||||
ITestNGMethod testMethodToSkip = result.getMethod();
|
||||
|
||||
ITestResult failedTestResult =
|
||||
testsWithFailure.get(testMethodToSkip.getInstance().getClass().getName());
|
||||
|
||||
// skip test with lower priority value and if it shouldn't always run
|
||||
if (failedTestResult != null
|
||||
&& testMethodToSkip.getPriority() > failedTestResult.getMethod().getPriority()
|
||||
&& !testMethodToSkip.isAlwaysRun()) {
|
||||
throw new SkipException(
|
||||
format(
|
||||
"Skipping test %s because it depends on test %s which has failed earlier.",
|
||||
getStartingTestLabel(testMethodToSkip),
|
||||
getCompletedTestLabel(failedTestResult.getMethod())));
|
||||
}
|
||||
}
|
||||
|
||||
private String getStartingTestLabel(ITestNGMethod test) {
|
||||
String invocationLabel = "";
|
||||
if (test.getCurrentInvocationCount() > 0) {
|
||||
invocationLabel = format(" (run %d)", test.getCurrentInvocationCount() + 1);
|
||||
}
|
||||
|
||||
return getTestLabel(test, invocationLabel);
|
||||
}
|
||||
|
||||
private String getCompletedTestLabel(ITestNGMethod test) {
|
||||
String invocationLabel = "";
|
||||
if (test.getCurrentInvocationCount() > 1) {
|
||||
invocationLabel = format(" (run %d)", test.getCurrentInvocationCount());
|
||||
}
|
||||
|
||||
return getTestLabel(test, invocationLabel);
|
||||
}
|
||||
|
||||
private String getTestLabel(ITestNGMethod test, String invocationLabel) {
|
||||
return format(
|
||||
"%s.%s%s",
|
||||
test.getInstance().getClass().getSimpleName(), test.getMethodName(), invocationLabel);
|
||||
}
|
||||
|
||||
/** Returns list of parent modules */
|
||||
@NotNull
|
||||
public abstract List<Module> getParentModules();
|
||||
|
||||
/** Returns list of child modules */
|
||||
@NotNull
|
||||
public abstract List<Module> getChildModules();
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.inject;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/** @author Dmytro Nochevnov */
|
||||
public class SeleniumTestStatistics {
|
||||
private static final String statisticsTemplate = "Passed: %d, failed: %d, skipped: %d.";
|
||||
|
||||
private final AtomicInteger runTests = new AtomicInteger();
|
||||
private final AtomicInteger failedTests = new AtomicInteger();
|
||||
private final AtomicInteger passedTests = new AtomicInteger();
|
||||
private final AtomicInteger skippedTests = new AtomicInteger();
|
||||
|
||||
public int hitStart() {
|
||||
return runTests.incrementAndGet();
|
||||
}
|
||||
|
||||
public int hitPass() {
|
||||
return passedTests.incrementAndGet();
|
||||
}
|
||||
|
||||
public int hitFail() {
|
||||
return failedTests.incrementAndGet();
|
||||
}
|
||||
|
||||
public int hitSkip() {
|
||||
return skippedTests.incrementAndGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
synchronized (this) {
|
||||
return format(statisticsTemplate, passedTests.get(), failedTests.get(), skippedTests.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.inject;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.name.Named;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.eclipse.che.selenium.core.TestGroup;
|
||||
import org.eclipse.che.selenium.core.constant.Infrastructure;
|
||||
import org.testng.annotations.ITestOrConfiguration;
|
||||
|
||||
/**
|
||||
* This class is aimed to filter TestNG tests.
|
||||
*
|
||||
* @author Dmytro Nochevnov
|
||||
*/
|
||||
@Singleton
|
||||
public class TestFilter {
|
||||
|
||||
private final boolean isMultiuser;
|
||||
private final Infrastructure infrastructure;
|
||||
private final String excludedGroups;
|
||||
|
||||
@Inject
|
||||
public TestFilter(
|
||||
@Named("sys.excludedGroups") String excludedGroups,
|
||||
@Named("che.multiuser") boolean isMultiuser,
|
||||
@Named("che.infrastructure") Infrastructure infrastructure) {
|
||||
this.isMultiuser = isMultiuser;
|
||||
this.infrastructure = infrastructure;
|
||||
this.excludedGroups = excludedGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method disable the test which belongs to test group which is being excluded or doesn't
|
||||
* comply current infrastructure, or doesn't support Singleuser/Multiuser type of Eclipse Che.
|
||||
*
|
||||
* @param annotation annotation of test method which reflects {@link org.testng.annotations.Test}
|
||||
* annotation attributes.
|
||||
*/
|
||||
public void excludeTestOfImproperGroup(ITestOrConfiguration annotation) {
|
||||
if (annotation.getGroups().length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> groups = new ArrayList<>(Arrays.asList(annotation.getGroups()));
|
||||
|
||||
// exclude test with group from excludedGroups
|
||||
if (excludedGroups != null
|
||||
&& Arrays.stream(excludedGroups.split(",")).anyMatch(groups::contains)) {
|
||||
annotation.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// exclude test which doesn't comply multiuser flag
|
||||
if (isMultiuser
|
||||
&& groups.contains(TestGroup.SINGLEUSER)
|
||||
&& !groups.contains(TestGroup.MULTIUSER)) {
|
||||
annotation.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// exclude test which doesn't comply singleuser flag
|
||||
if (!isMultiuser
|
||||
&& groups.contains(TestGroup.MULTIUSER)
|
||||
&& !groups.contains(TestGroup.SINGLEUSER)) {
|
||||
annotation.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// exclude test which doesn't support current infrastructure
|
||||
groups.remove(TestGroup.SINGLEUSER);
|
||||
groups.remove(TestGroup.MULTIUSER);
|
||||
groups.remove(TestGroup.GITHUB);
|
||||
groups.remove(TestGroup.UNDER_REPAIR);
|
||||
groups.remove(TestGroup.FLAKY);
|
||||
if (!groups.isEmpty() && !groups.contains(infrastructure.toString().toLowerCase())) {
|
||||
annotation.setEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.organization;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* To instantiate {@link TestOrganization} in test classes.
|
||||
*
|
||||
* @author Dmytro Nochevnov
|
||||
*/
|
||||
@Target({FIELD})
|
||||
@Retention(RUNTIME)
|
||||
@Documented
|
||||
public @interface InjectTestOrganization {
|
||||
/** Organization name prefix. */
|
||||
String prefix() default "";
|
||||
|
||||
/** Parent organization name prefix. */
|
||||
String parentPrefix() default "";
|
||||
}
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.organization;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
import org.eclipse.che.multiuser.organization.shared.dto.OrganizationDto;
|
||||
import org.eclipse.che.selenium.core.client.TestOrganizationServiceClient;
|
||||
|
||||
/**
|
||||
* Represents organization in a test environment.
|
||||
*
|
||||
* @author Dmytro Nochevnov
|
||||
*/
|
||||
public class TestOrganization {
|
||||
private final OrganizationDto organization;
|
||||
private final TestOrganizationServiceClient testOrganizationServiceClient;
|
||||
|
||||
public TestOrganization(String name, TestOrganizationServiceClient testOrganizationServiceClient)
|
||||
throws Exception {
|
||||
this.testOrganizationServiceClient = testOrganizationServiceClient;
|
||||
organization = testOrganizationServiceClient.create(name);
|
||||
}
|
||||
|
||||
public TestOrganization(
|
||||
String name, String parentId, TestOrganizationServiceClient testOrganizationServiceClient)
|
||||
throws Exception {
|
||||
this.testOrganizationServiceClient = testOrganizationServiceClient;
|
||||
organization = testOrganizationServiceClient.create(name, parentId);
|
||||
}
|
||||
|
||||
/** Returns the name of the organization. */
|
||||
public String getName() {
|
||||
return organization.getName();
|
||||
}
|
||||
|
||||
/** Returns the id of the organization. */
|
||||
public String getId() {
|
||||
return organization.getId();
|
||||
}
|
||||
|
||||
public void addAdmin(String userId) throws Exception {
|
||||
testOrganizationServiceClient.addAdmin(getId(), userId);
|
||||
}
|
||||
|
||||
public void addMember(String userId) throws Exception {
|
||||
testOrganizationServiceClient.addMember(getId(), userId);
|
||||
}
|
||||
|
||||
/** Deletes organization. */
|
||||
@PreDestroy
|
||||
public void delete() throws Exception {
|
||||
testOrganizationServiceClient.deleteById(getId());
|
||||
}
|
||||
|
||||
public String getQualifiedName() {
|
||||
return organization.getQualifiedName();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.organization;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.eclipse.che.commons.lang.NameGenerator.generate;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.MembersInjector;
|
||||
import com.google.inject.Provider;
|
||||
import java.lang.reflect.Field;
|
||||
import org.eclipse.che.selenium.core.client.TestOrganizationServiceClient;
|
||||
import org.eclipse.che.selenium.core.client.TestOrganizationServiceClientFactory;
|
||||
import org.eclipse.che.selenium.core.user.AdminTestUser;
|
||||
|
||||
/**
|
||||
* Injector for custom annotation {@link InjectTestOrganization}.
|
||||
*
|
||||
* @author Dmytro Nochevnov
|
||||
*/
|
||||
public class TestOrganizationInjector<T> implements MembersInjector<T> {
|
||||
|
||||
private final Field field;
|
||||
private final InjectTestOrganization injectTestOrganization;
|
||||
private final Provider<Injector> injectorProvider;
|
||||
|
||||
public TestOrganizationInjector(
|
||||
Field field,
|
||||
InjectTestOrganization injectTestOrganization,
|
||||
Provider<Injector> injectorProvider) {
|
||||
this.field = field;
|
||||
this.injectTestOrganization = injectTestOrganization;
|
||||
this.injectorProvider = injectorProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectMembers(T instance) {
|
||||
Injector injector = injectorProvider.get();
|
||||
|
||||
String name = generateName();
|
||||
String parentPrefix = injectTestOrganization.parentPrefix();
|
||||
|
||||
AdminTestUser adminTestUser = injector.getInstance(Key.get(AdminTestUser.class));
|
||||
|
||||
TestOrganizationServiceClientFactory testOrganizationServiceClient =
|
||||
injector.getInstance(Key.get(TestOrganizationServiceClientFactory.class));
|
||||
|
||||
TestOrganizationServiceClient adminOrganizationServiceClient =
|
||||
testOrganizationServiceClient.create(adminTestUser);
|
||||
|
||||
TestOrganization testOrganization;
|
||||
try {
|
||||
if (parentPrefix.isEmpty()) {
|
||||
testOrganization = new TestOrganization(name, adminOrganizationServiceClient);
|
||||
} else {
|
||||
String parentId = findInjectedOrganization(instance, parentPrefix);
|
||||
testOrganization = new TestOrganization(name, parentId, adminOrganizationServiceClient);
|
||||
}
|
||||
|
||||
field.setAccessible(true);
|
||||
field.set(instance, testOrganization);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(
|
||||
format(
|
||||
"Failed to instantiate organization with name '%s' in class '%s'",
|
||||
injectTestOrganization.prefix(), instance.getClass().getName()),
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
private String generateName() {
|
||||
String fieldNamePrefix = field.getName().substring(0, Math.min(field.getName().length(), 12));
|
||||
String annotationPrefix = injectTestOrganization.prefix();
|
||||
|
||||
String prefix = annotationPrefix.isEmpty() ? fieldNamePrefix : annotationPrefix;
|
||||
|
||||
return generate(prefix + "-", 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return id of organization among the fields of instance with name which starts from
|
||||
* orgNamePrefix
|
||||
*/
|
||||
private String findInjectedOrganization(T instance, String orgNamePrefix) {
|
||||
for (Field field : instance.getClass().getDeclaredFields()) {
|
||||
if (field.getType() == TestOrganization.class) {
|
||||
field.setAccessible(true);
|
||||
|
||||
TestOrganization org;
|
||||
try {
|
||||
org = (TestOrganization) field.get(instance);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
|
||||
if (org != null && org.getName().startsWith(orgNamePrefix)) {
|
||||
return org.getId();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(
|
||||
format(
|
||||
"Organization with name which starts from '%s' not found or isn't instantiated in class '%s'",
|
||||
orgNamePrefix, instance.getClass().getName()));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.pageobject;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* To instantiate different instances of the same page object.
|
||||
*
|
||||
* @author Anatolii Bazko
|
||||
*/
|
||||
@Target({FIELD})
|
||||
@Retention(RUNTIME)
|
||||
@Documented
|
||||
public @interface InjectPageObject {
|
||||
int driverId();
|
||||
}
|
||||
|
|
@ -1,130 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.pageobject;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
import org.eclipse.che.selenium.core.SeleniumWebDriver;
|
||||
import org.eclipse.che.selenium.core.webdriver.SeleniumWebDriverFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Injects fields annotated with {@link InjectPageObject}. All page objects with the same {@link
|
||||
* InjectPageObject#driverId()} must share a common {@link SeleniumWebDriver} instance.
|
||||
*
|
||||
* @author Anatolii Bazko
|
||||
*/
|
||||
public abstract class PageObjectsInjector {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(PageObjectsInjector.class);
|
||||
|
||||
@Inject private SeleniumWebDriverFactory seleniumWebDriverFactory;
|
||||
|
||||
public void injectMembers(Object testInstance, Injector injector) throws Exception {
|
||||
Map<Integer, Set<Field>> toInject = collectFieldsToInject(testInstance);
|
||||
|
||||
for (Integer poIndex : toInject.keySet()) {
|
||||
Map<Class<?>, Object> container = new HashMap<>();
|
||||
SeleniumWebDriver seleniumWebDriver = seleniumWebDriverFactory.create();
|
||||
|
||||
container.put(SeleniumWebDriver.class, seleniumWebDriver);
|
||||
container.putAll(getDependenciesWithWebdriver(seleniumWebDriver));
|
||||
|
||||
for (Field f : toInject.get(poIndex)) {
|
||||
try {
|
||||
injectField(f, testInstance, container, injector);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(
|
||||
format("Error of injection member '%s' into test '%s'.", f, testInstance), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract Map<Class<?>, Object> getDependenciesWithWebdriver(
|
||||
SeleniumWebDriver seleniumWebDriver);
|
||||
|
||||
private void injectField(
|
||||
Field field, Object instance, Map<Class<?>, Object> container, Injector injector)
|
||||
throws Exception {
|
||||
Object object = instantiate(field.getType(), container, injector);
|
||||
field.setAccessible(true);
|
||||
field.set(instance, object);
|
||||
}
|
||||
|
||||
private Object instantiate(Class<?> type, Map<Class<?>, Object> container, Injector injector)
|
||||
throws Exception {
|
||||
Object obj;
|
||||
|
||||
Optional<Constructor<?>> constructor = findConstructor(type);
|
||||
if (!constructor.isPresent()) {
|
||||
// interface? get instance from a guice container
|
||||
obj = injector.getInstance(type);
|
||||
|
||||
} else {
|
||||
Class<?>[] parameterTypes = constructor.get().getParameterTypes();
|
||||
Object[] params = new Object[parameterTypes.length];
|
||||
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
Object pt = container.get(parameterTypes[i]);
|
||||
if (pt == null) {
|
||||
pt = instantiate(parameterTypes[i], container, injector);
|
||||
}
|
||||
params[i] = pt;
|
||||
}
|
||||
|
||||
obj = constructor.get().newInstance(params);
|
||||
}
|
||||
|
||||
container.put(obj.getClass(), obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Optional<Constructor<?>> findConstructor(Class<?> type) {
|
||||
return Stream.of(type.getConstructors())
|
||||
.filter(
|
||||
c ->
|
||||
c.isAnnotationPresent(com.google.inject.Inject.class)
|
||||
|| c.isAnnotationPresent(javax.inject.Inject.class))
|
||||
.findAny();
|
||||
}
|
||||
|
||||
/** Find class fields annotated with {@link InjectPageObject}. */
|
||||
private Map<Integer, Set<Field>> collectFieldsToInject(Object testInstance) {
|
||||
Map<Integer, Set<Field>> toInject = new HashMap<>();
|
||||
|
||||
for (Field f : testInstance.getClass().getDeclaredFields()) {
|
||||
if (f.isAnnotationPresent(InjectPageObject.class)) {
|
||||
InjectPageObject pageObject = f.getAnnotation(InjectPageObject.class);
|
||||
int poIndex = pageObject.driverId();
|
||||
|
||||
Set<Field> fields = toInject.computeIfAbsent(poIndex, k -> new HashSet<>());
|
||||
fields.add(f);
|
||||
}
|
||||
}
|
||||
|
||||
return toInject;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.project;
|
||||
|
||||
/** @author Musienko Maxim */
|
||||
public class ProjectTemplates {
|
||||
public static final String C = "c.json";
|
||||
public static final String CPP = "cpp.json";
|
||||
public static final String PHP = "php.json";
|
||||
public static final String PYTHON = "python.json";
|
||||
public static final String NODE_JS = "node_js.json";
|
||||
public static final String MAVEN_SPRING = "maven_spring.json";
|
||||
public static final String MAVEN_SIMPLE = "maven_simple.json";
|
||||
public static final String MAVEN_JAVA_MULTIMODULE = "maven_java_multimodule.json";
|
||||
public static final String PLAIN_JAVA = "plain_java.json";
|
||||
public static final String CONSOLE_JAVA_SIMPLE = "console_java_simple.json";
|
||||
public static final String GO = "go.json";
|
||||
public static final String DOT_NET = "dotNet.json";
|
||||
public static final String PROJECT_OF_UNDEFINED_TYPE = "undefined.json";
|
||||
|
||||
private ProjectTemplates() {}
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.provider;
|
||||
|
||||
import org.eclipse.che.selenium.core.user.AdminTestUser;
|
||||
|
||||
/**
|
||||
* Admin test user provider.
|
||||
*
|
||||
* @author Dmytro Nochevnov
|
||||
*/
|
||||
public interface AdminTestUserProvider extends RemovableUserProvider<AdminTestUser> {}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.provider;
|
||||
|
||||
import org.eclipse.che.selenium.core.user.DefaultTestUser;
|
||||
|
||||
/**
|
||||
* Default test user provider.
|
||||
*
|
||||
* @author Dmytro Nochevnov
|
||||
*/
|
||||
public interface DefaultTestUserProvider extends RemovableUserProvider<DefaultTestUser> {}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.provider;
|
||||
|
||||
import com.google.inject.Provider;
|
||||
import java.io.IOException;
|
||||
import org.eclipse.che.selenium.core.user.TestUser;
|
||||
|
||||
/**
|
||||
* Removable user provider.
|
||||
*
|
||||
* @author Dmytro Nochevnov
|
||||
*/
|
||||
public interface RemovableUserProvider<T extends TestUser> extends Provider<T> {
|
||||
|
||||
/** Deletes user. */
|
||||
void delete() throws IOException;
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.provider;
|
||||
|
||||
import com.google.inject.Provider;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Api endpoint.
|
||||
*
|
||||
* @author Anatolii Bazko
|
||||
*/
|
||||
public interface TestApiEndpointUrlProvider extends Provider<URL> {}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.provider;
|
||||
|
||||
import com.google.inject.Provider;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Url to Dashboard.
|
||||
*
|
||||
* @author Anatolii Bazko
|
||||
*/
|
||||
public interface TestDashboardUrlProvider extends Provider<URL> {}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.provider;
|
||||
|
||||
import com.google.inject.Provider;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Url to IDE.
|
||||
*
|
||||
* @author Anatolii Bazko
|
||||
*/
|
||||
public interface TestIdeUrlProvider extends Provider<URL> {}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.selenium.core.provider;
|
||||
|
||||
import org.eclipse.che.selenium.core.user.TestUser;
|
||||
|
||||
/**
|
||||
* New test user provider.
|
||||
*
|
||||
* @author Dmytro Nochevnov
|
||||
*/
|
||||
public interface TestUserProvider extends RemovableUserProvider<TestUser> {}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue