init repo
This commit is contained in:
commit
6f1478bb59
23 changed files with 2035 additions and 0 deletions
39
.gitignore
vendored
Normal file
39
.gitignore
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
target/
|
||||||
|
test-output/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea/modules.xml
|
||||||
|
.idea/jarRepositories.xml
|
||||||
|
.idea/compiler.xml
|
||||||
|
.idea/libraries/
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
13
LICENSE
Normal file
13
LICENSE
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||||
|
Version 2, December 2004
|
||||||
|
|
||||||
|
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim or modified
|
||||||
|
copies of this license document, and changing it is allowed as long
|
||||||
|
as the name is changed.
|
||||||
|
|
||||||
|
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. You just DO WHAT THE FUCK YOU WANT TO.
|
5
README.MD
Normal file
5
README.MD
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
### Marinesco tests
|
||||||
|
|
||||||
|
https://git.redrise.ru/desu/marinesco/
|
||||||
|
|
||||||
|
Execute tests: `mvn -P RunSuites test`
|
16
api.xml
Normal file
16
api.xml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
|
||||||
|
<suite name="ru.redrise.api">
|
||||||
|
<test verbose="2" preserve-order="true" name="API tests">
|
||||||
|
|
||||||
|
<classes>
|
||||||
|
<class name="ru.redrise.api.AuthorsApiTest" />
|
||||||
|
<class name="ru.redrise.api.BooksApiTest" />
|
||||||
|
<class name="ru.redrise.api.GenresApiTest" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<class name="ru.redrise.api.ExampleOnly" />
|
||||||
|
-->
|
||||||
|
</classes>
|
||||||
|
</test>
|
||||||
|
</suite>
|
BIN
error_messages.xlsx
Normal file
BIN
error_messages.xlsx
Normal file
Binary file not shown.
112
pom.xml
Normal file
112
pom.xml
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>ru.redrise</groupId>
|
||||||
|
<artifactId>marinesco-tests</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>19</maven.compiler.source>
|
||||||
|
<maven.compiler.target>19</maven.compiler.target>
|
||||||
|
<apache-poi.version>5.2.5</apache-poi.version>
|
||||||
|
<rest-assured.version>5.4.0</rest-assured.version>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.testng</groupId>
|
||||||
|
<artifactId>testng</artifactId>
|
||||||
|
<version>7.9.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.seleniumhq.selenium</groupId>
|
||||||
|
<artifactId>selenium-java</artifactId>
|
||||||
|
<version>4.17.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
<version>2.0.12</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-simple</artifactId>
|
||||||
|
<version>2.0.12</version>
|
||||||
|
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Apache POI -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.poi</groupId>
|
||||||
|
<artifactId>poi</artifactId>
|
||||||
|
<version>${apache-poi.version}</version>
|
||||||
|
|
||||||
|
</dependency>
|
||||||
|
<!-- For xlsx format -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.poi</groupId>
|
||||||
|
<artifactId>poi-ooxml</artifactId>
|
||||||
|
<version>${apache-poi.version}</version>
|
||||||
|
|
||||||
|
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.rest-assured</groupId>
|
||||||
|
<artifactId>rest-assured</artifactId>
|
||||||
|
<version>${rest-assured.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.rest-assured</groupId>
|
||||||
|
<artifactId>json-schema-validator</artifactId>
|
||||||
|
<version>${rest-assured.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>RunSuites</id>
|
||||||
|
<activation>
|
||||||
|
<activeByDefault>true</activeByDefault>
|
||||||
|
</activation>
|
||||||
|
<build>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<skipTests>false</skipTests>
|
||||||
|
<suiteXmlFiles>
|
||||||
|
<suiteXmlFile>testng.xml</suiteXmlFile>
|
||||||
|
</suiteXmlFiles>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<suiteXmlFiles>
|
||||||
|
<suiteXmlFile>testng.xml</suiteXmlFile>
|
||||||
|
</suiteXmlFiles>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
</project>
|
BIN
server configuration files/test.inpx
Executable file
BIN
server configuration files/test.inpx
Executable file
Binary file not shown.
21
src/main/resources/author.json
Normal file
21
src/main/resources/author.json
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||||
|
"type": "array",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"authorName": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"authorName"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
119
src/main/resources/book.json
Normal file
119
src/main/resources/book.json
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||||
|
"type": "array",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"libraryId": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"libraryVersion": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"authors": {
|
||||||
|
"type": "array",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"authorName": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"authorName"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"genres": {
|
||||||
|
"type": "array",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"genreId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"humanReadableDescription": {
|
||||||
|
"type": ["string", "null"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"genreId",
|
||||||
|
"humanReadableDescription"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"series": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"serNo": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"fsFileName": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"fileSize": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"fileSizeForHumans": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"libId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"deleted": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"fileExtension": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"addedDate": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"container": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"line": {
|
||||||
|
"type": ["string", "null"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"libraryId",
|
||||||
|
"libraryVersion",
|
||||||
|
"authors",
|
||||||
|
"genres",
|
||||||
|
"title",
|
||||||
|
"series",
|
||||||
|
"serNo",
|
||||||
|
"fsFileName",
|
||||||
|
"fileSize",
|
||||||
|
"fileSizeForHumans",
|
||||||
|
"libId",
|
||||||
|
"deleted",
|
||||||
|
"fileExtension",
|
||||||
|
"addedDate",
|
||||||
|
"container",
|
||||||
|
"position",
|
||||||
|
"line"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
8
src/main/resources/simplelogger.properties
Normal file
8
src/main/resources/simplelogger.properties
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
org.slf4j.simpleLogger.defaultLogLevel=info
|
||||||
|
org.slf4j.simpleLogger.log.org.testng=warn
|
||||||
|
|
||||||
|
#org.slf4j.simpleLogger.showDateTime=false
|
||||||
|
org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z
|
||||||
|
#org.slf4j.simpleLogger.showThreadName=true
|
||||||
|
#org.slf4j.simpleLogger.showLogName=true
|
||||||
|
#org.slf4j.simpleLogger.showShortLogName=false
|
27
src/test/java/ru/redrise/ReportListener.java
Normal file
27
src/test/java/ru/redrise/ReportListener.java
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package ru.redrise;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.testng.ITestContext;
|
||||||
|
import org.testng.ITestListener;
|
||||||
|
|
||||||
|
public class ReportListener implements ITestListener {
|
||||||
|
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish(ITestContext testContext) {
|
||||||
|
log.info("PASSED TEST CASES");
|
||||||
|
testContext.getPassedTests().getAllResults()
|
||||||
|
.forEach(result ->
|
||||||
|
log.info(result.getName()));
|
||||||
|
|
||||||
|
log.info("FAILED TEST CASES");
|
||||||
|
testContext.getFailedTests().getAllResults()
|
||||||
|
.forEach(result ->
|
||||||
|
log.info(result.getName()));
|
||||||
|
|
||||||
|
log.info(
|
||||||
|
"Test completed on: " + testContext.getEndDate().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
110
src/test/java/ru/redrise/api/AuthorsApiTest.java
Normal file
110
src/test/java/ru/redrise/api/AuthorsApiTest.java
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
package ru.redrise.api;
|
||||||
|
|
||||||
|
import io.restassured.module.jsv.JsonSchemaValidator;
|
||||||
|
import io.restassured.path.json.JsonPath;
|
||||||
|
import io.restassured.specification.RequestSpecification;
|
||||||
|
import org.testng.Assert;
|
||||||
|
import org.testng.annotations.BeforeClass;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static io.restassured.RestAssured.given;
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
|
public class AuthorsApiTest {
|
||||||
|
|
||||||
|
//private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
private static final int RECENT_RECORDS_LIST_SIZE = 10;
|
||||||
|
private static final String TEST_AUTHOR_NAME = "파르나르";
|
||||||
|
private static final long TEST_AUTHOR_ID = 1656621508;
|
||||||
|
|
||||||
|
private static final String HOST_URI = "http://localhost";
|
||||||
|
private static final int HOST_PORT = 8080; // default 8080
|
||||||
|
|
||||||
|
private RequestSpecification specification;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public void beforeClass() {
|
||||||
|
this.specification = given()
|
||||||
|
.baseUri(HOST_URI)
|
||||||
|
.port(HOST_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// note: remember '.log().all()'
|
||||||
|
@Test(testName = "Check recent authors")
|
||||||
|
public void checkAuthors() {
|
||||||
|
JsonPath recent = specification
|
||||||
|
.when()
|
||||||
|
.get("/api/author")
|
||||||
|
.then()
|
||||||
|
.assertThat()
|
||||||
|
.statusCode(200)
|
||||||
|
.log().body()
|
||||||
|
.extract()
|
||||||
|
.jsonPath();
|
||||||
|
|
||||||
|
List<Map<String, Object>> list = recent.getList("$");
|
||||||
|
|
||||||
|
Assert.assertEquals(RECENT_RECORDS_LIST_SIZE, list.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(testName = "Check authors schema")
|
||||||
|
public void checkSchema() {
|
||||||
|
specification
|
||||||
|
.when()
|
||||||
|
.get("/api/author?recent")
|
||||||
|
.then()
|
||||||
|
.assertThat()
|
||||||
|
.statusCode(200)
|
||||||
|
.body(
|
||||||
|
JsonSchemaValidator.matchesJsonSchemaInClasspath("author.json")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//curl 'localhost:8080/api/author/by/name/Kern'
|
||||||
|
@Test(testName = "Check by name")
|
||||||
|
public void checkAuthors1() {
|
||||||
|
String requestedPath = "/api/author/by/name/" + TEST_AUTHOR_NAME;
|
||||||
|
|
||||||
|
JsonPath namesMatched = specification
|
||||||
|
.when()
|
||||||
|
.get(requestedPath)
|
||||||
|
.then()
|
||||||
|
.assertThat()
|
||||||
|
.statusCode(200)
|
||||||
|
.log().body()
|
||||||
|
.extract()
|
||||||
|
.jsonPath();
|
||||||
|
|
||||||
|
List<Map<String, Object>> list = namesMatched.getList("");
|
||||||
|
|
||||||
|
Assert.assertFalse(list.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
// curl 'localhost:8080/api/author/by/id/-605622692'
|
||||||
|
/* Expected:
|
||||||
|
{
|
||||||
|
"id": 1656621508,
|
||||||
|
"authorName": "파르나르"
|
||||||
|
}
|
||||||
|
* */
|
||||||
|
@Test(testName = "Check by id")
|
||||||
|
public void checkAuthors2() {
|
||||||
|
String requestedPath = "/api/author/by/id/" + TEST_AUTHOR_ID;
|
||||||
|
|
||||||
|
specification
|
||||||
|
.when()
|
||||||
|
.get(requestedPath)
|
||||||
|
.then()
|
||||||
|
.assertThat()
|
||||||
|
.statusCode(200)
|
||||||
|
.body("$", hasEntry("id", 1656621508))
|
||||||
|
.body("authorName", equalTo("파르나르"))
|
||||||
|
.log().body()
|
||||||
|
.extract()
|
||||||
|
.jsonPath();
|
||||||
|
}
|
||||||
|
}
|
189
src/test/java/ru/redrise/api/BooksApiTest.java
Normal file
189
src/test/java/ru/redrise/api/BooksApiTest.java
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
package ru.redrise.api;
|
||||||
|
|
||||||
|
import io.restassured.module.jsv.JsonSchemaValidator;
|
||||||
|
import io.restassured.path.json.JsonPath;
|
||||||
|
import io.restassured.specification.RequestSpecification;
|
||||||
|
import org.testng.Assert;
|
||||||
|
import org.testng.annotations.BeforeClass;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static io.restassured.RestAssured.given;
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
|
public class BooksApiTest {
|
||||||
|
|
||||||
|
//private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
private static final String TEST_TITLE = "Евгений Онегин";
|
||||||
|
private static final String TEST_SERIES = "Сборник «У солдата есть невеста»";
|
||||||
|
private static final Integer TEST_BOOK_ID = -2092944816;
|
||||||
|
|
||||||
|
private static final String HOST_URI = "http://localhost";
|
||||||
|
private static final int HOST_PORT = 8080; // default 8080
|
||||||
|
|
||||||
|
private RequestSpecification specification;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public void beforeClass() {
|
||||||
|
this.specification = given()
|
||||||
|
.baseUri(HOST_URI)
|
||||||
|
.port(HOST_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(testName = "Check recent books")
|
||||||
|
public void checkRecent() {
|
||||||
|
JsonPath recent = specification
|
||||||
|
.when()
|
||||||
|
.get("/api/book?recent")
|
||||||
|
.then()
|
||||||
|
.assertThat()
|
||||||
|
.statusCode(200)
|
||||||
|
.log().body()
|
||||||
|
.extract()
|
||||||
|
.jsonPath();
|
||||||
|
|
||||||
|
List<Map<String, Object>> list = recent.getList("");
|
||||||
|
|
||||||
|
Assert.assertFalse(list.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(testName = "Check JSON Schema")
|
||||||
|
public void checkSchema() {
|
||||||
|
specification
|
||||||
|
.when()
|
||||||
|
.get("/api/book?recent")
|
||||||
|
.then()
|
||||||
|
.assertThat()
|
||||||
|
.statusCode(200)
|
||||||
|
.body(
|
||||||
|
JsonSchemaValidator.matchesJsonSchemaInClasspath("book.json")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(testName = "Search books by title")
|
||||||
|
public void checkByTitle() {
|
||||||
|
final String[] authorsExpected = {
|
||||||
|
"Комментарий к роману А. С. Пушкина «Евгений Онегин»",
|
||||||
|
"Евгений Онегин",
|
||||||
|
"Евгений Онегин (Роман в стихове)",
|
||||||
|
"Евгений Онегин"
|
||||||
|
};
|
||||||
|
|
||||||
|
JsonPath book = specification
|
||||||
|
.when()
|
||||||
|
.get("/api/book/by/title/" + TEST_TITLE)
|
||||||
|
.then()
|
||||||
|
.assertThat()
|
||||||
|
.statusCode(200)
|
||||||
|
.log().body()
|
||||||
|
.extract()
|
||||||
|
.jsonPath();
|
||||||
|
|
||||||
|
String[] authors = book
|
||||||
|
.getList("flatten().findAll{it.authors.authorName.contains('Пушкин Александр Сергеевич')}.collect().title")
|
||||||
|
.toArray(String[]::new);
|
||||||
|
|
||||||
|
Arrays.sort(authorsExpected);
|
||||||
|
Arrays.sort(authors);
|
||||||
|
|
||||||
|
Assert.assertEquals(authorsExpected, authors);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(testName = "Search books by series")
|
||||||
|
public void checkBySeries() {
|
||||||
|
JsonPath recent = specification
|
||||||
|
.when()
|
||||||
|
.get("/api/book/by/series/" + TEST_SERIES)
|
||||||
|
.then()
|
||||||
|
.assertThat()
|
||||||
|
.statusCode(200)
|
||||||
|
.log().body()
|
||||||
|
.extract()
|
||||||
|
.jsonPath();
|
||||||
|
|
||||||
|
List<Map<String, Object>> list = recent.getList("");
|
||||||
|
|
||||||
|
Assert.assertTrue(list.size() > 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Example:
|
||||||
|
{
|
||||||
|
"id": -2092944816,
|
||||||
|
"libraryId": 1,
|
||||||
|
"libraryVersion": "20240101",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"id": -220073406,
|
||||||
|
"authorName": "Щеглов Михаил"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"genres": [
|
||||||
|
{
|
||||||
|
"genreId": "love_history",
|
||||||
|
"humanReadableDescription": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"genreId": "love_detective",
|
||||||
|
"humanReadableDescription": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"genreId": "love_short",
|
||||||
|
"humanReadableDescription": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Евгений Онегин, Александр Пушкин. Вся мораль книги с объяснением простыми словами, которую хотел донести автор",
|
||||||
|
"series": "",
|
||||||
|
"serNo": "",
|
||||||
|
"fsFileName": "765420",
|
||||||
|
"fileSize": 363564,
|
||||||
|
"fileSizeForHumans": "355,04 KB",
|
||||||
|
"libId": "765420",
|
||||||
|
"deleted": "0",
|
||||||
|
"fileExtension": "fb2",
|
||||||
|
"addedDate": "2023-12-31",
|
||||||
|
"container": "f.fb2-759836-765669",
|
||||||
|
"position": 0,
|
||||||
|
"line": null
|
||||||
|
}
|
||||||
|
* */
|
||||||
|
@Test(testName = "Search books by id",
|
||||||
|
enabled = true)
|
||||||
|
public void checkById() {
|
||||||
|
JsonPath book = specification
|
||||||
|
.when()
|
||||||
|
.get("/api/book/by/id/" + TEST_BOOK_ID)
|
||||||
|
.then()
|
||||||
|
.assertThat()
|
||||||
|
.statusCode(200)
|
||||||
|
.body("",
|
||||||
|
allOf(
|
||||||
|
hasKey("title"),
|
||||||
|
hasKey("series"),
|
||||||
|
hasKey("serNo"),
|
||||||
|
hasEntry("fsFileName", "765420"),
|
||||||
|
hasKey("fileSizeForHumans"),
|
||||||
|
hasEntry("libId", "765420"),
|
||||||
|
hasEntry("deleted", "0"),
|
||||||
|
hasEntry("fileExtension", "fb2"),
|
||||||
|
hasEntry("addedDate", "2023-12-31"),
|
||||||
|
hasEntry("container", "f.fb2-759836-765669"),
|
||||||
|
hasEntry("line", null)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.body("fileSize", equalTo(363564))
|
||||||
|
.body("position", equalTo(0))
|
||||||
|
.log().body()
|
||||||
|
.extract()
|
||||||
|
.jsonPath();
|
||||||
|
|
||||||
|
Assert.assertEquals(book.getInt("id"), -2092944816);
|
||||||
|
Assert.assertEquals(book.getInt("libraryId"), 1);
|
||||||
|
Assert.assertEquals(book.getString("libraryVersion"), "20240101");
|
||||||
|
Assert.assertEquals(book.getInt("authors[0].id"), -220073406);
|
||||||
|
Assert.assertEquals(book.get("authors[0].authorName"), "Щеглов Михаил");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
474
src/test/java/ru/redrise/api/ExampleOnly.java
Normal file
474
src/test/java/ru/redrise/api/ExampleOnly.java
Normal file
|
@ -0,0 +1,474 @@
|
||||||
|
package ru.redrise.api;
|
||||||
|
|
||||||
|
import io.restassured.module.jsv.JsonSchemaValidator;
|
||||||
|
import io.restassured.path.json.JsonPath;
|
||||||
|
import io.restassured.specification.RequestSpecification;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static io.restassured.RestAssured.given;
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
|
public class ExampleOnly {
|
||||||
|
|
||||||
|
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
private final String jsonExample = """
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"addedDate" : "2024-01-01",
|
||||||
|
"authors" : [
|
||||||
|
{
|
||||||
|
"authorName" : "Демиденко Светлана Владимировна",
|
||||||
|
"id" : -458202851
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"container" : "f.fb2-759836-765669",
|
||||||
|
"deleted" : "0",
|
||||||
|
"fileExtension" : "fb2",
|
||||||
|
"fileSize" : 706185,
|
||||||
|
"fileSizeForHumans" : "689,63 KB",
|
||||||
|
"fsFileName" : "765663",
|
||||||
|
"genres" : [
|
||||||
|
{
|
||||||
|
"genreId" : "nonf_biography",
|
||||||
|
"humanReadableDescription" : null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id" : -1826362880,
|
||||||
|
"libId" : "765663",
|
||||||
|
"libraryId" : 1,
|
||||||
|
"libraryVersion" : "20240101",
|
||||||
|
"line" : null,
|
||||||
|
"position" : 0,
|
||||||
|
"serNo" : "",
|
||||||
|
"series" : "",
|
||||||
|
"title" : "Перелистывая память"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addedDate" : "2024-01-01",
|
||||||
|
"authors" : [
|
||||||
|
{
|
||||||
|
"authorName" : "Май Дмитрий",
|
||||||
|
"id" : 311992404
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"container" : "f.fb2-759836-765669",
|
||||||
|
"deleted" : "0",
|
||||||
|
"fileExtension" : "fb2",
|
||||||
|
"fileSize" : 507378,
|
||||||
|
"fileSizeForHumans" : "495,49 KB",
|
||||||
|
"fsFileName" : "765643",
|
||||||
|
"genres" : [
|
||||||
|
{
|
||||||
|
"genreId" : "child_tale",
|
||||||
|
"humanReadableDescription" : null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id" : -1782438812,
|
||||||
|
"libId" : "765643",
|
||||||
|
"libraryId" : 1,
|
||||||
|
"libraryVersion" : "20240101",
|
||||||
|
"line" : null,
|
||||||
|
"position" : 0,
|
||||||
|
"serNo" : "2",
|
||||||
|
"series" : "Детство",
|
||||||
|
"title" : "Новогодняя сказка"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addedDate" : "2024-01-01",
|
||||||
|
"authors" : [
|
||||||
|
{
|
||||||
|
"authorName" : "Демиденко Светлана Владимировна",
|
||||||
|
"id" : -458202851
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"container" : "f.fb2-759836-765669",
|
||||||
|
"deleted" : "0",
|
||||||
|
"fileExtension" : "fb2",
|
||||||
|
"fileSize" : 3526176,
|
||||||
|
"fileSizeForHumans" : "3,36 MB",
|
||||||
|
"fsFileName" : "765661",
|
||||||
|
"genres" : [
|
||||||
|
{
|
||||||
|
"genreId" : "nonf_biography",
|
||||||
|
"humanReadableDescription" : null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id" : -1753421740,
|
||||||
|
"libId" : "765661",
|
||||||
|
"libraryId" : 1,
|
||||||
|
"libraryVersion" : "20240101",
|
||||||
|
"line" : null,
|
||||||
|
"position" : 0,
|
||||||
|
"serNo" : "",
|
||||||
|
"series" : "",
|
||||||
|
"title" : "Любите меня"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addedDate" : "2024-01-01",
|
||||||
|
"authors" : [
|
||||||
|
{
|
||||||
|
"authorName" : "Алексеев Борис",
|
||||||
|
"id" : -1665780547
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"container" : "f.fb2-759836-765669",
|
||||||
|
"deleted" : "0",
|
||||||
|
"fileExtension" : "fb2",
|
||||||
|
"fileSize" : 449204,
|
||||||
|
"fileSizeForHumans" : "438,68 KB",
|
||||||
|
"fsFileName" : "765633",
|
||||||
|
"genres" : [
|
||||||
|
{
|
||||||
|
"genreId" : "adventure",
|
||||||
|
"humanReadableDescription" : null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"genreId" : "child_tale",
|
||||||
|
"humanReadableDescription" : null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"genreId" : "children",
|
||||||
|
"humanReadableDescription" : null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id" : -1665535280,
|
||||||
|
"libId" : "765633",
|
||||||
|
"libraryId" : 1,
|
||||||
|
"libraryVersion" : "20240101",
|
||||||
|
"line" : null,
|
||||||
|
"position" : 0,
|
||||||
|
"serNo" : "",
|
||||||
|
"series" : "",
|
||||||
|
"title" : "Новогоднее путешествие Большой Лужи"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addedDate" : "2024-01-01",
|
||||||
|
"authors" : [
|
||||||
|
{
|
||||||
|
"authorName" : "Элья Крепкая",
|
||||||
|
"id" : -183449638
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"container" : "f.fb2-759836-765669",
|
||||||
|
"deleted" : "0",
|
||||||
|
"fileExtension" : "fb2",
|
||||||
|
"fileSize" : 610834,
|
||||||
|
"fileSizeForHumans" : "596,52 KB",
|
||||||
|
"fsFileName" : "765654",
|
||||||
|
"genres" : [
|
||||||
|
{
|
||||||
|
"genreId" : "sf_action",
|
||||||
|
"humanReadableDescription" : null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"genreId" : "sf_heroic",
|
||||||
|
"humanReadableDescription" : null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"genreId" : "adventure",
|
||||||
|
"humanReadableDescription" : null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id" : -1609360729,
|
||||||
|
"libId" : "765654",
|
||||||
|
"libraryId" : 1,
|
||||||
|
"libraryVersion" : "20240101",
|
||||||
|
"line" : null,
|
||||||
|
"position" : 0,
|
||||||
|
"serNo" : "",
|
||||||
|
"series" : "",
|
||||||
|
"title" : "Старый рыцарь"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addedDate" : "2024-01-01",
|
||||||
|
"authors" : [
|
||||||
|
{
|
||||||
|
"authorName" : "Бёме Юлия",
|
||||||
|
"id" : 2108296075
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"container" : "f.fb2-759836-765669",
|
||||||
|
"deleted" : "0",
|
||||||
|
"fileExtension" : "fb2",
|
||||||
|
"fileSize" : 12985383,
|
||||||
|
"fileSizeForHumans" : "12,38 MB",
|
||||||
|
"fsFileName" : "765630",
|
||||||
|
"genres" : [
|
||||||
|
{
|
||||||
|
"genreId" : "child_tale",
|
||||||
|
"humanReadableDescription" : null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"genreId" : "children",
|
||||||
|
"humanReadableDescription" : null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id" : -1518406716,
|
||||||
|
"libId" : "765630",
|
||||||
|
"libraryId" : 1,
|
||||||
|
"libraryVersion" : "20240101",
|
||||||
|
"line" : null,
|
||||||
|
"position" : 0,
|
||||||
|
"serNo" : "6",
|
||||||
|
"series" : "Приключения в саванне",
|
||||||
|
"title" : "Тафити и банда обезьян"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addedDate" : "2024-01-01",
|
||||||
|
"authors" : [
|
||||||
|
{
|
||||||
|
"authorName" : "Макаров Марк",
|
||||||
|
"id" : -1967304956
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"container" : "f.fb2-759836-765669",
|
||||||
|
"deleted" : "0",
|
||||||
|
"fileExtension" : "fb2",
|
||||||
|
"fileSize" : 491992,
|
||||||
|
"fileSizeForHumans" : "480,46 KB",
|
||||||
|
"fsFileName" : "765666",
|
||||||
|
"genres" : [
|
||||||
|
{
|
||||||
|
"genreId" : "child_tale",
|
||||||
|
"humanReadableDescription" : null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id" : -1232223904,
|
||||||
|
"libId" : "765666",
|
||||||
|
"libraryId" : 1,
|
||||||
|
"libraryVersion" : "20240101",
|
||||||
|
"line" : null,
|
||||||
|
"position" : 0,
|
||||||
|
"serNo" : "",
|
||||||
|
"series" : "",
|
||||||
|
"title" : "Сказ о Иване царевиче и сером волке"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addedDate" : "2024-01-01",
|
||||||
|
"authors" : [
|
||||||
|
{
|
||||||
|
"authorName" : "Блэк Архиус",
|
||||||
|
"id" : 1779566922
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"container" : "f.fb2-759836-765669",
|
||||||
|
"deleted" : "0",
|
||||||
|
"fileExtension" : "fb2",
|
||||||
|
"fileSize" : 323584,
|
||||||
|
"fileSizeForHumans" : "316,00 KB",
|
||||||
|
"fsFileName" : "765635",
|
||||||
|
"genres" : [
|
||||||
|
{
|
||||||
|
"genreId" : "sf_social",
|
||||||
|
"humanReadableDescription" : null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"genreId" : "humor_anecdote",
|
||||||
|
"humanReadableDescription" : null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id" : -1163766944,
|
||||||
|
"libId" : "765635",
|
||||||
|
"libraryId" : 1,
|
||||||
|
"libraryVersion" : "20240101",
|
||||||
|
"line" : null,
|
||||||
|
"position" : 0,
|
||||||
|
"serNo" : "",
|
||||||
|
"series" : "",
|
||||||
|
"title" : "Огонь лишь начало"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addedDate" : "2024-01-01",
|
||||||
|
"authors" : [
|
||||||
|
{
|
||||||
|
"authorName" : "Шабалина Валентина",
|
||||||
|
"id" : -1801290427
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"container" : "f.fb2-759836-765669",
|
||||||
|
"deleted" : "0",
|
||||||
|
"fileExtension" : "fb2",
|
||||||
|
"fileSize" : 566330,
|
||||||
|
"fileSizeForHumans" : "553,06 KB",
|
||||||
|
"fsFileName" : "765647",
|
||||||
|
"genres" : [
|
||||||
|
{
|
||||||
|
"genreId" : "child_tale",
|
||||||
|
"humanReadableDescription" : null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id" : -865309302,
|
||||||
|
"libId" : "765647",
|
||||||
|
"libraryId" : 1,
|
||||||
|
"libraryVersion" : "20240101",
|
||||||
|
"line" : null,
|
||||||
|
"position" : 0,
|
||||||
|
"serNo" : "",
|
||||||
|
"series" : "",
|
||||||
|
"title" : "Полуночный поросёнок"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addedDate" : "2024-01-01",
|
||||||
|
"authors" : [
|
||||||
|
{
|
||||||
|
"authorName" : "Азк",
|
||||||
|
"id" : 1033971
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"container" : "f.fb2-759836-765669",
|
||||||
|
"deleted" : "0",
|
||||||
|
"fileExtension" : "fb2",
|
||||||
|
"fileSize" : 746212,
|
||||||
|
"fileSizeForHumans" : "728,72 KB",
|
||||||
|
"fsFileName" : "765632",
|
||||||
|
"genres" : [
|
||||||
|
{
|
||||||
|
"genreId" : "sf_action",
|
||||||
|
"humanReadableDescription" : null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"genreId" : "adventure",
|
||||||
|
"humanReadableDescription" : null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"genreId" : "network_literature",
|
||||||
|
"humanReadableDescription" : null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"genreId" : "popadancy",
|
||||||
|
"humanReadableDescription" : null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id" : -853565692,
|
||||||
|
"libId" : "765632",
|
||||||
|
"libraryId" : 1,
|
||||||
|
"libraryVersion" : "20240101",
|
||||||
|
"line" : null,
|
||||||
|
"position" : 0,
|
||||||
|
"serNo" : "3",
|
||||||
|
"series" : "Дивизион",
|
||||||
|
"title" : "Маневры 4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
""";
|
||||||
|
|
||||||
|
|
||||||
|
@Test(testName = "example 1",
|
||||||
|
enabled = false)
|
||||||
|
public void check1() {
|
||||||
|
JsonPath jsonPath = new JsonPath(jsonExample);
|
||||||
|
|
||||||
|
|
||||||
|
log.info("" + jsonPath.get("[0].id"));
|
||||||
|
log.info("" + jsonPath.get("flatten()[0].id"));
|
||||||
|
log.info(jsonPath.get("flatten().findAll{e -> e.id == -1826362880}.genres") + "");
|
||||||
|
log.info(jsonPath.get("flatten().findAll{it.id == -1826362880}.genres") + "");
|
||||||
|
log.info(jsonPath.get("flatten().findAll{it.authors.id.contains(-458202851)}.id") + "");
|
||||||
|
log.info(jsonPath.get("find{it.authors.id.contains(-458202851)}.id") + "\n");
|
||||||
|
|
||||||
|
List<List<Map<String, Object>>> authorIds = jsonPath.getList("flatten().findAll{it.authors.authorName.contains('Азк')}.genres");
|
||||||
|
for (List<Map<String, Object>> authors : authorIds) {
|
||||||
|
for (Map<String, Object> map : authors) {
|
||||||
|
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||||
|
log.info(entry.getKey() + "\t→\t" + entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.info("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
//log.info(authorId + "\n");
|
||||||
|
|
||||||
|
log.info(jsonPath.get("flatten().findAll{it.title.startsWith('Перелистывая')}.title") + "\n");
|
||||||
|
|
||||||
|
log.info("\n");
|
||||||
|
// ------
|
||||||
|
List<Map<String, Object>> list = jsonPath.getList("$");
|
||||||
|
|
||||||
|
for (Map<String, Object> maps : list) {
|
||||||
|
for (Map.Entry<String, Object> entry : maps.entrySet()) {
|
||||||
|
log.info(entry.getKey() + "\t→\t" + entry.getValue());
|
||||||
|
}
|
||||||
|
log.info("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(testName = "example 2")
|
||||||
|
public void check2() {
|
||||||
|
String HOST_URI = "http://localhost";
|
||||||
|
int HOST_PORT = 8080;
|
||||||
|
|
||||||
|
RequestSpecification specification = given()
|
||||||
|
.baseUri(HOST_URI)
|
||||||
|
.port(HOST_PORT);
|
||||||
|
|
||||||
|
specification
|
||||||
|
.when()
|
||||||
|
.get("/api/book?recent")
|
||||||
|
.then()
|
||||||
|
.assertThat()
|
||||||
|
.statusCode(200)
|
||||||
|
.body("find{it.authors.id.contains(-458202851)}.genres", // Find single record among others
|
||||||
|
hasItems(
|
||||||
|
allOf(
|
||||||
|
hasEntry("genreId", "nonf_biography"),
|
||||||
|
hasEntry("humanReadableDescription", null)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.body("find{it.authors.id.contains(1033971)}.genres", // Find single record among others
|
||||||
|
hasItems(
|
||||||
|
allOf(
|
||||||
|
hasEntry("genreId", "popadancy"),
|
||||||
|
hasEntry("humanReadableDescription", null)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.body("find{it.authors.id.contains(311992404)}", // Find single record among others
|
||||||
|
allOf(
|
||||||
|
hasEntry("fileExtension", "fb2"),
|
||||||
|
hasEntry("serNo", "2")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.body("find{it.authors.id.contains(311992404)}", // Find single record among others
|
||||||
|
anyOf(
|
||||||
|
hasEntry("fileExtension", "fb2"),
|
||||||
|
hasEntry("fileExtension", "100511")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.body("find{it.authors.id.contains(311992404)}", // Find single record among others
|
||||||
|
allOf(
|
||||||
|
hasKey("libraryVersion"),
|
||||||
|
hasKey("id"),
|
||||||
|
not(hasKey("test"))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.log().body()
|
||||||
|
.extract()
|
||||||
|
.jsonPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(testName = "example 3")
|
||||||
|
public void check3() {
|
||||||
|
String HOST_URI = "http://localhost";
|
||||||
|
int HOST_PORT = 8080;
|
||||||
|
|
||||||
|
given()
|
||||||
|
.baseUri(HOST_URI)
|
||||||
|
.port(HOST_PORT)
|
||||||
|
.when()
|
||||||
|
.get("/api/book?recent")
|
||||||
|
.then()
|
||||||
|
.assertThat()
|
||||||
|
.statusCode(200)
|
||||||
|
.body(
|
||||||
|
JsonSchemaValidator.matchesJsonSchemaInClasspath("book.json")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
146
src/test/java/ru/redrise/api/GenresApiTest.java
Normal file
146
src/test/java/ru/redrise/api/GenresApiTest.java
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
package ru.redrise.api;
|
||||||
|
|
||||||
|
import io.restassured.http.ContentType;
|
||||||
|
import io.restassured.path.json.JsonPath;
|
||||||
|
import io.restassured.response.Response;
|
||||||
|
import io.restassured.specification.RequestSpecification;
|
||||||
|
import org.apache.http.HttpStatus;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.testng.Assert;
|
||||||
|
import org.testng.annotations.BeforeClass;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static io.restassured.RestAssured.given;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.hasEntry;
|
||||||
|
|
||||||
|
public class GenresApiTest {
|
||||||
|
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
private static final String HOST_URI = "http://localhost";
|
||||||
|
private static final int HOST_PORT = 8080; // default 8080
|
||||||
|
|
||||||
|
private RequestSpecification specification;
|
||||||
|
|
||||||
|
private static final String genreId1 = "test01";
|
||||||
|
private static final String genreId2 = "test02";
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public void beforeClass() {
|
||||||
|
this.specification = given()
|
||||||
|
.baseUri(HOST_URI)
|
||||||
|
.port(HOST_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(testName = "Genres fetch")
|
||||||
|
public void genresFetch() {
|
||||||
|
JsonPath recent = specification
|
||||||
|
.when()
|
||||||
|
.get("/api/genres")
|
||||||
|
.then()
|
||||||
|
.assertThat()
|
||||||
|
.statusCode(200)
|
||||||
|
.log().body()
|
||||||
|
.extract()
|
||||||
|
.jsonPath();
|
||||||
|
|
||||||
|
List<Map<String, Object>> list = recent.getList("");
|
||||||
|
|
||||||
|
Assert.assertFalse(list.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
///api/genres
|
||||||
|
@Test(testName = "Genres create 1",
|
||||||
|
enabled = true)
|
||||||
|
public void genresCreate1() {
|
||||||
|
String payload = String.format("""
|
||||||
|
{
|
||||||
|
"genreId" : "%s",
|
||||||
|
"humanReadableDescription" : "test 01 description"
|
||||||
|
}
|
||||||
|
""", genreId1);
|
||||||
|
|
||||||
|
Response response = specification
|
||||||
|
.contentType(ContentType.JSON)
|
||||||
|
.body(payload)
|
||||||
|
.log().body()
|
||||||
|
.post("/api/genres");
|
||||||
|
|
||||||
|
Assert.assertEquals(response.getStatusCode(), HttpStatus.SC_CREATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(testName = "Genres create 2",
|
||||||
|
enabled = true)
|
||||||
|
public void genresCreate2() {
|
||||||
|
Map<String, Object> jsonData = new HashMap<>();
|
||||||
|
jsonData.put("genreId", genreId2);
|
||||||
|
jsonData.put("humanReadableDescription", "test 02 description " +
|
||||||
|
LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME));
|
||||||
|
|
||||||
|
Response response = specification
|
||||||
|
.contentType(ContentType.JSON)
|
||||||
|
.body(jsonData)
|
||||||
|
.log().body()
|
||||||
|
.post("/api/genres");
|
||||||
|
|
||||||
|
Assert.assertEquals(response.getStatusCode(), HttpStatus.SC_CREATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(testName = "Replace genre (PUT)",
|
||||||
|
priority = 1,
|
||||||
|
dependsOnMethods = {"genresCreate1", "genresCreate2"})
|
||||||
|
public void genresReplace() {
|
||||||
|
String genreDesc = "REPLACED DESCRIPTION " +
|
||||||
|
LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME);
|
||||||
|
|
||||||
|
Map<String, Object> jsonData = new HashMap<>();
|
||||||
|
jsonData.put("genreId", genreId2);
|
||||||
|
jsonData.put("humanReadableDescription", genreDesc);
|
||||||
|
|
||||||
|
log.info("about to update:");
|
||||||
|
Response response = specification
|
||||||
|
.contentType(ContentType.JSON)
|
||||||
|
.body(jsonData)
|
||||||
|
.log().body()
|
||||||
|
.put("/api/genres/" + genreId2);
|
||||||
|
|
||||||
|
Assert.assertEquals(response.getStatusCode(), HttpStatus.SC_OK);
|
||||||
|
|
||||||
|
log.info("Just updated:");
|
||||||
|
specification.when()
|
||||||
|
.get("/api/genres/by/id/" + genreId2)
|
||||||
|
.then()
|
||||||
|
.assertThat()
|
||||||
|
.statusCode(200)
|
||||||
|
.body("$", hasEntry("genreId", genreId2))
|
||||||
|
.body("humanReadableDescription", equalTo(genreDesc))
|
||||||
|
.log().body()
|
||||||
|
.extract()
|
||||||
|
.jsonPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(testName = "Delete test",
|
||||||
|
priority = 1,
|
||||||
|
dependsOnMethods = {"genresReplace"})
|
||||||
|
public void genresDelete(){
|
||||||
|
int record1status = specification
|
||||||
|
.log().body()
|
||||||
|
.delete("/api/genres/" + genreId1)
|
||||||
|
.statusCode();
|
||||||
|
|
||||||
|
int record2status = specification
|
||||||
|
.log().body()
|
||||||
|
.delete("/api/genres/" + genreId2)
|
||||||
|
.statusCode();
|
||||||
|
|
||||||
|
Assert.assertEquals(record1status, HttpStatus.SC_NO_CONTENT);
|
||||||
|
Assert.assertEquals(record2status, HttpStatus.SC_NO_CONTENT);
|
||||||
|
}
|
||||||
|
}
|
112
src/test/java/ru/redrise/users_management/LoginTest.java
Normal file
112
src/test/java/ru/redrise/users_management/LoginTest.java
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
package ru.redrise.users_management;
|
||||||
|
|
||||||
|
import org.openqa.selenium.*;
|
||||||
|
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||||
|
import org.testng.Assert;
|
||||||
|
import org.testng.annotations.*;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
public class LoginTest extends ScreenshotsMaker{
|
||||||
|
private WebDriver driver;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public void beforeClass() {
|
||||||
|
driver = Suite.driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void beforeMethod(){
|
||||||
|
driver.get("http://localhost:8080/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(testName = "Login page availability",
|
||||||
|
groups = "Login tests")
|
||||||
|
public void checkAdminLogin() {
|
||||||
|
this.latestTestMethodName = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||||
|
|
||||||
|
WebElement header = driver.findElement(By.tagName("header"));
|
||||||
|
|
||||||
|
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
|
||||||
|
wait.until(f -> header.isDisplayed());
|
||||||
|
|
||||||
|
WebElement signInLink = driver.findElement(
|
||||||
|
By.xpath("//nav[@id='header_right_block']/div[@class='block_inner']/ul/li/a[1]"));
|
||||||
|
|
||||||
|
Assert.assertTrue(signInLink.getAttribute("href").endsWith("/login"));
|
||||||
|
|
||||||
|
WebElement userNameInput = driver.findElement(By.xpath("//input[@id='username']"));
|
||||||
|
|
||||||
|
Assert.assertEquals(userNameInput.getAttribute("type"), "text");
|
||||||
|
|
||||||
|
WebElement psswdInput = driver.findElement(By.xpath("//input[@id='password']"));
|
||||||
|
|
||||||
|
Assert.assertEquals(psswdInput.getAttribute("type"), "password");
|
||||||
|
|
||||||
|
try{
|
||||||
|
driver.findElement(By.xpath("//a[@id='logout']")).click();
|
||||||
|
}
|
||||||
|
catch (Exception ignore){}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(priority = 1,
|
||||||
|
testName = "Login Failure Test",
|
||||||
|
groups = "Login tests")
|
||||||
|
public void loginFailureCheck() {
|
||||||
|
this.latestTestMethodName = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||||
|
|
||||||
|
WebElement userNameInput = driver.findElement(By.xpath("//input[@id='username']"));
|
||||||
|
|
||||||
|
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
|
||||||
|
wait.until(f -> userNameInput.isDisplayed());
|
||||||
|
|
||||||
|
userNameInput.sendKeys("incorrect-values-set");
|
||||||
|
|
||||||
|
WebElement psswdInput = driver.findElement(By.xpath("//input[@id='password']"));
|
||||||
|
|
||||||
|
psswdInput.sendKeys("incorrect-values-set");
|
||||||
|
|
||||||
|
driver.findElement(By.xpath("//button[@type='submit']")).click();
|
||||||
|
|
||||||
|
WebElement settingsLink = driver.findElement(
|
||||||
|
By.xpath("//span[@class='validationError']"));
|
||||||
|
|
||||||
|
wait.until(f -> settingsLink.isDisplayed());
|
||||||
|
|
||||||
|
try{
|
||||||
|
driver.findElement(By.xpath("//a[@id='logout']")).click();
|
||||||
|
}
|
||||||
|
catch (Exception ignore){}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Parameters({"admin_username", "admin_password"})
|
||||||
|
@Test(testName = "Default admin login",
|
||||||
|
groups = "Login tests")
|
||||||
|
public void loginAsAdminCheck(String user, String password) {
|
||||||
|
this.latestTestMethodName = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||||
|
|
||||||
|
WebElement userNameInput = driver.findElement(By.xpath("//input[@id='username']"));
|
||||||
|
|
||||||
|
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
|
||||||
|
wait.until(f -> userNameInput.isDisplayed());
|
||||||
|
|
||||||
|
userNameInput.sendKeys(user);
|
||||||
|
|
||||||
|
WebElement psswdInput = driver.findElement(By.xpath("//input[@id='password']"));
|
||||||
|
|
||||||
|
psswdInput.sendKeys(password);
|
||||||
|
|
||||||
|
driver.findElement(By.xpath("//button[@type='submit']")).click();
|
||||||
|
|
||||||
|
WebElement settingsLink = driver.findElement(
|
||||||
|
By.xpath("//nav[@id='header_right_block']/div[@class='block_inner']/ul/li/a[@href='/settings']"));
|
||||||
|
|
||||||
|
wait.until(f -> settingsLink.isDisplayed());
|
||||||
|
|
||||||
|
try{
|
||||||
|
driver.findElement(By.xpath("//a[@id='logout']")).click();
|
||||||
|
}
|
||||||
|
catch (Exception ignore){}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
package ru.redrise.users_management;
|
||||||
|
|
||||||
|
import org.openqa.selenium.By;
|
||||||
|
import org.openqa.selenium.WebDriver;
|
||||||
|
import org.openqa.selenium.WebElement;
|
||||||
|
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||||
|
import org.testng.Assert;
|
||||||
|
import org.testng.annotations.*;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
public class RegistrationAllowTest extends ScreenshotsMaker {
|
||||||
|
|
||||||
|
private WebDriver driver;
|
||||||
|
private WebDriverWait wait;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public void beforeClass(){
|
||||||
|
driver = Suite.driver;
|
||||||
|
wait = new WebDriverWait(driver, Duration.ofSeconds(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void beforeMethod(){
|
||||||
|
driver.get("http://localhost:8080/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterMethod
|
||||||
|
public void logout(){
|
||||||
|
try{
|
||||||
|
driver.findElement(By.xpath("//a[@id='logout']")).click();
|
||||||
|
}
|
||||||
|
catch (Exception ignore){}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Parameters({"admin_username", "admin_password"})
|
||||||
|
@Test(testName = "Check registration NOT allowed",
|
||||||
|
priority = 1,
|
||||||
|
groups = "registration_configuration")
|
||||||
|
public void checkRegNotAllowed(String user, String password){
|
||||||
|
latestTestMethodName = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||||
|
|
||||||
|
loginAsAdmin(user, password);
|
||||||
|
openSettings();
|
||||||
|
setRegistrationAllowed(false);
|
||||||
|
|
||||||
|
Assert.assertTrue(getRegistrationLink().getAttribute("href").endsWith("/true"));
|
||||||
|
|
||||||
|
// logout; alternate element picking approach
|
||||||
|
driver
|
||||||
|
.findElement(By.xpath("//nav[@id='header_right_block']/div[@class='block_inner']/ul/li[4]/a[1]"))
|
||||||
|
.click();
|
||||||
|
|
||||||
|
WebElement registerLink = driver.findElement(By.xpath("//div[@class='container base']/a[1]"));
|
||||||
|
|
||||||
|
wait.until(f -> registerLink.isDisplayed());
|
||||||
|
|
||||||
|
registerLink.click();
|
||||||
|
|
||||||
|
WebElement text = driver.findElement(By.tagName("h1"));
|
||||||
|
wait.until(f -> text.isDisplayed());
|
||||||
|
|
||||||
|
Assert.assertTrue(text.getText().contains("Currently we're closed to new registrations"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Parameters({"admin_username", "admin_password"})
|
||||||
|
@Test(testName = "Check registration allowed",
|
||||||
|
priority = 2,
|
||||||
|
groups = "registration_configuration")
|
||||||
|
public void checkRegAllowed(String user, String password){
|
||||||
|
this.latestTestMethodName = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||||
|
|
||||||
|
loginAsAdmin(user, password);
|
||||||
|
openSettings();
|
||||||
|
setRegistrationAllowed(true);
|
||||||
|
|
||||||
|
Assert.assertTrue(getRegistrationLink().getAttribute("href").endsWith("/false"));
|
||||||
|
// deep validation would be done within other tests
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loginAsAdmin(String user, String password){
|
||||||
|
WebElement userNameInput = driver.findElement(By.xpath("//input[@id='username']"));
|
||||||
|
|
||||||
|
wait.until(f -> userNameInput.isDisplayed());
|
||||||
|
|
||||||
|
userNameInput.sendKeys(user);
|
||||||
|
|
||||||
|
driver.findElement(By.xpath("//input[@id='password']")).sendKeys(password);
|
||||||
|
driver.findElement(By.xpath("//button[@type='submit']")).click();
|
||||||
|
}
|
||||||
|
private void openSettings(){
|
||||||
|
WebElement settingsLink = driver.findElement(
|
||||||
|
By.xpath("//nav[@id='header_right_block']/div[@class='block_inner']/ul/li/a[@href='/settings']"));
|
||||||
|
|
||||||
|
wait.until(f -> settingsLink.isDisplayed());
|
||||||
|
|
||||||
|
settingsLink.click();
|
||||||
|
}
|
||||||
|
private WebElement getRegistrationLink(){
|
||||||
|
return driver.findElement(By.xpath("//a[@id='registration']"));
|
||||||
|
}
|
||||||
|
private void setRegistrationAllowed(boolean isAllowed){
|
||||||
|
WebElement registrationLink = getRegistrationLink();
|
||||||
|
if (registrationLink.getAttribute("href").endsWith(isAllowed ? "/true" : "/false")) {
|
||||||
|
registrationLink.click();
|
||||||
|
|
||||||
|
wait.until(f -> getRegistrationLink().isDisplayed());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
411
src/test/java/ru/redrise/users_management/RegistrationTest.java
Normal file
411
src/test/java/ru/redrise/users_management/RegistrationTest.java
Normal file
|
@ -0,0 +1,411 @@
|
||||||
|
package ru.redrise.users_management;
|
||||||
|
|
||||||
|
import org.openqa.selenium.By;
|
||||||
|
import org.openqa.selenium.NoSuchElementException;
|
||||||
|
import org.openqa.selenium.WebDriver;
|
||||||
|
import org.openqa.selenium.WebElement;
|
||||||
|
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||||
|
import org.testng.Assert;
|
||||||
|
import org.testng.annotations.*;
|
||||||
|
import ru.redrise.utils.TwoColumnsExcelReader;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class RegistrationTest extends ScreenshotsMaker{
|
||||||
|
//private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
private String registeredUserLogin;
|
||||||
|
|
||||||
|
private WebDriver driver;
|
||||||
|
private WebDriverWait wait;
|
||||||
|
|
||||||
|
private final HashMap<String, String> allMyHandyErrors = new HashMap<>();
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public void beforeClass() throws Exception{
|
||||||
|
driver = Suite.driver;
|
||||||
|
wait = new WebDriverWait(driver, Duration.ofSeconds(5));
|
||||||
|
|
||||||
|
Arrays.stream(TwoColumnsExcelReader.getFromFile(true, "error_messages.xlsx", "Лист1"))
|
||||||
|
.forEach(e -> allMyHandyErrors.put(
|
||||||
|
((String) e[0]).trim(), ((String) e[1]).trim())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void beforeMethod(){
|
||||||
|
driver.get("http://localhost:8080/");
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Parameters({"test_user_login", "test_user_password", "test_user_displayedname"})
|
||||||
|
@Test(priority = 3,
|
||||||
|
testName = "Registration - positive",
|
||||||
|
dependsOnGroups = "registration_configuration")
|
||||||
|
public void regularRegistration(String user, String password, String displayedName) throws Exception{
|
||||||
|
this.latestTestMethodName = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||||
|
|
||||||
|
openRegistrationPage();
|
||||||
|
|
||||||
|
Random random = new Random();
|
||||||
|
|
||||||
|
for (int i = 0; registerAttempt(user+random.nextInt(9999), password, displayedName); i++){
|
||||||
|
if (i >= 10)
|
||||||
|
throw new Exception("Unable to register new user");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private boolean registerAttempt(String user, String password, String displayedName) {
|
||||||
|
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
|
||||||
|
|
||||||
|
pickUserNameField().sendKeys(user);
|
||||||
|
pickPasswordField().sendKeys(password);
|
||||||
|
pickPasswordConfirmField().sendKeys(password);
|
||||||
|
pickDisplaynameField().sendKeys(displayedName);
|
||||||
|
pickRegisterButton().click();
|
||||||
|
|
||||||
|
try{
|
||||||
|
WebElement alreadyExistsError = driver.findElement(By.xpath("//span[@class='validationError']"));
|
||||||
|
wait.until(f -> alreadyExistsError.isDisplayed());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ignore){ }
|
||||||
|
|
||||||
|
registeredUserLogin = user;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Parameters({"test_user_password", "test_user_displayedname"})
|
||||||
|
@Test(priority = 4,
|
||||||
|
testName = "Registration - already registered",
|
||||||
|
dependsOnGroups = "registration_configuration")
|
||||||
|
public void duplicateRegistration(String password, String displayedName) {
|
||||||
|
this.latestTestMethodName = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||||
|
|
||||||
|
WebElement registerLink = driver.findElement(By.xpath("//div[@class='container base']/a[1]"));
|
||||||
|
|
||||||
|
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
|
||||||
|
wait.until(f -> registerLink.isDisplayed());
|
||||||
|
|
||||||
|
registerLink.click();
|
||||||
|
|
||||||
|
Assert.assertTrue(registerAttempt(registeredUserLogin, password, displayedName));
|
||||||
|
|
||||||
|
WebElement error = driver.findElement(By.xpath("//span[@id='duplicate_error']"));
|
||||||
|
wait.until(f -> error.isDisplayed());
|
||||||
|
|
||||||
|
Assert.assertEquals(error.getText(), allMyHandyErrors.get("duplicate_error"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Parameters({"test_user_password", "test_user_displayedname"})
|
||||||
|
@Test(priority = 4,
|
||||||
|
testName = "Registration - failure - no name",
|
||||||
|
dependsOnGroups = "registration_configuration")
|
||||||
|
public void registrationFailureNoName1(String password, String displayedName) {
|
||||||
|
this.latestTestMethodName = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||||
|
|
||||||
|
openRegistrationPage();
|
||||||
|
|
||||||
|
pickPasswordField().sendKeys(password);
|
||||||
|
pickPasswordConfirmField().sendKeys(password);
|
||||||
|
pickDisplaynameField().sendKeys(displayedName);
|
||||||
|
pickRegisterButton().click();
|
||||||
|
|
||||||
|
WebElement error = driver.findElement(By.xpath("//span[@id='username_error']"));
|
||||||
|
wait.until(f -> error.isDisplayed());
|
||||||
|
|
||||||
|
Assert.assertTrue(registerAttempt(registeredUserLogin, password, displayedName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Parameters({"test_user_password", "test_user_displayedname"})
|
||||||
|
@Test(priority = 4,
|
||||||
|
testName = "Registration - failure - wrong name - short",
|
||||||
|
dependsOnGroups = "registration_configuration")
|
||||||
|
public void registrationFailureShortName(String password, String displayedName) {
|
||||||
|
this.latestTestMethodName = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||||
|
|
||||||
|
openRegistrationPage();
|
||||||
|
|
||||||
|
pickUserNameField().sendKeys(getRandomLettersName(2));
|
||||||
|
pickPasswordField().sendKeys(password);
|
||||||
|
pickPasswordConfirmField().sendKeys(password);
|
||||||
|
pickDisplaynameField().sendKeys(displayedName);
|
||||||
|
pickRegisterButton().click();
|
||||||
|
|
||||||
|
WebElement error = driver.findElement(By.xpath("//span[@id='username_error']"));
|
||||||
|
wait.until(f -> error.isDisplayed());
|
||||||
|
|
||||||
|
Assert.assertEquals(error.getText(), allMyHandyErrors.get("username_error"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Parameters({"test_user_password", "test_user_displayedname"})
|
||||||
|
@Test(priority = 4,
|
||||||
|
testName = "Registration - failure - wrong name - huge",
|
||||||
|
dependsOnGroups = "registration_configuration")
|
||||||
|
public void registrationFailureBigName(String password, String displayedName) {
|
||||||
|
this.latestTestMethodName = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||||
|
|
||||||
|
openRegistrationPage();
|
||||||
|
|
||||||
|
pickUserNameField().sendKeys(getRandomLettersName(33));
|
||||||
|
pickPasswordField().sendKeys(password);
|
||||||
|
pickPasswordConfirmField().sendKeys(password);
|
||||||
|
pickDisplaynameField().sendKeys(displayedName);
|
||||||
|
pickRegisterButton().click();
|
||||||
|
|
||||||
|
WebElement error = driver.findElement(By.xpath("//span[@id='username_error']"));
|
||||||
|
wait.until(f -> error.isDisplayed());
|
||||||
|
|
||||||
|
Assert.assertEquals(error.getText(), allMyHandyErrors.get("username_error"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(priority = 4,
|
||||||
|
testName = "Registration - failure - Correct name only entered",
|
||||||
|
expectedExceptions = { NoSuchElementException.class },
|
||||||
|
dependsOnGroups = "registration_configuration")
|
||||||
|
public void registrationFailuresCorrectNameOnly() throws Exception{
|
||||||
|
this.latestTestMethodName = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||||
|
|
||||||
|
openRegistrationPage();
|
||||||
|
|
||||||
|
pickUserNameField().sendKeys(getRandomLettersName(10));
|
||||||
|
pickRegisterButton().click();
|
||||||
|
|
||||||
|
WebElement error = driver.findElement(By.xpath("//span[@id='username_error']"));
|
||||||
|
wait.until(f -> error.isDisplayed());
|
||||||
|
}
|
||||||
|
|
||||||
|
// PASSWORD TESTING
|
||||||
|
|
||||||
|
@Parameters({"not_being_registered_login", "test_user_displayedname"})
|
||||||
|
@Test(priority = 4,
|
||||||
|
testName = "Registration - failure - no passwords",
|
||||||
|
dependsOnGroups = "registration_configuration")
|
||||||
|
public void registrationFailureNoPassword1(String name, String displayedName) {
|
||||||
|
this.latestTestMethodName = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||||
|
|
||||||
|
openRegistrationPage();
|
||||||
|
|
||||||
|
pickUserNameField().sendKeys(name);
|
||||||
|
pickDisplaynameField().sendKeys(displayedName);
|
||||||
|
pickRegisterButton().click();
|
||||||
|
|
||||||
|
WebElement error = driver.findElement(By.xpath("//span[@id='password_error']"));
|
||||||
|
wait.until(f -> error.isDisplayed());
|
||||||
|
|
||||||
|
Assert.assertEquals(error.getText(), allMyHandyErrors.get("password_error"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Parameters({"not_being_registered_login", "test_user_displayedname"})
|
||||||
|
@Test(priority = 4,
|
||||||
|
testName = "Registration - failure - wrong passord - short",
|
||||||
|
dependsOnGroups = "registration_configuration")
|
||||||
|
public void registrationFailureShortPassword(String name, String displayedName) {
|
||||||
|
this.latestTestMethodName = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||||
|
|
||||||
|
openRegistrationPage();
|
||||||
|
|
||||||
|
String shortPassword = getRandomLettersName(7);
|
||||||
|
|
||||||
|
pickUserNameField().sendKeys(name);
|
||||||
|
pickPasswordField().sendKeys(shortPassword);
|
||||||
|
pickPasswordConfirmField().sendKeys(shortPassword);
|
||||||
|
pickDisplaynameField().sendKeys(displayedName);
|
||||||
|
pickRegisterButton().click();
|
||||||
|
|
||||||
|
WebElement error = driver.findElement(By.xpath("//span[@id='password_error']"));
|
||||||
|
wait.until(f -> error.isDisplayed());
|
||||||
|
|
||||||
|
Assert.assertEquals(error.getText(), allMyHandyErrors.get("password_error"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Parameters({"not_being_registered_login", "test_user_displayedname"})
|
||||||
|
@Test(priority = 4,
|
||||||
|
testName = "Registration - failure - wrong passord - huge",
|
||||||
|
dependsOnGroups = "registration_configuration")
|
||||||
|
public void registrationFailureBigPassword(String name, String displayedName) {
|
||||||
|
this.latestTestMethodName = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||||
|
|
||||||
|
openRegistrationPage();
|
||||||
|
|
||||||
|
String shortPassword = getRandomLettersName(33);
|
||||||
|
|
||||||
|
pickUserNameField().sendKeys(name);
|
||||||
|
pickPasswordField().sendKeys(shortPassword);
|
||||||
|
pickPasswordConfirmField().sendKeys(shortPassword);
|
||||||
|
pickDisplaynameField().sendKeys(displayedName);
|
||||||
|
pickRegisterButton().click();
|
||||||
|
|
||||||
|
WebElement error = driver.findElement(By.xpath("//span[@id='password_error']"));
|
||||||
|
wait.until(f -> error.isDisplayed());
|
||||||
|
|
||||||
|
Assert.assertEquals(error.getText(), allMyHandyErrors.get("password_error"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Parameters({"test_user_password"})
|
||||||
|
@Test(priority = 4,
|
||||||
|
testName = "Registration - failure - Correct password only entered",
|
||||||
|
expectedExceptions = { NoSuchElementException.class },
|
||||||
|
dependsOnGroups = "registration_configuration")
|
||||||
|
public void registrationFailuresCorrectPasswordOnly(String password) throws Exception{
|
||||||
|
this.latestTestMethodName = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||||
|
|
||||||
|
openRegistrationPage();
|
||||||
|
|
||||||
|
pickPasswordField().sendKeys(password);
|
||||||
|
pickRegisterButton().click();
|
||||||
|
|
||||||
|
WebElement error = driver.findElement(By.xpath("//span[@id='password_error']"));
|
||||||
|
wait.until(f -> error.isDisplayed());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Parameters({"test_user_password"})
|
||||||
|
@Test(priority = 4,
|
||||||
|
testName = "Registration - failure - Correct password (both) only entered",
|
||||||
|
expectedExceptions = { NoSuchElementException.class },
|
||||||
|
dependsOnGroups = "registration_configuration")
|
||||||
|
public void registrationFailuresCorrectPasswordsOnly(String password) throws Exception{
|
||||||
|
this.latestTestMethodName = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||||
|
|
||||||
|
openRegistrationPage();
|
||||||
|
|
||||||
|
pickPasswordField().sendKeys(password);
|
||||||
|
pickPasswordConfirmField().sendKeys(password);
|
||||||
|
pickRegisterButton().click();
|
||||||
|
|
||||||
|
WebElement error = driver.findElement(By.xpath("//span[@id='password_error']"));
|
||||||
|
wait.until(f -> error.isDisplayed());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Repeat password field tests
|
||||||
|
|
||||||
|
@Parameters({"not_being_registered_login", "test_user_password", "test_user_displayedname"})
|
||||||
|
@Test(priority = 4,
|
||||||
|
testName = "Registration - failure - no duplicate password",
|
||||||
|
dependsOnGroups = "registration_configuration")
|
||||||
|
public void registrationFailureNoDuplicatePassword(String name, String password, String displayedName) {
|
||||||
|
this.latestTestMethodName = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||||
|
|
||||||
|
openRegistrationPage();
|
||||||
|
|
||||||
|
pickUserNameField().sendKeys(name);
|
||||||
|
pickPasswordField().sendKeys(password);
|
||||||
|
pickDisplaynameField().sendKeys(displayedName);
|
||||||
|
pickRegisterButton().click();
|
||||||
|
|
||||||
|
WebElement error = driver.findElement(By.xpath("//span[@id='password_dup_error']"));
|
||||||
|
wait.until(f -> error.isDisplayed());
|
||||||
|
|
||||||
|
Assert.assertEquals(error.getText(), allMyHandyErrors.get("password_dup_error"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Parameters({"not_being_registered_login", "test_user_password", "test_user_displayedname"})
|
||||||
|
@Test(priority = 4,
|
||||||
|
testName = "Registration - failure - password no match",
|
||||||
|
dependsOnGroups = "registration_configuration")
|
||||||
|
public void registrationWrongDuplicPassword(String name, String password, String displayedName) {
|
||||||
|
this.latestTestMethodName = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||||
|
|
||||||
|
openRegistrationPage();
|
||||||
|
|
||||||
|
pickUserNameField().sendKeys(name);
|
||||||
|
pickPasswordField().sendKeys(password);
|
||||||
|
pickPasswordConfirmField().sendKeys("42test");
|
||||||
|
pickDisplaynameField().sendKeys(displayedName);
|
||||||
|
pickRegisterButton().click();
|
||||||
|
|
||||||
|
WebElement error = driver.findElement(By.xpath("//span[@id='password_dup_error']"));
|
||||||
|
wait.until(f -> error.isDisplayed());
|
||||||
|
|
||||||
|
Assert.assertEquals(error.getText(), allMyHandyErrors.get("password_dup_error"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// DISPLAY NAME TESTING
|
||||||
|
|
||||||
|
@Parameters({"not_being_registered_login", "test_user_password"})
|
||||||
|
@Test(priority = 4,
|
||||||
|
testName = "Registration - failure - no display name",
|
||||||
|
dependsOnGroups = "registration_configuration")
|
||||||
|
public void registrationFailureNoDisplayName(String name, String password) {
|
||||||
|
this.latestTestMethodName = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||||
|
|
||||||
|
openRegistrationPage();
|
||||||
|
|
||||||
|
pickUserNameField().sendKeys(name);
|
||||||
|
pickPasswordField().sendKeys(password);
|
||||||
|
pickPasswordConfirmField().sendKeys(password);
|
||||||
|
pickRegisterButton().click();
|
||||||
|
|
||||||
|
WebElement error = driver.findElement(By.xpath("//span[@id='displayname_error']"));
|
||||||
|
wait.until(f -> error.isDisplayed());
|
||||||
|
|
||||||
|
Assert.assertEquals(error.getText(), allMyHandyErrors.get("displayname_error"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(priority = 4,
|
||||||
|
testName = "Registration - failure - Correct display name only entered",
|
||||||
|
expectedExceptions = { NoSuchElementException.class },
|
||||||
|
dependsOnGroups = "registration_configuration")
|
||||||
|
public void registrationFailuresCorrectDisplayNameOnly() throws Exception{
|
||||||
|
this.latestTestMethodName = Thread.currentThread().getStackTrace()[1].getMethodName();
|
||||||
|
|
||||||
|
openRegistrationPage();
|
||||||
|
|
||||||
|
pickDisplaynameField().sendKeys("test test test");
|
||||||
|
pickRegisterButton().click();
|
||||||
|
|
||||||
|
WebElement error = driver.findElement(By.xpath("//span[@id='displayname_error']"));
|
||||||
|
wait.until(f -> error.isDisplayed());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openRegistrationPage(){
|
||||||
|
WebElement header = driver.findElement(By.tagName("header"));
|
||||||
|
wait.until(f -> header.isDisplayed());
|
||||||
|
WebElement registerLink = driver.findElement(By.xpath("//div[@class='container base']/a[1]"));
|
||||||
|
registerLink.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
private WebElement pickUserNameField(){
|
||||||
|
return driver.findElement(By.xpath("//input[@id='username']"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private WebElement pickPasswordField(){
|
||||||
|
return driver.findElement(By.xpath("//input[@id='password']"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private WebElement pickPasswordConfirmField() {
|
||||||
|
return driver.findElement(By.xpath("//input[@id='passwordConfirm']"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private WebElement pickDisplaynameField() {
|
||||||
|
return driver.findElement(By.xpath("//input[@id='displayname']"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private WebElement pickRegisterButton() {
|
||||||
|
return driver.findElement(By.xpath("//button[@id='register_submit']"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRandomLettersName(int length){
|
||||||
|
if (length <= 0)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
Random random = new Random();
|
||||||
|
StringBuilder name = new StringBuilder((char) random.nextInt(0x41, 0x5A));
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
name.append((char) random.nextInt(0x41, 0x5A));
|
||||||
|
|
||||||
|
return name.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logout(){
|
||||||
|
try{
|
||||||
|
driver.findElement(By.xpath("//a[@id='logout']")).click();
|
||||||
|
}
|
||||||
|
catch (Exception ignore){}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package ru.redrise.users_management;
|
||||||
|
|
||||||
|
import org.openqa.selenium.OutputType;
|
||||||
|
import org.testng.Assert;
|
||||||
|
import org.testng.annotations.AfterMethod;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
|
||||||
|
public abstract class ScreenshotsMaker{
|
||||||
|
protected String latestTestMethodName;
|
||||||
|
|
||||||
|
@AfterMethod
|
||||||
|
public void takeScreenshot() throws IOException {
|
||||||
|
final String finalFileLocation = String.format("/tmp/tests-output/%s - %s.png",
|
||||||
|
getClass().toString().replaceAll("^.*\\.", ""), latestTestMethodName);
|
||||||
|
|
||||||
|
File screenshot = Suite.driver.getScreenshotAs(OutputType.FILE);
|
||||||
|
File finalLocation = new File(finalFileLocation);
|
||||||
|
|
||||||
|
if (!finalLocation.getParentFile().exists())
|
||||||
|
Assert.assertTrue(finalLocation.getParentFile().mkdirs());
|
||||||
|
|
||||||
|
Files.move(screenshot.toPath(), finalLocation.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
|
||||||
|
this.latestTestMethodName = "";
|
||||||
|
}
|
||||||
|
}
|
26
src/test/java/ru/redrise/users_management/Suite.java
Normal file
26
src/test/java/ru/redrise/users_management/Suite.java
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package ru.redrise.users_management;
|
||||||
|
|
||||||
|
import org.openqa.selenium.Dimension;
|
||||||
|
import org.openqa.selenium.chrome.ChromeDriver;
|
||||||
|
import org.openqa.selenium.chrome.ChromeOptions;
|
||||||
|
import org.testng.annotations.AfterSuite;
|
||||||
|
import org.testng.annotations.BeforeSuite;
|
||||||
|
|
||||||
|
public class Suite{
|
||||||
|
static ChromeDriver driver;
|
||||||
|
|
||||||
|
@BeforeSuite
|
||||||
|
public void beforeSuite() {
|
||||||
|
ChromeOptions options = new ChromeOptions();
|
||||||
|
options.addArguments("--remote-allow-origins=*");
|
||||||
|
options.addArguments("--headless");
|
||||||
|
|
||||||
|
driver = new ChromeDriver(options);
|
||||||
|
driver.manage().window().setSize(new Dimension(1024, 768));
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterSuite
|
||||||
|
public void afterSuite() {
|
||||||
|
driver.close();
|
||||||
|
}
|
||||||
|
}
|
33
src/test/java/ru/redrise/utils/TwoColumnsExcelReader.java
Normal file
33
src/test/java/ru/redrise/utils/TwoColumnsExcelReader.java
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package ru.redrise.utils;
|
||||||
|
|
||||||
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
|
||||||
|
public class TwoColumnsExcelReader {
|
||||||
|
private static final int COLUMN_COUNT = 2;
|
||||||
|
|
||||||
|
private TwoColumnsExcelReader(){}
|
||||||
|
|
||||||
|
public static Object[][] getFromFile(boolean firstRowIsTitle, String fileLocation, String sheetName) throws Exception{
|
||||||
|
return getFromFile(0, firstRowIsTitle ? 1 : 0, fileLocation, sheetName);
|
||||||
|
}
|
||||||
|
public static Object[][] getFromFile(int startColumn, int startRow, String fileLocation, String sheetName) throws Exception{
|
||||||
|
XSSFWorkbook excelWorkbook = new XSSFWorkbook(new FileInputStream(fileLocation));
|
||||||
|
XSSFSheet excelSpreadsheet = excelWorkbook.getSheet(sheetName);
|
||||||
|
int rowsCount = excelSpreadsheet.getLastRowNum();
|
||||||
|
|
||||||
|
String[][] results = new String[rowsCount - startRow][COLUMN_COUNT];
|
||||||
|
int j = 0;
|
||||||
|
for (int i = startRow; i < rowsCount; i++) {
|
||||||
|
Row row = excelSpreadsheet.getRow(i);
|
||||||
|
results[j][0] = row.getCell(startColumn).getStringCellValue();
|
||||||
|
results[j][1] = row.getCell(startColumn+1).getStringCellValue();
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
}
|
8
testng.xml
Normal file
8
testng.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
|
||||||
|
<suite name="All">
|
||||||
|
<suite-files>
|
||||||
|
<suite-file path="ui.xml" />
|
||||||
|
<suite-file path="api.xml" />
|
||||||
|
</suite-files>
|
||||||
|
</suite>
|
25
ui.xml
Normal file
25
ui.xml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
|
||||||
|
<suite name="UI Tests">
|
||||||
|
<!--
|
||||||
|
<listeners>
|
||||||
|
<listener class-name="ru.redrise.ReportListener" />
|
||||||
|
</listeners>
|
||||||
|
-->
|
||||||
|
<test verbose="2" preserve-order="true" name="UI tests">
|
||||||
|
<parameter name="admin_username" value="root"/>
|
||||||
|
<parameter name="admin_password" value="root"/>
|
||||||
|
|
||||||
|
<parameter name="not_being_registered_login" value="imnotregistered"/>
|
||||||
|
<parameter name="test_user_login" value="test-user"/>
|
||||||
|
<parameter name="test_user_password" value="hereisthetextuserpassword"/>
|
||||||
|
<parameter name="test_user_displayedname" value="Test User Name"/>
|
||||||
|
|
||||||
|
<classes>
|
||||||
|
<class name="ru.redrise.users_management.Suite" />
|
||||||
|
<class name="ru.redrise.users_management.LoginTest" />
|
||||||
|
<class name="ru.redrise.users_management.RegistrationAllowTest" />
|
||||||
|
<class name="ru.redrise.users_management.RegistrationTest" />
|
||||||
|
</classes>
|
||||||
|
</test>
|
||||||
|
</suite>
|
Loading…
Reference in a new issue