diff --git a/.gitignore b/.gitignore index c9165c9820..654e5bb9ac 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ bin .classpath /test-output /.settings -*/.settings +**/.settings /com /application.log /sql.log diff --git a/archetype/pom.xml b/archetype/pom.xml new file mode 100644 index 0000000000..401179b782 --- /dev/null +++ b/archetype/pom.xml @@ -0,0 +1,43 @@ + + + 4.0.0 + + com.qaprosoft + carina-archetype + 1.0 + maven-archetype + http://www.qaprosoft.com/ + carina-archetype + + + + + org.apache.maven.archetype + archetype-packaging + 2.4 + + + + + + + maven-archetype-plugin + 2.4 + + + + + + + + QPS_Nexus + Qaprosoft Releases + https://oss.sonatype.org/service/local/staging/deploy/maven2 + + + QPS_Nexus + Qaprosoft Snapshots + https://oss.sonatype.org/content/repositories/snapshots/ + + + diff --git a/archetype/src/main/resources/META-INF/maven/archetype-metadata.xml b/archetype/src/main/resources/META-INF/maven/archetype-metadata.xml new file mode 100644 index 0000000000..42dafcb922 --- /dev/null +++ b/archetype/src/main/resources/META-INF/maven/archetype-metadata.xml @@ -0,0 +1,79 @@ + + + + + src/main/java + + **/*.java + + + + src/main/groovy + + **/*.groovy + + + + src/main/groovy + + **/*. + + + + src/main/resources + + **/*.properties + + + + src/main/resources + + **/*.key + + + + src/test/java + + **/*.java + + + + src/test/resources + + **/*.xml + **/*.properties + + + + src/test/resources + + **/*.schema + **/*.xlsx + **/*.json + + + + .settings + + **/*.prefs + + + + + + .classpath + .project + + + + + + .gitignore + LICENSE + README.md + + + + diff --git a/archetype/src/main/resources/archetype-resources/LICENSE b/archetype/src/main/resources/archetype-resources/LICENSE new file mode 100644 index 0000000000..ff2171168a --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2013-2017 QAPROSOFT + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/archetype/src/main/resources/archetype-resources/README.md b/archetype/src/main/resources/archetype-resources/README.md new file mode 100644 index 0000000000..98919d6683 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/README.md @@ -0,0 +1,17 @@ +### Carina +Carina is a Java-based framework developed to simplify test automation process. Frameworks combines functionality for **Web**, **Mobile**, **WebService** and **DB** testing. Carina allows to implement robust integrational test scenarios that covers all aspects of application, for example you may prepare some test data in DB then go and interact with Web UI, after that make some WebService API calls and finally verify Mobile app changes. All that possible using Carina framework! It uses multiple open source frameworks under the hood: +* [Selenium](https://github.com/SeleniumHQ/selenium) - portable software testing framework for web applications that supports most of the browsers +* [Appium](https://github.com/appium/appium) - test automation framework for native and hybrid mobile apps both for iOS and Android +* [MyBatis](https://github.com/mybatis/) - persistence framework that couples objects with stored procedures or SQL statements using an XML descriptor or annotations +* [Freemarker](https://github.com/freemarker/) - template engine that allows to dynamicly generate WebService requests and repornces +* [TestNG](https://github.com/cbeust/testng) - testing framwork that helps to organize test cases and test suites +* [Apache Maven](https://github.com/apache/maven) - project build tool + +### Environment requirements +* Install and configure JDK 1.7 +* Install and configure [Apache Maven 3.3.1+](http://maven.apache.org/) +* Download and start latest [Selenium standalone server](http://www.seleniumhq.org/download/) +* Download the latest version of [Eclipse](http://www.eclipse.org/downloads/) and install [TestNG plugin](http://testng.org/doc/download.html) + +### Wiki +Read all information on [Carina Wiki page](https://github.com/qaprosoft/carina-demo/wiki). diff --git a/archetype/src/main/resources/archetype-resources/pom.xml b/archetype/src/main/resources/archetype-resources/pom.xml new file mode 100644 index 0000000000..e707d4a448 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/pom.xml @@ -0,0 +1,85 @@ + + + + 4.0.0 + ${groupId} + ${artifactId} + ${version} + jar + Carina Demo + http://www.qaprosoft.com/ + + + UTF-8 + LATEST + 4.5.3 + 1.8 + api + + + + + qaprosoft_releases + Qaprosoft Releases + http://ci.qaprosoft.com:8081/nexus/content/repositories/releases/ + + + + false + + + + qaprosoft_snapshots + Qaprosoft Snapshots + http://ci.qaprosoft.com:8081/nexus/content/repositories/snapshots/ + + false + + + + + + + + + com.qaprosoft + carina-core + ${carina-core.version} + + + org.apache.httpcomponents + httpclient + ${httpclient.version} + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.18.1 + + + ${project.build.directory}/test-classes/testng_suites/${suite}.xml + + + + listener + com.qaprosoft.carina.core.foundation.listeners.HealthCheckListener,com.qaprosoft.zafira.listener.ZafiraListener + + + + + + + diff --git a/archetype/src/main/resources/archetype-resources/src/main/groovy/jobs/Creator.groovy b/archetype/src/main/resources/archetype-resources/src/main/groovy/jobs/Creator.groovy new file mode 100644 index 0000000000..ea225ddc30 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/groovy/jobs/Creator.groovy @@ -0,0 +1,88 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +package ${package}.jobs + + +@Grab('org.testng:testng:6.3.1') + +import groovy.io.FileType; +import org.testng.xml.Parser; +import org.testng.xml.XmlSuite; +import ${package}.jobs.Job; + +createJobs() + +void createJobs() { + def list = [] + + def currentBuild = Thread.currentThread().executable + def workspace = currentBuild.getEnvVars()["WORKSPACE"] + println "JENKINS_HOME: ${symbol_dollar}{JENKINS_HOME}" + println "WORKSPACE: ${symbol_dollar}{WORKSPACE}" + + def dir = new File(workspace, "src/test/resources/testng_suites") + dir.eachFileRecurse (FileType.FILES) { file -> + list << file + } + + list.each { + def currentSuiteItem = it + if (currentSuiteItem.name.endsWith('.xml')) { + def xmlFile = new Parser(new File(currentSuiteItem.path).absolutePath) + xmlFile.setLoadClasses(false) + + List suiteXml = xmlFile.parseToList() + XmlSuite currentSuite = suiteXml.get(0) + + if (currentSuite.toXml().contains("jenkinsJobCreation")) { + + def jobFolder = currentSuite.getParameter("jenkinsJobFolder").toString() + folder(jobFolder) { + displayName(jobFolder) + } + + String suiteName = currentSuiteItem.path + String suiteFrontRemoval = "testng_suites/" + suiteName = suiteName.substring(suiteName.lastIndexOf(suiteFrontRemoval) + suiteFrontRemoval.length(), suiteName.indexOf(".xml")) + + println "${symbol_escape}n" + currentSuiteItem.path + println "${symbol_escape}n" + suiteName + println "${symbol_escape}n" + currentSuite.toXml() + "${symbol_escape}n" + println "jenkinsJobCreation: " + currentSuite.getParameter("jenkinsJobCreation").toString() + if (currentSuite.getParameter("jenkinsJobCreation").contains("true")) { + def jobName = currentSuite.getParameter("jenkinsJobName").toString() + createViews(suiteName, jobFolder) + Job.createPipeline(pipelineJob(jobFolder + "/" + jobName), currentSuite, suiteName) + } + } + } + } +} + +void createViews(suiteName, jobFolder) { + String[] viewCreationList = suiteName.tokenize("${symbol_escape}${symbol_escape}") + println "${symbol_escape}n Checking View List: ${symbol_dollar}{viewCreationList}" + + if (viewCreationList.size() >= 2) { + for (int i = 0; i < 2; i++) { + println viewCreationList[i].capitalize() + listView(jobFolder + "/" + viewCreationList[i].toUpperCase()) { + columns { + status() + weather() + name() + lastSuccess() + lastFailure() + lastDuration() + buildButton() + } + jobs { + def filterString = String.format("(?i).*%s.*", viewCreationList[i]).capitalize() + regex("${symbol_dollar}{filterString}") + } + } + } + } +} + diff --git a/archetype/src/main/resources/archetype-resources/src/main/groovy/jobs/Job.groovy b/archetype/src/main/resources/archetype-resources/src/main/groovy/jobs/Job.groovy new file mode 100644 index 0000000000..be0a5bc28e --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/groovy/jobs/Job.groovy @@ -0,0 +1,255 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +package ${package}.jobs + +class Job { + + static void createPipeline(pipelineJob, org.testng.xml.XmlSuite currentSuite, String suiteName) { + pipelineJob.with { + description(currentSuite.name) + logRotator { + numToKeep 100 + } + + /** Properties & Parameters Area **/ + parameters { + choiceParam('env', getEnvironments(currentSuite), 'Environment to test against.') + + switch(suiteName) { + case ~/^(?!.*web).*api.*${symbol_dollar}/: + configure addHiddenParameter('platform', '', 'API') + configure addHiddenParameter('browser', '', 'NULL') + break; + case ~/^.*web.*${symbol_dollar}/: + configure addExtensibleChoice('browser', 'gc_BROWSER', 'Select a browser to run tests against.', 'chrome') + booleanParam('auto_screenshot', true, 'Generate screenshots automatically during the test') + booleanParam('keep_all_screenshots', true, 'Keep screenshots even if the tests pass') + break; + case ~/^.*android.*${symbol_dollar}/: + choiceParam('device', getDeviceList(suiteName), "Select the Device a Test will run against. ALL - Any available device, PHONE - Any available phone, TABLET - Any tablet") + stringParam('build', '.*', "latest - use fresh build artifact from S3 or local storage;") + booleanParam('recoveryMode', true, 'Restart application between retries') + booleanParam('auto_screenshot', true, 'Generate screenshots automatically during the test') + booleanParam('keep_all_screenshots', true, 'Keep screenshots even if the tests pass') + configure addHiddenParameter('browser', '', 'NULL') + break; + default: + throw new RuntimeException("Undefined suite test type: " + suiteName); + break; + } + + configure addExtensibleChoice('repository', "gc_GIT_REPOSITORY", "Select a GitHub Testing Repository to run against", "git@github.com:qaprosoft/${artifactId}.git") + configure addExtensibleChoice('branch', "gc_GIT_BRANCH", "Select a GitHub Testing Repository Branch to run against", "master") + configure addHiddenParameter('suite', '', suiteName) + configure addHiddenParameter('ci_parent_url', '', '') + configure addHiddenParameter('ci_parent_build', '', '') + + stringParam('email_list', currentSuite.getParameter("jenkinsEmail").toString(), 'List of Users to be emailed after the test') + choiceParam('retry_count', [0, 1, 2, 3], 'Number of Times to Retry a Failed Test') + booleanParam('develop', false, 'Check to execute test without registration to Zafira and TestRail') + booleanParam('rerun_failures', false, 'During ${symbol_escape}"Rebuild${symbol_escape}" pick it to execute only failed cases') + configure addHiddenParameter('project', '', "unknown") + configure addHiddenParameter('overrideFields', '' , getCustomFields(currentSuite)) + + configure addExtensibleGroovyScript('ci_run_id', "", "import static java.util.UUID.randomUUID${symbol_escape}nreturn [randomUUID()]", true) + } + + /** Git Stuff **/ + definition { + cpsScm { + scm { + git { + remote { + url('${symbol_dollar}{repository}') + } + branch('${symbol_dollar}{branch}') + } + } + scriptPath('src/main/groovy/${packageInPathFormat}/pipelines/JenkinsFile') + } + } + } + } + + static Closure addExtensibleChoice(choiceName, globalName, desc, choice) { + //TODO: Need to move the choiceListProvider into a parameterized class as well as that can change. + return { node -> + node / 'properties' / 'hudson.model.ParametersDefinitionProperty' / 'parameterDefinitions' << 'jp.ikedam.jenkins.plugins.extensible__choice__parameter.ExtensibleChoiceParameterDefinition'(plugin: 'extensible-choice-parameter@1.4.1') { + name choiceName + description desc + editable false + choiceListProvider(class: 'jp.ikedam.jenkins.plugins.extensible_choice_parameter.GlobalTextareaChoiceListProvider') { + whenToAdd 'Triggered' + name globalName + defaultChoice choice + } + } + } + } + + static Closure addExtensibleGroovyScript(choiceName, desc, scriptValue, editableValue) { + return { node -> + node / 'properties' / 'hudson.model.ParametersDefinitionProperty' / 'parameterDefinitions' << 'jp.ikedam.jenkins.plugins.extensible__choice__parameter.ExtensibleChoiceParameterDefinition'(plugin: 'extensible-choice-parameter@1.4.1') { + name choiceName + description desc + editable editableValue + choiceListProvider(class: 'jp.ikedam.jenkins.plugins.extensible_choice_parameter.SystemGroovyChoiceListProvider') { + groovyScript { + script scriptValue + sandbox true + } + usePredefinedVariables false + } + } + } + } + + + static Closure addHiddenParameter(paramName, paramDesc, paramValue) { + return { node -> + node / 'properties' / 'hudson.model.ParametersDefinitionProperty' / 'parameterDefinitions' << 'com.wangyin.parameter.WHideParameterDefinition'(plugin: 'hidden-parameter@0.0.4') { + name paramName + description paramDesc + defaultValue paramValue + } + } + } + + static void createRegressionPipeline(pipelineJob, suiteName, List customFields) { + pipelineJob.with { + description(suiteName) + logRotator { + numToKeep 100 + } + configure addExtensibleChoice('repository', "repositories", "Select a GitHub Testing Repository to run against", "git@github.com:qaprosoft/${artifactId}.git") + configure addExtensibleChoice('branch', "gc_GIT_BRANCH", "Select a GitHub Testing Repository Branch to run against", "master") + parameters { + stringParam('email_list_for_pipeline', 'msarychau@qaprosoft.com', 'List of Users to be emailed after the test') + booleanParam('overrideEmail', false, 'Check to override email field on all Pipeline Jobs with above email') + for (String customField : customFields) { + if (!customField.contains("=")) { + stringParam(customField, "", "Custom Field") + } else { + def customFieldList = customField.split("=") + stringParam(customFieldList[0], customFieldList[1].toString(), "Custom Field") + } + } + } + configure addHiddenParameter('overrideFields', 'This allows for mass overriding of any fields in this pipeline.', '') + definition { + cpsScm { + scm { + git { + remote { + url('${symbol_dollar}{repository}') + credentials('qJenkins-Token') + } + branch('${symbol_dollar}{branch}') + } + } + scriptPath('src/main/groovy/${packageInPathFormat}/pipelines/JenkinsFilePipeline') + } + } + } + } + + static List getEnvironments(currentSuite) { + def envList = getGenericSplit(currentSuite, "jenkinsEnvironments") + + if (envList.isEmpty()) { + envList.add("QA") + } + + return envList + } + + static String getCustomFields(currentSuite) { + def overrideFields = getGenericSplit(currentSuite, "overrideFields") + def prepCustomFields = "" + + if (!overrideFields.isEmpty()) { + for (String customField : overrideFields) { + prepCustomFields = prepCustomFields + " -D" + customField + } + } + + return prepCustomFields + } + + static List getGenericSplit(currentSuite, parameterName) { + String genericField = currentSuite.getParameter(parameterName) + def genericFields = [] + + if (genericField != null) { + if (!genericField.contains(", ")) { + genericFields = genericField.split(",") + } else { + genericFields = genericField.split(", ") + } + } + return genericFields + } + + static List getTagList(String tags) { + if (tags.contains(", ")) { + return tags.split(", ") + } else { + return tags.split(",") + } + } + + static List getDeviceList(String suite) { + def currentBuild = Thread.currentThread().executable + def workspace = currentBuild.getEnvVars()["WORKSPACE"] + def deviceList = ["ALL", "Samsung_Galaxy_TAB4_10", "Samsung_Galaxy_Note_4", "Samsung_Grand_Prime", "Samsung_Galaxy_S6", "Samsung_Galaxy_S7", "Motorola_Nexus_6"] + + return deviceList + } + + static checkAndAddDevice(List deviceList, String suite, Map deviceEntry) { + + switch(suite.toLowerCase()) { + case ~/^.*handset.*${symbol_dollar}/: + deviceList.add(deviceEntry.get("device").toString()) + checkAndAddDeviceType(deviceList, deviceEntry) + deviceList.sort { a,b -> a.toLowerCase() <=> b.toLowerCase() } + deviceList.remove("phone") + deviceList.add(0,"phone") + case ~/^.*tablet.*${symbol_dollar}/: + if (deviceEntry.get("deviceType").toString().toLowerCase().contains("tablet") && !deviceList.contains(deviceEntry.get("device"))) { + deviceList.add(deviceEntry.get("device").toString()) + checkAndAddDeviceType(deviceList, deviceEntry) + deviceList.sort { a,b -> a.toLowerCase() <=> b.toLowerCase() } + deviceList.remove("tablet") + deviceList.add(0,"tablet") + } + break; + default: + deviceList.add(deviceEntry.get("device").toString()) + checkAndAddDeviceType(deviceList, deviceEntry) + deviceList.sort { a,b -> a.toLowerCase() <=> b.toLowerCase() } + break; + } + } + + static checkAndAddDeviceType(List deviceList, Map deviceEntry) { + if (!deviceList.contains(deviceEntry.get("deviceType").toString().toLowerCase())) { + deviceList.add(deviceEntry.get("deviceType").toString()) + } + checkAndAddTag(deviceList, deviceEntry) + + return deviceList + } + + static checkAndAddTag(List deviceList, Map deviceEntry) { + if (deviceEntry.get("tags") != null) { + for (String tag : getTagList(deviceEntry.get("tags").toString())) { + if (!deviceList.contains(tag.toLowerCase())) { + deviceList.add(tag) + } + } + } + return deviceList + } +} \ No newline at end of file diff --git a/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/api/DeleteUserMethod.java b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/api/DeleteUserMethod.java new file mode 100644 index 0000000000..c056e5323e --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/api/DeleteUserMethod.java @@ -0,0 +1,32 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +/* + * Copyright 2013-2017 QAPROSOFT (http://qaprosoft.com/). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ${package}.carina.demo.api; + +import com.qaprosoft.carina.core.foundation.api.AbstractApiMethodV2; +import com.qaprosoft.carina.core.foundation.utils.Configuration; + +public class DeleteUserMethod extends AbstractApiMethodV2 +{ + + public DeleteUserMethod() + { + super("api/users/_delete/rq.json", "api/users/_delete/rs.json", "api/users/user.properties"); + replaceUrlPlaceholder("base_url", Configuration.getEnvArg("api_url")); + } +} diff --git a/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/api/GetUserMethods.java b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/api/GetUserMethods.java new file mode 100644 index 0000000000..66953b10b3 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/api/GetUserMethods.java @@ -0,0 +1,33 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +/* + * Copyright 2013-2017 QAPROSOFT (http://qaprosoft.com/). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ${package}.carina.demo.api; + +import com.qaprosoft.carina.core.foundation.api.AbstractApiMethodV2; +import com.qaprosoft.carina.core.foundation.utils.Configuration; + +import java.util.Properties; + +public class GetUserMethods extends AbstractApiMethodV2 +{ + public GetUserMethods() + { + super(null, "api/users/_get/rs.json", new Properties()); + replaceUrlPlaceholder("base_url", Configuration.getEnvArg("api_url")); + } +} diff --git a/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/api/PostUserMethod.java b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/api/PostUserMethod.java new file mode 100644 index 0000000000..7bc4a44954 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/api/PostUserMethod.java @@ -0,0 +1,31 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +/* + * Copyright 2013-2017 QAPROSOFT (http://qaprosoft.com/). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ${package}.carina.demo.api; + +import com.qaprosoft.carina.core.foundation.api.AbstractApiMethodV2; +import com.qaprosoft.carina.core.foundation.utils.Configuration; + +public class PostUserMethod extends AbstractApiMethodV2 +{ + public PostUserMethod() + { + super("api/users/_post/rq.json", "api/users/_post/rs.json", "api/users/user.properties"); + replaceUrlPlaceholder("base_url", Configuration.getEnvArg("api_url")); + } +} diff --git a/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/components/FooterMenu.java b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/components/FooterMenu.java new file mode 100644 index 0000000000..ec3dd04a16 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/components/FooterMenu.java @@ -0,0 +1,54 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +/* + * Copyright 2013-2017 QAPROSOFT (http://qaprosoft.com/). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ${package}.carina.demo.gui.components; + +import org.openqa.selenium.SearchContext; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.FindBy; + +import com.qaprosoft.carina.core.foundation.webdriver.decorator.ExtendedWebElement; +import com.qaprosoft.carina.core.gui.AbstractUIObject; +import ${package}.carina.demo.gui.pages.CompareModelsPage; +import ${package}.carina.demo.gui.pages.HomePage; + +public class FooterMenu extends AbstractUIObject +{ + @FindBy(linkText = "Home") + private ExtendedWebElement homeLink; + + @FindBy(linkText = "Compare") + private ExtendedWebElement compareLink; + + public FooterMenu(WebDriver driver, SearchContext searchContext) + { + super(driver, searchContext); + } + + public HomePage openHomePage() + { + homeLink.click(); + return new HomePage(driver); + } + + public CompareModelsPage openComparePage() + { + compareLink.click(); + return new CompareModelsPage(driver); + } +} diff --git a/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/components/ModelItem.java b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/components/ModelItem.java new file mode 100644 index 0000000000..e8eb132563 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/components/ModelItem.java @@ -0,0 +1,52 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +/* + * Copyright 2013-2017 QAPROSOFT (http://qaprosoft.com/). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ${package}.carina.demo.gui.components; + +import org.openqa.selenium.SearchContext; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.FindBy; + +import com.qaprosoft.carina.core.foundation.webdriver.decorator.ExtendedWebElement; +import com.qaprosoft.carina.core.gui.AbstractUIObject; +import ${package}.carina.demo.gui.pages.ModelInfoPage; + +public class ModelItem extends AbstractUIObject +{ + @FindBy(xpath = ".//strong/span") + private ExtendedWebElement modelLabel; + + @FindBy(xpath = ".//a") + private ExtendedWebElement modelLink; + + public ModelItem(WebDriver driver, SearchContext searchContext) + { + super(driver, searchContext); + } + + public String readModel() + { + return modelLabel.getText(); + } + + public ModelInfoPage openModelPage() + { + modelLink.click(); + return new ModelInfoPage(driver); + } +} diff --git a/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/components/compare/CondidateBlock.java b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/components/compare/CondidateBlock.java new file mode 100644 index 0000000000..6459857f90 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/components/compare/CondidateBlock.java @@ -0,0 +1,52 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +/* + * Copyright 2013-2017 QAPROSOFT (http://qaprosoft.com/). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ${package}.carina.demo.gui.components.compare; + +import com.qaprosoft.carina.core.foundation.webdriver.decorator.ExtendedWebElement; +import com.qaprosoft.carina.core.gui.AbstractUIObject; +import org.openqa.selenium.SearchContext; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.FindBy; + +import java.util.List; + +public class CondidateBlock extends AbstractUIObject +{ + @FindBy(xpath = ".//input[contains(@id, 'sSearch')]") + private ExtendedWebElement inputField; + + @FindBy(xpath = ".//div[contains(@class, 'autocomplete-search')]//a[not(@class)]") + private List autocompleteSearchElements; + + public CondidateBlock(WebDriver driver, SearchContext searchContext) + { + super(driver, searchContext); + } + + public void sendKeysToInputField(String text) + { + click(inputField); + type(inputField, text); + } + + public void getFirstPhone() + { + click(autocompleteSearchElements.get(0)); + } +} diff --git a/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/components/compare/ModelSpecs.java b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/components/compare/ModelSpecs.java new file mode 100644 index 0000000000..44e7a3a840 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/components/compare/ModelSpecs.java @@ -0,0 +1,60 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +/* + * Copyright 2013-2017 QAPROSOFT (http://qaprosoft.com/). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ${package}.carina.demo.gui.components.compare; + +import java.util.HashMap; +import java.util.Map; + +public class ModelSpecs +{ + public enum SpecType + { + TECHNOLOGY("Technology"), + ANNOUNCED("Announced"); + + private String type; + + SpecType(String type) + { + this.type = type; + } + + public String getType() + { + return type; + } + } + + private Map modelSpecsMap; + + public ModelSpecs() + { + this.modelSpecsMap = new HashMap<>(); + } + + public void setToModelSpecsMap(SpecType specType, String spec) + { + this.modelSpecsMap.put(specType, spec); + } + + public String readSpec(SpecType specType) + { + return modelSpecsMap.get(specType); + } +} diff --git a/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/pages/BrandModelsPage.java b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/pages/BrandModelsPage.java new file mode 100644 index 0000000000..f55c446511 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/pages/BrandModelsPage.java @@ -0,0 +1,50 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +/* + * Copyright 2013-2017 QAPROSOFT (http://qaprosoft.com/). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ${package}.carina.demo.gui.pages; + +import java.util.List; + +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.FindBy; + +import com.qaprosoft.carina.core.gui.AbstractPage; +import ${package}.carina.demo.gui.components.ModelItem; + +public class BrandModelsPage extends AbstractPage +{ + @FindBy(xpath = "//div[@id='review-body']//li") + private List models; + + public BrandModelsPage(WebDriver driver) + { + super(driver); + } + + public ModelInfoPage selectModel(String modelName) + { + for (ModelItem model : models) + { + if(model.readModel().equalsIgnoreCase(modelName)) + { + return model.openModelPage(); + } + } + throw new RuntimeException("Unable to open model: " + modelName); + } +} diff --git a/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/pages/CompareModelsPage.java b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/pages/CompareModelsPage.java new file mode 100644 index 0000000000..563f8d7c50 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/pages/CompareModelsPage.java @@ -0,0 +1,64 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +/* + * Copyright 2013-2017 QAPROSOFT (http://qaprosoft.com/). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ${package}.carina.demo.gui.pages; + +import java.util.ArrayList; +import java.util.List; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.FindBy; + +import com.qaprosoft.carina.core.foundation.webdriver.decorator.ExtendedWebElement; +import com.qaprosoft.carina.core.gui.AbstractPage; +import ${package}.carina.demo.gui.components.compare.CondidateBlock; +import ${package}.carina.demo.gui.components.compare.ModelSpecs; + +public class CompareModelsPage extends AbstractPage +{ + @FindBy(xpath = "//div[contains(@class, 'candidate-search')]") + private List condidateBlocks; + + public CompareModelsPage(WebDriver driver) + { + super(driver); + } + + public List compareModels(String... models) + { + CondidateBlock condidateBlock; + List modelSpecs = new ArrayList<>(); + ModelSpecs modelSpec; + for (int index = 0; index < models.length; index++) + { + modelSpec = new ModelSpecs(); + condidateBlock = condidateBlocks.get(index); + condidateBlock.sendKeysToInputField(models[index]); + condidateBlock.getFirstPhone(); + for (ModelSpecs.SpecType type : ModelSpecs.SpecType.values()) + { + ExtendedWebElement spec = findExtendedWebElement(By.xpath( + String.format("//tr[.//a[text()='%s']]//td[@class='nfo'][%d]", type.getType(), index + 1))); + modelSpec.setToModelSpecsMap(type, spec.getText()); + } + modelSpecs.add(modelSpec); + } + return modelSpecs; + } +} diff --git a/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/pages/HomePage.java b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/pages/HomePage.java new file mode 100644 index 0000000000..74a911028d --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/pages/HomePage.java @@ -0,0 +1,60 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +/* + * Copyright 2013-2017 QAPROSOFT (http://qaprosoft.com/). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ${package}.carina.demo.gui.pages; + +import java.util.List; + +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.FindBy; + +import com.qaprosoft.carina.core.foundation.webdriver.decorator.ExtendedWebElement; +import com.qaprosoft.carina.core.gui.AbstractPage; +import ${package}.carina.demo.gui.components.FooterMenu; + +public class HomePage extends AbstractPage +{ + @FindBy(id = "footmenu") + private FooterMenu footerMenu; + + @FindBy(xpath = "//div[contains(@class, 'brandmenu-v2')]//a") + private List brandLinks; + + public HomePage(WebDriver driver) + { + super(driver); + } + + public FooterMenu getFooterMenu() + { + return footerMenu; + } + + public BrandModelsPage selectBrand(String brand) + { + for(ExtendedWebElement brandLink : brandLinks) + { + if(brand.equalsIgnoreCase(brandLink.getText())) + { + brandLink.click(); + return new BrandModelsPage(driver); + } + } + throw new RuntimeException("Unable to open brand: " + brand); + } +} diff --git a/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/pages/LoginPage.java b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/pages/LoginPage.java new file mode 100644 index 0000000000..1c2fd5d95f --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/pages/LoginPage.java @@ -0,0 +1,61 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +/* + * Copyright 2013-2017 QAPROSOFT (http://qaprosoft.com/). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ${package}.carina.demo.gui.pages; + +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.FindBy; + +import com.qaprosoft.carina.core.foundation.webdriver.ai.FindByAI; +import com.qaprosoft.carina.core.foundation.webdriver.ai.Label; +import com.qaprosoft.carina.core.foundation.webdriver.decorator.ExtendedWebElement; +import com.qaprosoft.carina.core.gui.AbstractPage; + +public class LoginPage extends AbstractPage +{ + @FindBy(name = "email") + private ExtendedWebElement emailTextField; + + @FindBy(name = "password") + private ExtendedWebElement passwordTextField; + + @FindBy(xpath = "//input[@value='Log in']") + private ExtendedWebElement signInButton; + + @FindByAI(caption = "Google", label = Label.BUTTON) + private ExtendedWebElement googleButton; + + public LoginPage(WebDriver driver) + { + super(driver); + setPageAbsoluteURL("https://stackoverflow.com/users/login"); + } + + public void signIn(String email, String password) + { + emailTextField.type(email); + passwordTextField.type(password); + signInButton.click(); + } + + // AI usage + public void signInViaGoogle() + { + googleButton.click(); + } +} \ No newline at end of file diff --git a/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/pages/ModelInfoPage.java b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/pages/ModelInfoPage.java new file mode 100644 index 0000000000..200c1b270f --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/java/carina/demo/gui/pages/ModelInfoPage.java @@ -0,0 +1,69 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +/* + * Copyright 2013-2017 QAPROSOFT (http://qaprosoft.com/). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ${package}.carina.demo.gui.pages; + +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.FindBy; + +import com.qaprosoft.carina.core.foundation.webdriver.decorator.ExtendedWebElement; +import com.qaprosoft.carina.core.gui.AbstractPage; + +public class ModelInfoPage extends AbstractPage +{ + @FindBy(css = ".help-display strong") + private ExtendedWebElement displayInfoLabel; + + @FindBy(css = ".help-camera strong") + private ExtendedWebElement cameraInfoLabel; + + @FindBy(css = ".help-expansion strong") + private ExtendedWebElement displayRamLabel; + + @FindBy(css = ".help-battery strong") + private ExtendedWebElement batteryInfoLabel; + + public ModelInfoPage(WebDriver driver) + { + super(driver); + } + + public String readDisplay() + { + assertElementPresent(displayInfoLabel); + return displayInfoLabel.getText(); + } + + public String readCamera() + { + assertElementPresent(cameraInfoLabel); + return cameraInfoLabel.getText(); + } + + public String readRam() + { + assertElementPresent(displayRamLabel); + return displayRamLabel.getText(); + } + + public String readBattery() + { + assertElementPresent(displayInfoLabel); + return batteryInfoLabel.getText(); + } +} diff --git a/archetype/src/main/resources/archetype-resources/src/main/resources/_api.properties b/archetype/src/main/resources/archetype-resources/src/main/resources/_api.properties new file mode 100644 index 0000000000..35abcd60e6 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/resources/_api.properties @@ -0,0 +1,11 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +${symbol_pound}=====================================================${symbol_pound} +${symbol_pound}=================== API methods ====================${symbol_pound} +${symbol_pound}=====================================================${symbol_pound} +GetUserMethods=GET:${symbol_dollar}{base_url}/users +PostUserMethod=POST:${symbol_dollar}{base_url}/users +DeleteUserMethod=DELETE:${symbol_dollar}{base_url}/users/1 +PutPostsMethod=PUT:${symbol_dollar}{base_url}/posts/1 +PatchPostsMethod=PATCH:${symbol_dollar}{base_url}/posts/1 \ No newline at end of file diff --git a/archetype/src/main/resources/archetype-resources/src/main/resources/_config.properties b/archetype/src/main/resources/archetype-resources/src/main/resources/_config.properties new file mode 100644 index 0000000000..17fd1e99a4 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/resources/_config.properties @@ -0,0 +1,103 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +${symbol_pound}=====================================================${symbol_pound} +${symbol_pound}================= Configuration v2 ==================${symbol_pound} +${symbol_pound}=====================================================${symbol_pound} + +${symbol_pound}=================== Global configuration ============${symbol_pound} +url=http://www.gsmarena.com +platform=* +browser=chrome +browser_version=* +selenium_host=http://localhost:4444/wd/hub +driver_mode=method_mode +custom_capabilities=NULL +extra_capabilities=NULL +app_version= +${symbol_pound}=====================================================${symbol_pound} + +${symbol_pound}=============== Environment configuration ===========${symbol_pound} +env=DEMO +DEMO.api_url=https://jsonplaceholder.typicode.com +STAG.api_url= +${symbol_pound}=====================================================${symbol_pound} + +${symbol_pound}============== WebDirver configuration ==============${symbol_pound} +implicit_timeout=10 +explicit_timeout=20 +retry_interval=5 +thread_count=1 +${symbol_pound}=====================================================${symbol_pound} + +${symbol_pound}================ Report configuration ===============${symbol_pound} +core_log_level=INFO +auto_screenshot=true +keep_all_screenshots=true +project_report_directory=./reports/qa +report_url=NULL +max_screen_history=10 +result_sorting=true + +email_list=NULL +failure_email_list=NULL +ignore_known_issues=false +sender_email=NULL +sender_pswd=NULL +suite_name=NULL +${symbol_pound}=====================================================${symbol_pound} + +${symbol_pound}================ Retry configuration ================${symbol_pound} +init_retry_count=0 +init_retry_interval=1 +retry_count=0 +${symbol_pound}=====================================================${symbol_pound} + +${symbol_pound}=============== MyBatis configuration ===============${symbol_pound} +mybatis_cnfg=mybatis.config.xml +mybatis_env=testing +${symbol_pound}=====================================================${symbol_pound} + +${symbol_pound}================ JIRA integration ===================${symbol_pound} +jira_updater=com.qaprosoft.carina.core.foundation.jira.DefaultJiraUpdater +jira_url=NULL +jira_user=NULL +jira_password=NULL +jira_suite_id=NULL +jira_create_new_ticket=false +jira_project=NULL +jira_project_short=NULL +${symbol_pound}=====================================================${symbol_pound} + +${symbol_pound}====================== TestRail =====================${symbol_pound} +testrail_url=NULL +testrail_user=NULL +testrail_password=NULL +testrail_milestone=NULL +testrail_assignee=NULL +${symbol_pound}=====================================================${symbol_pound} + +${symbol_pound}======== Localization parser properties =============${symbol_pound} +add_new_localization=false +add_new_localization_path=NULL +add_new_localization_property_name=new_custom_messages_ +${symbol_pound}=====================================================${symbol_pound} + +${symbol_pound}===================== Amazon ========================${symbol_pound} +s3_bucket_name=NULL +access_key_id=NULL +secret_key=NULL + +${symbol_pound}================ Amazon-Screenshots =================${symbol_pound} +s3_screenshot_bucket_name=NULL +s3_save_screenshots=FALSE +${symbol_pound}=====================================================${symbol_pound} + +${symbol_pound}=========== Cucumber related properties =============${symbol_pound} +cucumber_tests= +cucumber_tests_app_version= +cucumber_tests_name= +cucumber_tests_results_image_resize=30 +cucumber_user_js_in_report= +cucumber_report_subfolder=cucumber-html-reports +${symbol_pound}=====================================================${symbol_pound} diff --git a/archetype/src/main/resources/archetype-resources/src/main/resources/_database.properties b/archetype/src/main/resources/archetype-resources/src/main/resources/_database.properties new file mode 100644 index 0000000000..5232563eb9 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/resources/_database.properties @@ -0,0 +1,12 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +${symbol_pound}===============================================================${symbol_pound} +${symbol_pound}================== Database configuration ====================${symbol_pound} +${symbol_pound}===============================================================${symbol_pound} +db.url={must_override} +${symbol_pound}db.driver=net.sourceforge.jtds.jdbc.Driver +${symbol_pound}db.driver=com.mysql.jdbc.Driver +db.driver={must_override} +db.user={must_override} +db.pass={must_override} \ No newline at end of file diff --git a/archetype/src/main/resources/archetype-resources/src/main/resources/_email.properties b/archetype/src/main/resources/archetype-resources/src/main/resources/_email.properties new file mode 100644 index 0000000000..8c3e10c88f --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/resources/_email.properties @@ -0,0 +1,16 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +${symbol_pound}===============================================================${symbol_pound} +${symbol_pound}================== Email base configuration ===================${symbol_pound} +${symbol_pound}===============================================================${symbol_pound} + +title=Carina Demo Tests + +${symbol_pound}================= SMTP server configuration ==================${symbol_pound} +mail.smtp.host=smtp.gmail.com +mail.smtp.socketFactory.port=465 +mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory +mail.smtp.auth=true +mail.smtp.port=465 +${symbol_pound}==============================================================${symbol_pound} \ No newline at end of file diff --git a/archetype/src/main/resources/archetype-resources/src/main/resources/_testdata.properties b/archetype/src/main/resources/archetype-resources/src/main/resources/_testdata.properties new file mode 100644 index 0000000000..75edebbc51 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/resources/_testdata.properties @@ -0,0 +1,6 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +${symbol_pound}===============================================================${symbol_pound} +${symbol_pound}========================== Test data ==========================${symbol_pound} +${symbol_pound}===============================================================${symbol_pound} \ No newline at end of file diff --git a/archetype/src/main/resources/archetype-resources/src/main/resources/alice.properties b/archetype/src/main/resources/archetype-resources/src/main/resources/alice.properties new file mode 100644 index 0000000000..e08394c112 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/resources/alice.properties @@ -0,0 +1,6 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +alice_enabled=false +alice_service_url={must_override} +alice_access_token={must_override} \ No newline at end of file diff --git a/archetype/src/main/resources/archetype-resources/src/main/resources/crypto.key b/archetype/src/main/resources/archetype-resources/src/main/resources/crypto.key new file mode 100644 index 0000000000..75ca17d319 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/resources/crypto.key @@ -0,0 +1 @@ +OIujpEmIVZ0C9kOkXniFRw== \ No newline at end of file diff --git a/archetype/src/main/resources/archetype-resources/src/main/resources/l18n/messages.properties b/archetype/src/main/resources/archetype-resources/src/main/resources/l18n/messages.properties new file mode 100644 index 0000000000..712a6a3ac7 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/resources/l18n/messages.properties @@ -0,0 +1,3 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) diff --git a/archetype/src/main/resources/archetype-resources/src/main/resources/zafira.properties b/archetype/src/main/resources/archetype-resources/src/main/resources/zafira.properties new file mode 100644 index 0000000000..03922846f1 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/main/resources/zafira.properties @@ -0,0 +1,30 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +zafira_enabled=false +zafira_service_url={must_override} +zafira_access_token={must_override} +zafira_project=undefined +zafira_rerun_failures=true +zafira_report_emails= +zafira_configurator=com.qaprosoft.carina.core.foundation.report.ZafiraConfigurator + +${symbol_pound} ------ CI integration ------ +${symbol_pound} ci_url= +${symbol_pound} ci_run_id= +${symbol_pound} ci_build= +${symbol_pound} ci_build_cause= +${symbol_pound} ci_parent_url= +${symbol_pound} ci_parent_build= +${symbol_pound} ci_user_id= +${symbol_pound} ci_user_first_name= +${symbol_pound} ci_user_last_name= +${symbol_pound} ci_user_email= + +${symbol_pound} ------ Git integration ------ +${symbol_pound} git_branch= +${symbol_pound} git_commit= +${symbol_pound} git_url= + +${symbol_pound} ------ JIRA integration ------ +${symbol_pound} jira_suite_id \ No newline at end of file diff --git a/archetype/src/main/resources/archetype-resources/src/test/java/carina/demo/AISampleTest.java b/archetype/src/main/resources/archetype-resources/src/test/java/carina/demo/AISampleTest.java new file mode 100644 index 0000000000..fa0226f830 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/test/java/carina/demo/AISampleTest.java @@ -0,0 +1,44 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +/* + * Copyright 2013-2017 QAPROSOFT (http://qaprosoft.com/). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ${package}.carina.demo; + +import org.testng.Assert; +import org.testng.annotations.Test; + +import com.qaprosoft.carina.core.foundation.AbstractTest; +import com.qaprosoft.carina.core.foundation.utils.ownership.MethodOwner; +import ${package}.carina.demo.gui.pages.LoginPage; + +/** + * This sample shows how to use Alice AI to find UI elements. + * + * @author akhursevich + */ +public class AISampleTest extends AbstractTest +{ + @Test(description = "JIRA${symbol_pound}AUTO-0010") + @MethodOwner(owner = "akhursevich") + public void testGoogleLoginWithAI() + { + LoginPage homePage = new LoginPage(getDriver()); + homePage.open(); + homePage.signInViaGoogle(); + Assert.assertTrue(getDriver().getCurrentUrl().startsWith("https://accounts.google.com/signin"), "Google login not opened"); + } +} diff --git a/archetype/src/main/resources/archetype-resources/src/test/java/carina/demo/APISampleTest.java b/archetype/src/main/resources/archetype-resources/src/test/java/carina/demo/APISampleTest.java new file mode 100644 index 0000000000..029aa504d8 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/test/java/carina/demo/APISampleTest.java @@ -0,0 +1,81 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +/* + * Copyright 2013-2017 QAPROSOFT (http://qaprosoft.com/). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ${package}.carina.demo; + +import org.skyscreamer.jsonassert.JSONCompareMode; +import org.testng.annotations.Test; + +import com.qaprosoft.apitools.validation.JsonCompareKeywords; +import com.qaprosoft.carina.core.foundation.AbstractTest; +import com.qaprosoft.carina.core.foundation.http.HttpResponseStatusType; +import com.qaprosoft.carina.core.foundation.utils.ownership.MethodOwner; +import ${package}.carina.demo.api.DeleteUserMethod; +import ${package}.carina.demo.api.GetUserMethods; +import ${package}.carina.demo.api.PostUserMethod; + +/** + * This sample shows how create REST API tests. + * + * @author akhursevich + */ +public class APISampleTest extends AbstractTest +{ + @Test(description = "JIRA${symbol_pound}DEMO-0001") + @MethodOwner(owner="akhursevich") + public void testCreateUser() throws Exception + { + PostUserMethod api = new PostUserMethod(); + api.expectResponseStatus(HttpResponseStatusType.CREATED_201); + api.callAPI(); + api.validateResponse(); + } + + @Test(description = "JIRA${symbol_pound}DEMO-0002") + @MethodOwner(owner="akhursevich") + public void testCreateUserMissingSomeFields() throws Exception + { + PostUserMethod api = new PostUserMethod(); + api.getProperties().remove("name"); + api.getProperties().remove("username"); + api.expectResponseStatus(HttpResponseStatusType.CREATED_201); + api.callAPI(); + api.validateResponse(); + } + + @Test(description = "JIRA${symbol_pound}DEMO-0003") + @MethodOwner(owner="akhursevich") + public void testGetUsers() + { + GetUserMethods getUsersMethods = new GetUserMethods(); + getUsersMethods.expectResponseStatus(HttpResponseStatusType.OK_200); + getUsersMethods.callAPI(); + getUsersMethods.validateResponse(JSONCompareMode.STRICT, JsonCompareKeywords.ARRAY_CONTAINS.getKey()); + getUsersMethods.validateResponseAgainstJSONSchema("api/users/_get/rs.schema"); + } + + @Test(description = "JIRA${symbol_pound}DEMO-0004") + @MethodOwner(owner="akhursevich") + public void testDeleteUsers() + { + DeleteUserMethod deleteUserMethod = new DeleteUserMethod(); + deleteUserMethod.expectResponseStatus(HttpResponseStatusType.OK_200); + deleteUserMethod.callAPI(); + deleteUserMethod.validateResponse(); + } +} diff --git a/archetype/src/main/resources/archetype-resources/src/test/java/carina/demo/DataprovidersSampleTest.java b/archetype/src/main/resources/archetype-resources/src/test/java/carina/demo/DataprovidersSampleTest.java new file mode 100644 index 0000000000..bb5f1d8958 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/test/java/carina/demo/DataprovidersSampleTest.java @@ -0,0 +1,96 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +/* + * Copyright 2013-2017 QAPROSOFT (http://qaprosoft.com/). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ${package}.carina.demo; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import com.qaprosoft.carina.core.foundation.AbstractTest; +import com.qaprosoft.carina.core.foundation.dataprovider.annotations.XlsDataSourceParameters; +import com.qaprosoft.carina.core.foundation.utils.ownership.MethodOwner; + +/** + * This sample shows how to use data-providers. + * + * @author akhursevich + */ +public class DataprovidersSampleTest extends AbstractTest +{ + /** + * Parametrization using external XLS/XLSX: every row in spreadsheet provides tests arguments set for 1 test. + * + * 1. Specify data-provider type: - @Test(dataProvider = "XLSDataProvider") allows parallel execution + * - @Test(dataProvider = "SingleDataProvider") allows single-thread execution 2. In @XlsDataSourceParameters should + * contain: - path - xls/xlsx file path located in src/test/resources - sheet - xls spreadsheet name - dsUid - + * data-source unique identifier, use TUID or set of parameters - dsArgs - column names from spreadsheet + */ + @Test(dataProvider = "DataProvider", description = "JIRA${symbol_pound}DEMO-0005") + @MethodOwner(owner="akhursevich") + @XlsDataSourceParameters(path = "xls/demo.xlsx", sheet = "Calculator", dsUid = "TUID", dsArgs = "a,b,c") + public void testSumOperation(String a, String b, String c) + { + int actual = Integer.valueOf(a) + Integer.valueOf(b); + int expected = Integer.valueOf(c); + Assert.assertEquals(actual, expected, "Invalid sum result!"); + } + + /** + * Paramatrization using TestNG dataproviders: + * + * 1. Create data-provider method that returns Object[][] and set DataProvider annotation. 2. Specify data-provider + * name in @Test annotation. + */ + @Test(dataProvider = "DP1", description = "JIRA${symbol_pound}DEMO-0006") + @MethodOwner(owner="akhursevich") + public void testMuliplyOperation(int a, int b, int c) + { + int actual = a * b; + int expected = c; + Assert.assertEquals(actual, expected, "Invalid sum result!"); + } + + @DataProvider(parallel = false, name = "DP1") + public static Object[][] dataprovider() + { + return new Object[][] + { + { 2, 3, 6 }, + { 6, 6, 36 }, + { 5, 8, 40 } }; + } + + /** + * Parametrization using TestNG annotation @Parameters: + * + * 1. List all parameter names in appropriate annotation. 2. Pass all parameters from TestNG xml file (check + * test_suites/dataproviders.xml). + */ + @Test(description = "JIRA${symbol_pound}DEMO-0007") + @MethodOwner(owner="akhursevich") + @Parameters( + { "a", "b", "c" }) + public void testSubstractOperation(int a, int b, int c) + { + int actual = Integer.valueOf(a) - Integer.valueOf(b); + int expected = Integer.valueOf(c); + Assert.assertEquals(actual, expected, "Invalid substract result!"); + } +} diff --git a/archetype/src/main/resources/archetype-resources/src/test/java/carina/demo/WebSampleTest.java b/archetype/src/main/resources/archetype-resources/src/test/java/carina/demo/WebSampleTest.java new file mode 100644 index 0000000000..48835ed5c4 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/test/java/carina/demo/WebSampleTest.java @@ -0,0 +1,82 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +/* + * Copyright 2013-2017 QAPROSOFT (http://qaprosoft.com/). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ${package}.carina.demo; + +import java.util.List; + +import org.testng.Assert; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import com.qaprosoft.carina.core.foundation.AbstractTest; +import com.qaprosoft.carina.core.foundation.dataprovider.annotations.XlsDataSourceParameters; +import com.qaprosoft.carina.core.foundation.utils.ownership.MethodOwner; +import ${package}.carina.demo.gui.components.compare.ModelSpecs; +import ${package}.carina.demo.gui.components.compare.ModelSpecs.SpecType; +import ${package}.carina.demo.gui.pages.BrandModelsPage; +import ${package}.carina.demo.gui.pages.CompareModelsPage; +import ${package}.carina.demo.gui.pages.HomePage; +import ${package}.carina.demo.gui.pages.ModelInfoPage; + +/** + * This sample shows how create Web test. + * + * @author akhursevich + */ +public class WebSampleTest extends AbstractTest +{ + @Test(dataProvider = "SingleDataProvider", description = "JIRA${symbol_pound}AUTO-0008") + @MethodOwner(owner = "akhursevich") + @XlsDataSourceParameters(path = "xls/demo.xlsx", sheet = "GSMArena", dsUid = "TUID", dsArgs = "brand, model, display, camera, ram, battery") + public void testModelSpecs(String brand, String model, String display, String camera, String ram, String battery) + { + // Open GSM Arena home page and verify page is opened + HomePage homePage = new HomePage(getDriver()); + homePage.open(); + Assert.assertTrue(homePage.isPageOpened(), "Home page is not opened"); + // Select phone brand + BrandModelsPage productsPage = homePage.selectBrand(brand); + // Select phone model + ModelInfoPage productInfoPage = productsPage.selectModel(model); + // Verify phone specifications + Assert.assertEquals(productInfoPage.readDisplay(), display, "Invalid display info!"); + Assert.assertEquals(productInfoPage.readCamera(), camera, "Invalid camera info!"); + Assert.assertEquals(productInfoPage.readRam(), ram, "Invalid ram info!"); + Assert.assertEquals(productInfoPage.readBattery(), battery, "Invalid battery info!"); + } + + @Test(description = "JIRA${symbol_pound}AUTO-0009") + @MethodOwner(owner = "akhursevich") + @Parameters + public void testCompareModels() + { + // Open GSM Arena home page and verify page is opened + HomePage homePage = new HomePage(getDriver()); + homePage.open(); + Assert.assertTrue(homePage.isPageOpened(), "Home page is not opened"); + // Open model compare page + CompareModelsPage comparePage = homePage.getFooterMenu().openComparePage(); + // Compare 3 models + List specs = comparePage.compareModels("Samsung Galaxy J3", "Samsung Galaxy J5", "Samsung Galaxy J7"); + // Verify model announced dates + Assert.assertEquals(specs.get(0).readSpec(SpecType.ANNOUNCED), "2015, November"); + Assert.assertEquals(specs.get(1).readSpec(SpecType.ANNOUNCED), "2017, June"); + Assert.assertEquals(specs.get(2).readSpec(SpecType.ANNOUNCED), "2017, June"); + } +} diff --git a/archetype/src/main/resources/archetype-resources/src/test/resources/api/users/_delete/rq.json b/archetype/src/main/resources/archetype-resources/src/test/resources/api/users/_delete/rq.json new file mode 100644 index 0000000000..ff8b4962b5 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/test/resources/api/users/_delete/rq.json @@ -0,0 +1,48 @@ +[ + { + "id": 1, + "name": "${name}", + "username": "${username}", + "email": "Sincere@april.biz", + "address": { + "street": "Kulas Light", + "suite": "Apt. 556", + "city": "Gwenborough", + "zipcode": "92998-3874", + "geo": { + "lat": "-37.3159", + "lng": "81.1496" + } + }, + "phone": "1-770-736-8031 x56442", + "website": "hildegard.org", + "company": { + "name": "${company_name}", + "catchPhrase": "Multi-layered client-server neural-net", + "bs": "harness real-time e-markets" + } + }, + { + "id": 2, + "name": "${name}", + "username": "${username}", + "email": "Sincere@april.biz", + "address": { + "street": "Kulas Light", + "suite": "Apt. 556", + "city": "Gwenborough", + "zipcode": "92998-3874", + "geo": { + "lat": "-37.3159", + "lng": "81.1496" + } + }, + "phone": "1-770-736-8031 x56442", + "website": "hildegard.org", + "company": { + "name": "${company_name}", + "catchPhrase": "Multi-layered client-server neural-net", + "bs": "harness real-time e-markets" + } + } +] \ No newline at end of file diff --git a/archetype/src/main/resources/archetype-resources/src/test/resources/api/users/_delete/rs.json b/archetype/src/main/resources/archetype-resources/src/test/resources/api/users/_delete/rs.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/test/resources/api/users/_delete/rs.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/archetype/src/main/resources/archetype-resources/src/test/resources/api/users/_get/rs.json b/archetype/src/main/resources/archetype-resources/src/test/resources/api/users/_get/rs.json new file mode 100644 index 0000000000..476a410725 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/test/resources/api/users/_get/rs.json @@ -0,0 +1,186 @@ +[ + { + "id": "regex:[\\d]", + "name": "type:String", + "username": "regex:[a-zA-Z\\d]+", + "email": "regex:[a-zA-Z\\d\\_\\.]+@[a-z]+\\.[a-z]{2,4}", + "address": { + "street": "regex:[a-zA-Z\\d]+", + "suite": "Apt. 556", + "city": "skip", + "zipcode": "regex:[\\d]{5}-[\\d]{4}", + "geo": { + "lat": "-37.3159", + "lng": "81.1496" + } + }, + "phone": "1-770-736-8031 x56442", + "website": "hildegard.org", + "company": { + "name": "Romaguera-Crona", + "catchPhrase": "Multi-layered client-server neural-net", + "bs": "harness real-time e-markets" + } + }, + { + "id": 2, + "name": "Ervin Howell", + "username": "Antonette", + "email": "Shanna@melissa.tv", + "address": { + "street": "Victor Plains", + "suite": "Suite 879", + "city": "Wisokyburgh", + "zipcode": "90566-7771", + "geo": { + "lat": "-43.9509", + "lng": "-34.4618" + } + }, + "phone": "010-692-6593 x09125", + "website": "anastasia.net", + "company": { + "name": "Deckow-Crist", + "catchPhrase": "Proactive didactic contingency", + "bs": "synergize scalable supply-chains" + } + }, + { + "id": 3, + "name": "Clementine Bauch", + "username": "Samantha", + "email": "Nathan@yesenia.net", + "address": { + "street": "Douglas Extension", + "suite": "Suite 847", + "city": "McKenziehaven", + "zipcode": "59590-4157", + "geo": { + "lat": "-68.6102", + "lng": "-47.0653" + } + }, + "phone": "1-463-123-4447", + "website": "ramiro.info", + "company": { + "name": "Romaguera-Jacobson", + "catchPhrase": "Face to face bifurcated interface", + "bs": "e-enable strategic applications" + } + }, + { + "id": 4, + "name": "Patricia Lebsack", + "username": "Karianne", + "email": "Julianne.OConner@kory.org", + "address": { + "street": "Hoeger Mall", + "suite": "Apt. 692", + "city": "South Elvis", + "zipcode": "53919-4257", + "geo": { + "lat": "29.4572", + "lng": "-164.2990" + } + }, + "phone": "493-170-9623 x156", + "website": "kale.biz", + "company": { + "name": "Robel-Corkery", + "catchPhrase": "Multi-tiered zero tolerance productivity", + "bs": "transition cutting-edge web services" + } + }, + { + "id": 5, + "name": "Chelsey Dietrich", + "username": "Kamren", + "email": "Lucio_Hettinger@annie.ca", + "address": { + "street": "Skiles Walks", + "suite": "Suite 351", + "city": "Roscoeview", + "zipcode": "33263", + "geo": { + "lat": "-31.8129", + "lng": "62.5342" + } + }, + "phone": "(254)954-1289", + "website": "demarco.info", + "company": { + "name": "Keebler LLC", + "catchPhrase": "User-centric fault-tolerant solution", + "bs": "revolutionize end-to-end systems" + } + }, + { + "id": 6, + "name": "Mrs. Dennis Schulist", + "username": "Leopoldo_Corkery", + "email": "Karley_Dach@jasper.info", + "address": { + "street": "Norberto Crossing", + "suite": "Apt. 950", + "city": "South Christy", + "zipcode": "23505-1337", + "geo": { + "lat": "-71.4197", + "lng": "71.7478" + } + }, + "phone": "1-477-935-8478 x6430", + "website": "ola.org", + "company": { + "name": "Considine-Lockman", + "catchPhrase": "Synchronised bottom-line interface", + "bs": "e-enable innovative applications" + } + }, + { + "id": 7, + "name": "Kurtis Weissnat", + "username": "Elwyn.Skiles", + "email": "Telly.Hoeger@billy.biz", + "address": { + "street": "Rex Trail", + "suite": "Suite 280", + "city": "Howemouth", + "zipcode": "58804-1099", + "geo": { + "lat": "24.8918", + "lng": "21.8984" + } + }, + "phone": "210.067.6132", + "website": "elvis.io", + "company": { + "name": "Johns Group", + "catchPhrase": "Configurable multimedia task-force", + "bs": "generate enterprise e-tailers" + } + }, + { + "id": 8, + "name": "Nicholas Runolfsdottir V", + "username": "Maxime_Nienow", + "email": "Sherwood@rosamond.me", + "address": { + "street": "Ellsworth Summit", + "suite": "Suite 729", + "city": "Aliyaview", + "zipcode": "45169", + "geo": { + "lat": "-14.3990", + "lng": "-120.7677" + } + }, + "phone": "586.493.6943 x140", + "website": "jacynthe.com", + "company": { + "name": "Abernathy Group", + "catchPhrase": "Implemented secondary concept", + "bs": "e-enable extensible e-tailers" + } + } +] \ No newline at end of file diff --git a/archetype/src/main/resources/archetype-resources/src/test/resources/api/users/_get/rs.schema b/archetype/src/main/resources/archetype-resources/src/test/resources/api/users/_get/rs.schema new file mode 100644 index 0000000000..63f4206b41 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/test/resources/api/users/_get/rs.schema @@ -0,0 +1,95 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "username": { + "type": "string" + }, + "email": { + "type": "string" + }, + "address": { + "type": "object", + "properties": { + "street": { + "type": "string" + }, + "suite": { + "type": "string" + }, + "city": { + "type": "string" + }, + "zipcode": { + "type": "string" + }, + "geo": { + "type": "object", + "properties": { + "lat": { + "type": "string" + }, + "lng": { + "type": "string" + } + }, + "required": [ + "lat", + "lng" + ] + } + }, + "required": [ + "street", + "suite", + "city", + "zipcode", + "geo" + ] + }, + "phone": { + "type": "string" + }, + "website": { + "type": "string" + }, + "company": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "catchPhrase": { + "type": "string" + }, + "bs": { + "type": "string" + } + }, + "required": [ + "name", + "catchPhrase", + "bs" + ] + } + }, + "required": [ + "id", + "name", + "username", + "email", + "address", + "phone", + "website", + "company" + ] + } +} \ No newline at end of file diff --git a/archetype/src/main/resources/archetype-resources/src/test/resources/api/users/_post/rq.json b/archetype/src/main/resources/archetype-resources/src/test/resources/api/users/_post/rq.json new file mode 100644 index 0000000000..5fd0da2a2a --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/test/resources/api/users/_post/rq.json @@ -0,0 +1,25 @@ +[ + { + "id": 1, + <#if name??>"name": "${name}", + <#if username??>"username": "${username}", + "email": "Sincere@april.biz", + "address": { + "street": "Kulas Light", + "suite": "Apt. 556", + "city": "Gwenborough", + "zipcode": "92998-3874", + "geo": { + "lat": "-37.3159", + "lng": "81.1496" + } + }, + "phone": "1-770-736-8031 x56442", + "website": "hildegard.org", + "company": { + "name": "${company_name}", + "catchPhrase": "Multi-layered client-server neural-net", + "bs": "harness real-time e-markets" + } + } +] \ No newline at end of file diff --git a/archetype/src/main/resources/archetype-resources/src/test/resources/api/users/_post/rs.json b/archetype/src/main/resources/archetype-resources/src/test/resources/api/users/_post/rs.json new file mode 100644 index 0000000000..5fd0da2a2a --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/test/resources/api/users/_post/rs.json @@ -0,0 +1,25 @@ +[ + { + "id": 1, + <#if name??>"name": "${name}", + <#if username??>"username": "${username}", + "email": "Sincere@april.biz", + "address": { + "street": "Kulas Light", + "suite": "Apt. 556", + "city": "Gwenborough", + "zipcode": "92998-3874", + "geo": { + "lat": "-37.3159", + "lng": "81.1496" + } + }, + "phone": "1-770-736-8031 x56442", + "website": "hildegard.org", + "company": { + "name": "${company_name}", + "catchPhrase": "Multi-layered client-server neural-net", + "bs": "harness real-time e-markets" + } + } +] \ No newline at end of file diff --git a/archetype/src/main/resources/archetype-resources/src/test/resources/api/users/user.properties b/archetype/src/main/resources/archetype-resources/src/test/resources/api/users/user.properties new file mode 100644 index 0000000000..d59cd0caa5 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/test/resources/api/users/user.properties @@ -0,0 +1,6 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +name=Leanne Graham +username=generate_word(8) +company_name=generate_word(8) \ No newline at end of file diff --git a/archetype/src/main/resources/archetype-resources/src/test/resources/testng_suites/api.xml b/archetype/src/main/resources/archetype-resources/src/test/resources/testng_suites/api.xml new file mode 100644 index 0000000000..3f99318d82 --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/test/resources/testng_suites/api.xml @@ -0,0 +1,60 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/archetype/src/main/resources/archetype-resources/src/test/resources/testng_suites/web.xml b/archetype/src/main/resources/archetype-resources/src/test/resources/testng_suites/web.xml new file mode 100644 index 0000000000..a7901e18fc --- /dev/null +++ b/archetype/src/main/resources/archetype-resources/src/test/resources/testng_suites/web.xml @@ -0,0 +1,33 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/archetype/src/main/resources/archetype-resources/src/test/resources/xls/demo.xlsx b/archetype/src/main/resources/archetype-resources/src/test/resources/xls/demo.xlsx new file mode 100644 index 0000000000..e42bc96c2f Binary files /dev/null and b/archetype/src/main/resources/archetype-resources/src/test/resources/xls/demo.xlsx differ diff --git a/archetype/src/test/resources/projects/basic/archetype.properties b/archetype/src/test/resources/projects/basic/archetype.properties new file mode 100644 index 0000000000..331d24380e --- /dev/null +++ b/archetype/src/test/resources/projects/basic/archetype.properties @@ -0,0 +1,5 @@ +#Tue Nov 14 16:32:23 MSK 2017 +package=it.pkg +version=0.1-SNAPSHOT +groupId=archetype.it +artifactId=basic diff --git a/archetype/src/test/resources/projects/basic/goal.txt b/archetype/src/test/resources/projects/basic/goal.txt new file mode 100644 index 0000000000..e69de29bb2