Merge remote-tracking branch 'origin/release/1.0.0' into feature/SUPPORT-8556_fix

This commit is contained in:
Eduard Tihomirov 2024-10-01 09:49:35 +03:00
commit 323b27be12
93 changed files with 1545 additions and 5563 deletions

View file

@ -244,9 +244,13 @@
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${parent.artifactId}</finalName>
<finalName>${project.parent.artifactId}</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>

View file

@ -0,0 +1,33 @@
package ru.micord.ervu.kafka;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.UUID;
import org.apache.kafka.clients.producer.ProducerInterceptor;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
/**
* @author gulnaz
*/
public class ErvuProducerInterceptor implements ProducerInterceptor<String, String> {
@Override
public ProducerRecord<String, String> onSend(ProducerRecord<String, String> record) {
if (record.topic().startsWith("ervu")) {
record.headers().remove("messageId");
record.headers().add("messageId", UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8));
}
return record;
}
@Override
public void onAcknowledgement(RecordMetadata recordMetadata, Exception e) {}
@Override
public void close() {}
@Override
public void configure(Map<String, ?> map) {}
}

View file

@ -12,11 +12,12 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.annotation.EnableKafka;
import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
import org.springframework.kafka.core.*;
import org.springframework.kafka.listener.ConcurrentMessageListenerContainer;
import org.springframework.kafka.requestreply.ReplyingKafkaTemplate;
import org.springframework.kafka.core.ConsumerFactory;
import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
import org.springframework.kafka.core.DefaultKafkaProducerFactory;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.core.ProducerFactory;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
@ -34,7 +35,8 @@ public class ReplyingKafkaConfig {
private String groupId;
@Value("${ervu.kafka.reply.timeout:30}")
private long replyTimeout;
@Value("${ervu.kafka.excerpt.reply.topic}")
private String excerptReplyTopic;
@Value("${ervu.kafka.security.protocol}")
private String securityProtocol;
@Value("${ervu.kafka.login.module:org.apache.kafka.common.security.scram.ScramLoginModule}")
@ -60,6 +62,7 @@ public class ReplyingKafkaConfig {
}
@Bean
@Qualifier("ervu")
public KafkaTemplate<String, String> kafkaTemplate() {
return new KafkaTemplate<>(producerFactory());
}
@ -85,49 +88,67 @@ public class ReplyingKafkaConfig {
return factory;
}
@Bean
@Qualifier("org")
public ConcurrentMessageListenerContainer<String, String> replyContainer(
ConcurrentKafkaListenerContainerFactory<String, String> factory) {
ConcurrentMessageListenerContainer<String, String> container = factory.createContainer(
orgReplyTopic);
container.getContainerProperties().setGroupId(groupId);
return container;
}
@Bean
@Qualifier("journal")
public ConcurrentMessageListenerContainer<String, String> journalReplyContainer(
ConcurrentKafkaListenerContainerFactory<String, String> factory) {
ConcurrentMessageListenerContainer<String, String> container = factory.createContainer(
journalReplyTopic);
container.getContainerProperties().setGroupId(groupId);
return container;
}
@Bean
@Qualifier("org")
public ReplyingKafkaTemplate<String, String, String> orgReplyingKafkaTemplate(
@Qualifier("ervu") ProducerFactory<String, String> pf,
@Qualifier("org") ConcurrentMessageListenerContainer<String, String> container) {
return initReplyingKafkaTemplate(pf, container);
}
@Bean
@Qualifier("journal")
public ReplyingKafkaTemplate<String, String, String> journalReplyingKafkaTemplate(
@Qualifier("ervu") ProducerFactory<String, String> pf,
@Qualifier("journal") ConcurrentMessageListenerContainer<String, String> container) {
return initReplyingKafkaTemplate(pf, container);
}
private ReplyingKafkaTemplate<String, String, String> initReplyingKafkaTemplate(
ProducerFactory<String, String> pf,
ConcurrentMessageListenerContainer<String, String> container) {
ReplyingKafkaTemplate<String, String, String> replyingKafkaTemplate =
new ReplyingKafkaTemplate<>(pf, container);
replyingKafkaTemplate.setCorrelationHeaderName("messageID");
replyingKafkaTemplate.setDefaultReplyTimeout(Duration.ofSeconds(replyTimeout));
return replyingKafkaTemplate;
}
// @Bean()
// @Qualifier("excerpt-container")
// public ConcurrentMessageListenerContainer<String, String> excerptReplyContainer(
// ConcurrentKafkaListenerContainerFactory<String, String> factory) {
// ConcurrentMessageListenerContainer<String, String> container = factory.createContainer(
// excerptReplyTopic);
// container.getContainerProperties().setGroupId(groupId);
// return container;
// }
//
// @Bean()
// @Qualifier("excerpt-template")
// public ReplyingKafkaTemplate<String, String, String> excerptReplyingKafkaTemplate(
// @Qualifier("ervu") ProducerFactory<String, String> pf,
// @Qualifier("excerpt-container") ConcurrentMessageListenerContainer<String, String> container) {
// return initReplyingKafkaTemplate(pf, container);
// }
//
// @Bean
// @Qualifier("org")
// public ConcurrentMessageListenerContainer<String, String> replyContainer(
// ConcurrentKafkaListenerContainerFactory<String, String> factory) {
// ConcurrentMessageListenerContainer<String, String> container = factory.createContainer(
// orgReplyTopic);
// container.getContainerProperties().setGroupId(groupId);
// return container;
// }
//
// @Bean
// @Qualifier("journal")
// public ConcurrentMessageListenerContainer<String, String> journalReplyContainer(
// ConcurrentKafkaListenerContainerFactory<String, String> factory) {
// ConcurrentMessageListenerContainer<String, String> container = factory.createContainer(
// journalReplyTopic);
// container.getContainerProperties().setGroupId(groupId);
// return container;
// }
//
// @Bean
// @Qualifier("org")
// public ReplyingKafkaTemplate<String, String, String> orgReplyingKafkaTemplate(
// @Qualifier("ervu") ProducerFactory<String, String> pf,
// @Qualifier("org") ConcurrentMessageListenerContainer<String, String> container) {
// return initReplyingKafkaTemplate(pf, container);
// }
//
// @Bean
// @Qualifier("journal")
// public ReplyingKafkaTemplate<String, String, String> journalReplyingKafkaTemplate(
// @Qualifier("ervu") ProducerFactory<String, String> pf,
// @Qualifier("journal") ConcurrentMessageListenerContainer<String, String> container) {
// return initReplyingKafkaTemplate(pf, container);
// }
//
// private ReplyingKafkaTemplate<String, String, String> initReplyingKafkaTemplate(
// ProducerFactory<String, String> pf,
// ConcurrentMessageListenerContainer<String, String> container) {
// ReplyingKafkaTemplate<String, String, String> replyingKafkaTemplate =
// new ReplyingKafkaTemplate<>(pf, container);
// replyingKafkaTemplate.setCorrelationHeaderName("messageId");
// replyingKafkaTemplate.setDefaultReplyTimeout(Duration.ofSeconds(replyTimeout));
// return replyingKafkaTemplate;
// }
}

View file

@ -0,0 +1,83 @@
package ru.micord.ervu.kafka.controller;
import java.util.Arrays;
import java.util.Optional;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import ru.micord.ervu.kafka.model.Data;
import ru.micord.ervu.kafka.model.ErvuOrgResponse;
import ru.micord.ervu.kafka.model.ExcerptResponse;
import ru.micord.ervu.kafka.service.ReplyingKafkaService;
import ru.micord.ervu.s3.S3Service;
import ru.micord.ervu.security.webbpm.jwt.model.Token;
import ru.micord.ervu.security.webbpm.jwt.service.JwtTokenService;
/**
* @author Eduard Tihomirov
*/
@RestController
public class ErvuKafkaController {
@Autowired
// @Qualifier("excerpt-service")
private ReplyingKafkaService replyingKafkaService;
@Autowired
private S3Service s3Service;
@Autowired
private JwtTokenService jwtTokenService;
@Value("${ervu.kafka.excerpt.reply.topic}")
private String requestReplyTopic;
@Value("${ervu.kafka.excerpt.request.topic}")
private String requestTopic;
@Autowired
private ObjectMapper objectMapper;
@RequestMapping(value = "/kafka/excerpt")
public ResponseEntity<InputStreamResource> getExcerptFile(HttpServletRequest request) {
try {
String authToken = getAuthToken(request);
Token token = jwtTokenService.getToken(authToken);
String[] split = token.getUserAccountId().split(":");
String prnOid = split[0];
String ervuId = split[1];
Data data = new Data();
data.setOrgId_ERVU(ervuId);
data.setPrnOid(prnOid);
String kafkaResponse = replyingKafkaService.sendMessageAndGetReply(requestTopic, requestReplyTopic,
objectMapper.writeValueAsString(data)
);
ExcerptResponse excerptResponse = objectMapper.readValue(kafkaResponse, ExcerptResponse.class);
return s3Service.getFile(excerptResponse.getFileUrl());
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
private String getAuthToken(HttpServletRequest request) {
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("auth_token")) {
return cookie.getValue();
}
}
}
return null;
}
}

View file

@ -13,7 +13,7 @@ public class ErvuOrgResponse implements Serializable {
private static final long serialVersionUID = 1L;
private boolean success;
private String message;
private Data[] data;
private Data data;
public boolean getSuccess() {
return success;
@ -31,11 +31,11 @@ public class ErvuOrgResponse implements Serializable {
this.message = message;
}
public Data[] getData() {
public Data getData() {
return data;
}
public void setData(Data[] data) {
public void setData(Data data) {
this.data = data;
}
}

View file

@ -0,0 +1,66 @@
package ru.micord.ervu.kafka.model;
import java.io.Serializable;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/**
* @author Eduard Tihomirov
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class ExcerptResponse implements Serializable {
private static final long serialVersionUID = 1L;
private String excerptId;
private String orgId;
private String fileUrl;
@JsonFormat(pattern = "dd.MM.yyyy HH:mm")
private Date departureDateTime;
private String timeZone;
public String getExcerptId() {
return excerptId;
}
public void setExcerptId(String excerptId) {
this.excerptId = excerptId;
}
public String getOrgId() {
return orgId;
}
public void setOrgId(String orgId) {
this.orgId = orgId;
}
public Date getDepartureDateTime() {
return departureDateTime;
}
public void setDepartureDateTime(Date departureDateTime) {
this.departureDateTime = departureDateTime;
}
public String getTimeZone() {
return timeZone;
}
public void setTimeZone(String timeZone) {
this.timeZone = timeZone;
}
public String getFileUrl() {
return fileUrl;
}
public void setFileUrl(String fileUrl) {
this.fileUrl = fileUrl;
}
}

View file

@ -1,39 +1,73 @@
package ru.micord.ervu.kafka.service.impl;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Collections;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.header.internals.RecordHeader;
import org.springframework.kafka.requestreply.ReplyingKafkaTemplate;
import org.springframework.kafka.requestreply.RequestReplyFuture;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.kafka.core.ConsumerFactory;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.KafkaHeaders;
import org.springframework.stereotype.Service;
import ru.micord.ervu.kafka.service.ReplyingKafkaService;
/**
* @author Eduard Tihomirov
*/
public abstract class BaseReplyingKafkaServiceImpl implements ReplyingKafkaService {
@Service
public class BaseReplyingKafkaServiceImpl implements ReplyingKafkaService {
protected abstract ReplyingKafkaTemplate<String, String, String> getReplyingKafkaTemplate();
// protected abstract ReplyingKafkaTemplate<String, String, String> getReplyingKafkaTemplate();
@Autowired
@Qualifier("ervu")
private KafkaTemplate<String, String> kafkaTemplate;
@Autowired
private ConsumerFactory<String, String> consumerFactory;
@Value("${ervu.kafka.group.id}")
private String groupId;
@Value("${ervu.kafka.reply.timeout:30}")
private long replyTimeout;
public String sendMessageAndGetReply(String requestTopic,
String requestReplyTopic,
String replyTopic,
String requestMessage) {
ProducerRecord<String, String> record = new ProducerRecord<>(requestTopic, requestMessage);
record.headers().add(new RecordHeader(KafkaHeaders.REPLY_TOPIC, requestReplyTopic.getBytes()));
record.headers().add(new RecordHeader(KafkaHeaders.REPLY_TOPIC, replyTopic.getBytes()));
//TODO fix No pending reply error
// RequestReplyFuture<String, String, String> replyFuture = getReplyingKafkaTemplate()
// .sendAndReceive(record);
//
// try {
// return Optional.ofNullable(replyFuture.get())
// .map(ConsumerRecord::value)
// .orElseThrow(() -> new RuntimeException("Kafka return result is null."));
// }
// catch (InterruptedException | ExecutionException e) {
// throw new RuntimeException("Failed to get kafka response.", e);
// }
RequestReplyFuture<String, String, String> replyFuture = getReplyingKafkaTemplate()
.sendAndReceive(record);
record.headers().add("messageId", UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8));
kafkaTemplate.send(record);
AtomicReference<String> responseRef = new AtomicReference<>(null);
try {
return Optional.ofNullable(replyFuture.get())
.map(ConsumerRecord::value)
.orElseThrow(() -> new RuntimeException("Kafka return result is null."));
}
catch (InterruptedException | ExecutionException e) {
throw new RuntimeException("Failed to get kafka response.", e);
try (Consumer<String, String> consumer =
consumerFactory.createConsumer(groupId, null)) {
consumer.subscribe(Collections.singletonList(replyTopic));
ConsumerRecords<String, String> consumerRecords = consumer.poll(Duration.ofSeconds(replyTimeout));
consumerRecords.forEach(consumerRecord -> responseRef.set(consumerRecord.value()));
consumer.commitSync();
}
return Optional.ofNullable(responseRef.get())
.orElseThrow(() -> new RuntimeException("Kafka return result is null"));
}
}

View file

@ -0,0 +1,23 @@
package ru.micord.ervu.kafka.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.kafka.requestreply.ReplyingKafkaTemplate;
import org.springframework.stereotype.Service;
/**
* @author Eduard Tihomirov
*/
//@Service
//@Qualifier("excerpt-service")
public class ExcerptReplyingKafkaServiceImpl {
// @Autowired
// @Qualifier("excerpt-template")
// private ReplyingKafkaTemplate<String, String, String> excerptReplyingKafkaTemplate;
//
// @Override
// protected ReplyingKafkaTemplate<String, String, String> getReplyingKafkaTemplate() {
// return excerptReplyingKafkaTemplate;
// }
}

View file

@ -5,16 +5,16 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.kafka.requestreply.ReplyingKafkaTemplate;
import org.springframework.stereotype.Service;
@Service
@Qualifier("journal")
public class JournalReplyingKafkaServiceImpl extends BaseReplyingKafkaServiceImpl {
//@Service
//@Qualifier("journal")
public class JournalReplyingKafkaServiceImpl {
@Autowired
@Qualifier("journal")
private ReplyingKafkaTemplate<String, String, String> journalReplyingKafkaTemplate;
@Override
protected ReplyingKafkaTemplate<String, String, String> getReplyingKafkaTemplate() {
return journalReplyingKafkaTemplate;
}
// @Autowired
// @Qualifier("journal")
// private ReplyingKafkaTemplate<String, String, String> journalReplyingKafkaTemplate;
//
// @Override
// protected ReplyingKafkaTemplate<String, String, String> getReplyingKafkaTemplate() {
// return journalReplyingKafkaTemplate;
// }
}

View file

@ -5,16 +5,16 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.kafka.requestreply.ReplyingKafkaTemplate;
import org.springframework.stereotype.Service;
@Service
@Qualifier("org")
public class OrgReplyingKafkaServiceImpl extends BaseReplyingKafkaServiceImpl {
//@Service
//@Qualifier("org")
public class OrgReplyingKafkaServiceImpl {
@Autowired
@Qualifier("org")
private ReplyingKafkaTemplate<String, String, String> orgReplyingKafkaTemplate;
@Override
protected ReplyingKafkaTemplate<String, String, String> getReplyingKafkaTemplate() {
return orgReplyingKafkaTemplate;
}
// @Autowired
// @Qualifier("org")
// private ReplyingKafkaTemplate<String, String, String> orgReplyingKafkaTemplate;
//
// @Override
// protected ReplyingKafkaTemplate<String, String, String> getReplyingKafkaTemplate() {
// return orgReplyingKafkaTemplate;
// }
}

View file

@ -0,0 +1,41 @@
package ru.micord.ervu.s3;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Eduard Tihomirov
*/
@Configuration
public class S3Connection {
@Value("${s3.endpoint}")
private String endpoint;
@Value("${s3.access_key}")
private String accessKey;
@Value("${s3.secret_key}")
private String secretKey;
@Bean("outClient")
public AmazonS3 getS3OutClient() {
return getS3Client(endpoint, accessKey, secretKey);
}
private static AmazonS3 getS3Client(String endpoint, String accessKey, String secretKey) {
AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
String region = Region.getRegion(Regions.DEFAULT_REGION).toString();
return AmazonS3ClientBuilder.standard()
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endpoint, region))
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.build();
}
}

View file

@ -0,0 +1,42 @@
package ru.micord.ervu.s3;
import java.io.File;
import java.net.URI;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3URI;
import com.amazonaws.services.s3.model.S3Object;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
/**
* @author Eduard Tihomirov
*/
@Service
public class S3Service {
private final AmazonS3 outClient;
@Autowired
public S3Service(AmazonS3 outClient) {
this.outClient = outClient;
}
public ResponseEntity<InputStreamResource> getFile(String fileUrl) {
try {
AmazonS3URI uri = new AmazonS3URI(fileUrl);
S3Object s3Object = outClient.getObject(uri.getBucket(), uri.getKey());
InputStreamResource resource = new InputStreamResource(s3Object.getObjectContent());
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + uri.getKey())
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(resource);
}
catch (AmazonServiceException e) {
throw new RuntimeException(e);
}
}
}

View file

@ -13,7 +13,6 @@ import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.servlet.http.Cookie;
@ -22,11 +21,11 @@ import javax.servlet.http.HttpServletResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import ervu.service.okopf.OkopfService;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.util.StringUtils;
import ru.micord.ervu.security.esia.config.EsiaConfig;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import ru.micord.ervu.kafka.model.Brhs;
import ru.micord.ervu.kafka.model.Data;
import ru.micord.ervu.kafka.model.Employee;
import ru.micord.ervu.kafka.model.ErvuOrgResponse;
import ru.micord.ervu.kafka.model.OrgInfo;
@ -41,6 +40,7 @@ import ru.micord.ervu.security.esia.model.EsiaAccessToken;
import ru.micord.ervu.security.esia.model.EsiaTokenResponse;
import ru.micord.ervu.security.esia.model.FormUrlencoded;
import ru.micord.ervu.security.esia.model.OrganizationModel;
import ru.micord.ervu.security.webbpm.jwt.JwtAuthentication;
import ru.micord.ervu.security.webbpm.jwt.service.JwtTokenService;
import ru.micord.ervu.security.webbpm.jwt.model.Token;
@ -66,7 +66,7 @@ public class EsiaAuthService {
private JwtTokenService jwtTokenService;
@Autowired
@Qualifier("org")
// @Qualifier("org")
private ReplyingKafkaService replyingKafkaService;
@Autowired
@ -233,9 +233,13 @@ public class EsiaAuthService {
authToken.setPath(cookiePath);
authToken.setHttpOnly(true);
response.addCookie(authToken);
SecurityContextHolder.getContext()
.setAuthentication(
new UsernamePasswordAuthenticationToken(esiaAccessToken.getSbj_id(), null));
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
new UsernamePasswordAuthenticationToken(token.getUserAccountId(), null);
SecurityContext context = SecurityContextHolder.createEmptyContext();
JwtAuthentication authentication = new JwtAuthentication(usernamePasswordAuthenticationToken,
esiaAccessToken.getSbj_id(), token.getValue());
context.setAuthentication(authentication);
SecurityContextHolder.setContext(context);
Cookie isAuth = new Cookie("webbpm.ervu-lkrp-ul", "true");
isAuth.setMaxAge(tokenResponse.getExpires_in().intValue());
@ -331,9 +335,13 @@ public class EsiaAuthService {
authToken.setPath(cookiePath);
authToken.setHttpOnly(true);
response.addCookie(authToken);
SecurityContextHolder.getContext()
.setAuthentication(
new UsernamePasswordAuthenticationToken(esiaAccessToken.getSbj_id(), null));
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
new UsernamePasswordAuthenticationToken(token.getUserAccountId(), null);
SecurityContext context = SecurityContextHolder.createEmptyContext();
JwtAuthentication authentication = new JwtAuthentication(usernamePasswordAuthenticationToken,
esiaAccessToken.getSbj_id(), token.getValue());
context.setAuthentication(authentication);
SecurityContextHolder.setContext(context);
Cookie isAuth = new Cookie("webbpm.ervu-lkrp-ul", "true");
isAuth.setMaxAge(tokenResponse.getExpires_in().intValue());
@ -420,21 +428,16 @@ public class EsiaAuthService {
requestReplyTopic, objectMapper.writeValueAsString(orgInfo)
);
ErvuOrgResponse ervuOrgResponse = objectMapper.readValue(kafkaResponse, ErvuOrgResponse.class);
List<String> listErvuId = Arrays.stream(ervuOrgResponse.getData()).filter(data -> data.getPrnOid().equals(prnOid)).map(
Data::getOrgId_ERVU).toList();
if (listErvuId.size() > 1) {
throw new RuntimeException("More than one ervuId for prnOid = " + prnOid);
}
else if (listErvuId.isEmpty()) {
String ervuId = ervuOrgResponse.getData().getOrgId_ERVU();
if (!StringUtils.hasText(ervuId)) {
throw new RuntimeException("No ervuId for prnOid = " + prnOid);
}
return listErvuId.get(0);
return ervuId;
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
private OrgInfo copyToOrgInfo(OrganizationModel organizationModel, EmployeeModel employeeModel, EmployeeModel chiefModel ) {

View file

@ -47,7 +47,7 @@ public class JwtAuthenticationProvider implements AuthenticationProvider {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
new UsernamePasswordAuthenticationToken(token.getUserAccountId(), null);
return new JwtAuthentication(usernamePasswordAuthenticationToken, token.getUserAccountId());
return new JwtAuthentication(usernamePasswordAuthenticationToken, token.getUserAccountId(), token.getValue());
}
@Override

View file

@ -76,6 +76,7 @@ public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFil
for (Cookie cookie : cookies) {
if (cookie.getName().equals("auth_token")) {
token = cookie.getValue();
LOGGER.info("Token extracted from cookie: {}", token);
}
}
}

View file

@ -1,22 +1,22 @@
package ru.micord.ervu.service.grid.impl;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import ru.micord.ervu.journal.JournalDto;
import ru.micord.ervu.journal.JournalFileDataRequest;
import ru.micord.ervu.journal.JournalFileDataResponse;
import ru.micord.ervu.journal.mapper.JournalDtoMapper;
import ru.micord.ervu.security.webbpm.jwt.JwtAuthentication;
import ru.micord.ervu.service.InteractionService;
import ru.micord.ervu.service.grid.InMemoryStaticGridLoadService;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import ru.micord.ervu.kafka.service.ReplyingKafkaService;
@ -30,6 +30,8 @@ public class JournalInMemoryStaticGridLoadService implements
private final InteractionService interactionService;
private final ReplyingKafkaService ervuReplyingKafkaService;
private final ObjectMapper objectMapper;
private final HttpServletRequest request;
@Value("${ervu.kafka.journal.request.topic}")
private String requestTopic;
@ -40,12 +42,13 @@ public class JournalInMemoryStaticGridLoadService implements
public JournalInMemoryStaticGridLoadService(JwtTokenService jwtTokenService,
InteractionService interactionService,
@Qualifier("journal") ReplyingKafkaService ervuReplyingKafkaService,
ObjectMapper objectMapper) {
ReplyingKafkaService ervuReplyingKafkaService,
ObjectMapper objectMapper, HttpServletRequest request) {
this.jwtTokenService = jwtTokenService;
this.interactionService = interactionService;
this.ervuReplyingKafkaService = ervuReplyingKafkaService;
this.objectMapper = objectMapper;
this.request = request;
}
@Override
@ -76,11 +79,14 @@ public class JournalInMemoryStaticGridLoadService implements
}
private JournalFileDataRequest initJournalFileDataRequest() {
Optional<Authentication> authentication = Optional.ofNullable(
SecurityContextHolder.getContext().getAuthentication());
String jwtToken = authentication.map(auth -> ((JwtAuthentication) auth).getToken())
String authToken = Optional.ofNullable(request.getCookies())
.map(cookies -> Arrays.stream(cookies)
.filter(cookie -> cookie.getName().equals("auth_token"))
.findFirst()
.map(Cookie::getValue)
.orElseThrow(() -> new RuntimeException("Failed to get auth data. User unauthorized.")))
.orElseThrow(() -> new RuntimeException("Failed to get auth data. User unauthorized."));
String[] ids = jwtTokenService.getToken(jwtToken).getUserAccountId().split(":");
String[] ids = jwtTokenService.getToken(authToken).getUserAccountId().split(":");
String userId = ids[0];
String ervuId = ids[1];
return new JournalFileDataRequest()

View file

@ -29,7 +29,7 @@ ESIA_CLIENT_ID=MNSV89
ESIA_REDIRECT_URL=https://lkrp-dev.micord.ru/ul/
SIGN_URL=https://ervu-sign-dev.k8s.micord.ru/sign
ESIA_CLIENT_CERT_HASH=04508B4B0B58776A954A0E15F574B4E58799D74C61EE020B3330716C203E3BDD
ERVU_KAFKA_BOOTSTRAP_SERVERS=localhost:9092
ERVU_KAFKA_BOOTSTRAP_SERVERS=10.10.31.11:32609
ERVU_KAFKA_ORG_REPLY_TOPIC=ervu.organization.response
ERVU_KAFKA_GROUP_ID=1
ERVU_KAFKA_ORG_REQUEST_TOPIC=ervu.organization.request
@ -42,3 +42,9 @@ ERVU_KAFKA_SECURITY_PROTOCOL=SASL_PLAINTEXT
ERVU_KAFKA_SASL_MECHANISM=SCRAM-SHA-256
ERVU_KAFKA_USERNAME=user1
ERVU_KAFKA_PASSWORD=Blfi9d2OFG
ERVU_KAFKA_EXCERPT_REPLY_TOPIC=ervu.lkrp.excerpt.response
ERVU_KAFKA_EXCERPT_REQUEST_TOPIC=ervu.lkrp.excerpt.request
S3_ENDPOINT=http://ervu-minio.k8s.micord.ru:31900
S3_ACCESS_KEY=rlTdTvkmSXu9FsLhfecw
S3_SECRET_KEY=NUmY0wwRIEyAd98GCKd1cOgJWvLQYAcMMul5Ulu0

View file

@ -89,6 +89,11 @@
<property name="esnsi.okopf.url" value="https://esnsi.gosuslugi.ru/rest/ext/v1/classifiers/11465/file?extension=JSON&amp;encoding=UTF_8"/>
<property name="ervu.kafka.journal.request.topic" value="ervu.organization.journal.request"/>
<property name="ervu.kafka.journal.reply.topic" value="ervu.organization.journal.response"/>
<property name="ervu.kafka.excerpt.reply.topic" value="ervu.lkrp.excerpt.response"/>
<property name="ervu.kafka.excerpt.request.topic" value="ervu.lkrp.excerpt.request"/>
<property name="s3.endpoint" value="http://ervu-minio.k8s.micord.ru:31900"/>
<property name="s3.access_key" value="rlTdTvkmSXu9FsLhfecw"/>
<property name="s3.secret_key" value="NUmY0wwRIEyAd98GCKd1cOgJWvLQYAcMMul5Ulu0"/>
<property name="av.kafka.group.id" value="1"/>
<property name="av.kafka.download.response" value="file-status"/>
</system-properties>

111
frontend/home.html Normal file
View file

@ -0,0 +1,111 @@
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="src/resources/landing/home.css">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body class="ul">
<div class="header">
<div class="header-logo"></div>
<div class="header-title">Официальный сайт Минобороны России <a href="https://mil.ru/">mil.ru</a></div>
</div>
<div class="container">
<div class="container-inside">
<div class="list-group lk-what">
<div>
<div class="title short-text"><a href="/">Личный кабинет</a> для ведения воинского учета в организациях</div>
<div class="paragraph">
<div class="paragraph-left">
<div class="text icon-checklist">Кому доступен личный кабинет?</div>
<div class="short-text">Организациям, за ĸоторыми заĸреплена обязанность по осуществлению воинсĸого учета в соответствии с <a href="https://www.consultant.ru/document/cons_doc_LAW_18260/">ФЗ от 28.03.1998 No 53-ФЗ</a></div>
</div>
<div class="paragraph-right">
<div class="text icon-clock">Для чего нужен личный кабинет?</div>
<div class="short-text">Для своевременной и оперативной передачи сведений в военĸоматы в элеĸтронном виде</div>
</div>
</div>
</div>
</div>
<div class="list-group lk-access">
<div class="paragraph">
<div class="paragraph-left">
<div class="subtitle short-text">Как получить доступ к Личному кабинету?</div>
</div>
<div class="paragraph-right">
<div class="list">
<div class="esia short-text">Необходимо авторизоваться</div>
<div class="case short-text">Потребуется подтвержденная учетная запись организации</div>
<div class="user short-text">Доступ предоставляется тольĸо сотрудниĸу, наделенному соответствующими полномочиями (ролью) на ведения воинсĸого учета внутри организации</div>
</div>
<div class="btn-group">
<a href="/" class="btn">Войти в Личный кабинет</a>
</div>
</div>
</div>
</div>
<div class="list-group lk-info">
<div class="subtitle">Какие виды сведений доступны для отправки?</div>
<div class="paragraph">
<div class="paragraph-left">
<div class="section-group">
<div class="icon-case">
Сведения о приеме на работу (увольнении), зачислении в образовательную организацию (отчислении)
<div class="muted">Срок передачи сведений: <span class="detailed">до 5 дней</span></div>
</div>
<div class="icon-shield">
Изменения сведений сотрудников, необходимых для ведения воинского учета
<div class="muted">Срок передачи сведений: <span class="detailed">до 5 дней</span></div>
</div>
<div class="icon-clip">
Сообщение о гражданах, не состоящих, но обязанных состоять на воинском учете
<div class="muted">Срок передачи сведений: <span class="detailed">до 3 дней</span></div>
</div>
</div>
</div>
<div class="paragraph-right">
<div class="section-group">
<div class="icon-pers">
Ежегодное предоставление списка граждан мужского пола, подлежащих первоначальной постановке на воинский учет в год достижения ими возраста 17 лет
<div class="muted">Срок передачи сведений: <span class="detailed">ежегодно, в срок до 1 ноября</span></div>
</div>
<div class="icon-building">
Ежегодное предоставление списка сотрудников/обучающихся в организации, подлежащих воинскому учету
<div class="muted">Срок передачи сведений: <span class="detailed">ежегодно, по согласованию с военкоматом</span></div>
</div>
</div>
</div>
</div>
</div>
<div class="list-group lk-pass">
<div class="subtitle">Как передавать сведения?</div>
<div class="pass-list">
<div>Подготовьте файл-excel с данными в соответствии с форматом</div>
<div>Убедитесь, что все данные в файле введены ĸорреĸтно</div>
<div>Войдите в личный ĸабинет организации через Госуслуги</div>
<div>Выберите необходимый вид сведения и загрузите файл</div>
<div>Следите за статусом приема</div>
</div>
</div>
<div class="list-group lk-msg">
<div class="msg-list">
<span class="info"></span>Если в файле будут ошибĸи, данные не будут приняты Реестром и выгрузĸу сведений придется повторить
</div>
</div>
<div class="list-group lk-docs">
<div class="subtitle">Формы документов для заполнения</div>
<div class="docs-list">
<div><a href="#"></a>Приложение №2</div>
<div><a href="#"></a>Приложение №9</div>
<div><a href="#"></a>Приложение №10</div>
<div><a href="#"></a>Приложение №11</div>
<div><a href="#"></a>Приложение №12</div>
</div>
</div>
</div>
</div>
</body>
</html>

View file

@ -70,6 +70,7 @@
<include>doc/**/*</include>
<include>node_modules/**/*</include>
<include>index.html</include>
<include>home.html</include>
<include>systemjs.config.js</include>
</includes>
</resource>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Before After
Before After

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,717 @@
@font-face {
font-family: 'InterL';
src: url('fonts/Inter-Light.otf');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Inter';
src: url('fonts/Inter-Regular.otf');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'InterM';
src: url('fonts/Inter-Medium.otf');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'InterSB';
src: url('fonts/Inter-SemiBold.otf');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'InterB';
src: url('fonts/Inter-Bold.otf');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Golos';
src: url('fonts/GolosText-Regular.ttf');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'GolosM';
src: url('fonts/GolosText-Medium.ttf');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'GolosDB';
src: url('fonts/GolosText-DemiBold.ttf');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'GolosB';
src: url('fonts/GolosText-Bold.ttf');
font-weight: 400;
font-style: normal;
}
:root {
--white: #ffffff;
--black: #000000;
--color-text-primary: #1d1e21;
--color-text-secondary: #acacac;
--color-link: #c64e1b;
--color-link-hover: #fa773f;
--color-form: #3f434b;
--color-bg-main: #223d36;
--color-light: #868b87;
--bg-light: #fafafa;
--bg-warn: #ffdcc6;
--bg-form: #eee;
--border-light: #d2d2d2;
--bg-shadow: 0 19px 19px 0 rgba(230, 230, 230, 0.19), 0 1px 4px 0 #f3f3f3;
--h-header: 64px;
--w-screen: 100px;
--size-text-maintitle: 54px;
--size-text-title: 40px;
--size-text-subtitle: 32px;
--size-text-primary: 20px;
--size-text-secondary: 16px;
--indent-huge: 72px;
--indent-big: 52px;
--indent-medium: 32px;
--indent-small: 24px;
--indent-mini: 16px;
}
body, html {
height: 100%
}
body {
-ms-text-size-adjust: 100%;
-moz-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
display: flex;
flex-direction: column;
padding: 0;
margin: 0;
}
a {
color: var(--color-link);
text-decoration: none;
}
a:is(:hover, :focus, :active) {
color: var(--color-link-hover);
}
button, a.btn {
display: flex;
justify-content: center;
align-items: center;
color: var(--white);
font-family: 'InterL';
font-size: var(--size-text-secondary);
padding: 0 24px;
height: 48px;
border: 1px solid transparent;
border-radius: 4px;
background: var(--color-link);
}
button:is(:hover, :focus, :active),
a.btn:is(:hover, :focus, :active) {
background: var(--color-link-hover);
cursor: pointer;
}
.btn.btn-secondary {
color: var(--color-link);
border-color: var(--color-link);
background-color: transparent;
}
.btn.btn-secondary:is(:hover, :focus, :active) {
color: var(--color-link-hover);
border-color: var(--color-link-hover);
background: transparent;
}
.header {
display: flex;
flex-direction: row;
align-items: center;
font-family: 'InterSB';
min-height: var(--h-header);
padding: 0 var(--w-screen);
border: 0;
background-color: var(--color-bg-main);
}
.header .header-logo {
width: 62px;
height: 40px;
background: url(img/svg/mil-logo.svg) no-repeat 0 50%;
}
.header .header-title {
color: var(--white);
font-size: var(--size-text-secondary);
margin-left: var(--indent-mini);
}
:is(.ul, .fl) .header {
background-color: var(--color-text-primary);
z-index: 1;
}
.container {
width: 100%;
max-width: 100%;
height: auto;
margin: 0;
padding: var(--h-header) 0 0;
position: absolute;
top: 0px;
left: 0;
right: 0;
bottom: 0;
border: 0;
overflow: hidden;
}
.container-inside {
display: flex;
flex-direction: column;
height: 100%;
color: var(--color-text-primary);
font-family: 'Inter';
padding: 0 var(--w-screen);
background-color: var(--bg-light);
overflow: auto;
}
.container-inside .short-text {
max-width: 60%;
}
.container-inside .paragraph-left .short-text {
max-width: 70%;
}
.container-inside .block-group {
display: flex;
flex-direction: row;
margin: auto;
}
.container-inside .block {
font-family: 'Inter';
min-width: 355px;
padding: 40px;
border-radius: 12px;
background-color: var(--white);
box-shadow: var(--bg-shadow);
}
.container-inside .block > div {
max-width: 350px;
}
.container-inside .block + .block {
margin-left: 40px;
}
.container-inside .block .block-img {
width: 100px;
height: 100px;
}
.container-inside .block.block-ul .block-img {
background-image: url(img/svg/ul.svg);
}
.container-inside .block.block-fl .block-img {
background-image: url(img/svg/fl.svg);
}
.container-inside .block .block-title {
font-family: 'GolosB';
font-size: var(--size-text-subtitle);
margin-top: var(--indent-mini);
}
.container-inside .block .block-description {
font-family: 'Golos';
font-size: var(--size-text-primary);
margin-top: var(--indent-mini);
}
.container-inside .block .btn {
width: auto;
margin-top: var(--indent-medium);
}
:is(.ul, .fl) .container-inside {
padding: 0;
background-color: var(--white);
}
:is(.ul, .fl) .container-inside .btn-group {
display: flex;
flex-direction: row;
}
:is(.ul, .fl) .container-inside .btn-group .btn + .btn {
margin-left: var(--indent-mini);
}
:is(.ul, .fl) .container-inside .list-group {
position: relative;
padding: 0 var(--w-screen);
}
:is(.ul, .fl) .container-inside .list-group .btn {
width: max-content;
}
:is(.ul, .fl) .container-inside .list-group .title {
font-size: var(--size-text-maintitle);
font-family: 'GolosB';
margin-bottom: var(--indent-huge);
}
:is(.ul, .fl) .container-inside .list-group .subtitle {
font-size: var(--size-text-title);
font-family: 'GolosDB';
margin-bottom: var(--indent-big);
}
:is(.ul, .fl) .container-inside .list-group .muted {
color: var(--color-light);
}
:is(.ul, .fl) .container-inside .list-group .paragraph {
display: flex;
flex-direction: row;
}
:is(.ul, .fl) .container-inside .list-group .paragraph .paragraph-left {
width: 40%;
}
:is(.ul, .fl) .container-inside .list-group .paragraph .paragraph-right {
width: 60%;
}
:is(.ul, .fl) .container-inside .list-group .paragraph .paragraph-half {
width: 50%;
}
:is(.ul, .fl) .container-inside .list-group .paragraph .paragraph-third {
width: 33.33%;
}
:is(.ul, .fl) .container-inside .list-group .paragraph [class*="paragraph-"] + [class*="paragraph-"] {
margin-left: 40px;
}
:is(.ul, .fl) .container-inside .list-group .paragraph .text {
font-family: 'InterSB';
font-size: var(--size-text-primary);
margin-bottom: var(--indent-mini);
}
:is(.ul, .fl) .container-inside .list-group .paragraph .icon-checklist,
:is(.ul, .fl) .container-inside .list-group .paragraph .icon-clock,
:is(.ul, .fl) .container-inside .list-group .paragraph .icon-text {
padding-top: 44px;
}
:is(.ul, .fl) .container-inside .list-group .paragraph .icon-checklist {
background: url(img/svg/checklist-32x32.svg) no-repeat 0 0;
}
:is(.ul, .fl) .container-inside .list-group .paragraph .icon-clock {
background: url(img/svg/clock-32x32.svg) no-repeat 0 0;
}
:is(.ul, .fl) .container-inside .list-group .paragraph .icon-text {
background: url(img/svg/text-32x32.svg) no-repeat 0 0;
}
:is(.ul, .fl) .container-inside .list-group .list > div {
position: relative;
padding-left: 36px;
}
:is(.ul, .fl) .container-inside .list-group .list > div + div {
margin-top: var(--indent-mini);
}
:is(.ul, .fl) .container-inside .list-group .list > div::after {
content: "";
position: absolute;
width: 24px;
height: 24px;
top: 0;
left: 0;
}
:is(.ul, .fl) .container-inside .list-group .list > div.esia::after {
background: url(img/svg/esia-24x24.svg) no-repeat 0 0;
}
:is(.ul, .fl) .container-inside .list-group .list > div.case::after {
background: url(img/svg/case-24x24.svg) no-repeat 0 0;
}
:is(.ul, .fl) .container-inside .list-group .list > div.user::after {
background: url(img/svg/user-24x24.svg) no-repeat 0 0;
}
:is(.ul, .fl) .container-inside .list-group .list > div.romb::after {
background: url(img/svg/romb-24x24.svg) no-repeat 0 0;
}
:is(.ul, .fl) .container-inside .list-group .list ~ .btn-group {
margin-top: var(--indent-medium);
}
:is(.ul, .fl) .container-inside .list-group .section-group > div {
display: flex;
flex-direction: column;
min-height: 48px;
position: relative;
padding: 16px 16px 16px 76px;
margin-bottom: 16px;
border-radius: 4px;
background-color: var(--bg-form);
}
:is(.ul, .fl) .container-inside .list-group .section-group > div:last-child {
margin-bottom: 0;
}
:is(.ul, .fl) .container-inside .list-group .section-group > div::before {
content: "";
position: absolute;
left: 16px;
width: 48px;
height: 48px;
border-radius: 50px;
background-color: var(--color-bg-main);
background-repeat: no-repeat;
background-position: 50% 50%;
}
:is(.ul, .fl) .container-inside .list-group .section-group > div.icon-user::before {
background-image: url(img/svg/pers-wt.svg);
}
:is(.ul, .fl) .container-inside .list-group .section-group > div.icon-case::before {
background-image: url(img/svg/case-wt.svg);
}
:is(.ul, .fl) .container-inside .list-group .section-group > div.icon-shield::before {
background-image: url(img/svg/shield-wt.svg);
}
:is(.ul, .fl) .container-inside .list-group .section-group > div.icon-clip::before {
background-image: url(img/svg/clip-wt.svg);
}
:is(.ul, .fl) .container-inside .list-group .section-group > div.icon-pers::before {
background-image: url(img/svg/pers-wt.svg);
}
:is(.ul, .fl) .container-inside .list-group .section-group > div.icon-building::before {
background-image: url(img/svg/building-wt.svg);
}
:is(.ul, .fl) .container-inside .list-group .section-group > div .muted {
margin-top: 12px;
}
:is(.ul, .fl) .container-inside .list-group .section-group > div .muted .detailed {
color: var(--color-text-primary);
font-family: 'InterB';
}
:is(.ul, .fl) .container-inside .list-group .pass-list {
position: relative;
display: flex;
flex-direction: row;
padding-top: 60px;
}
:is(.ul, .fl) .container-inside .list-group .pass-list::before {
content: "";
position: absolute;
width: calc(80% + 40px);
height: 4px;
top: 18px;
left: 0;
background-color: var(--color-link-hover);
}
:is(.ul, .fl) .container-inside .list-group .pass-list > div {
position: relative;
width: 20%;
}
:is(.ul, .fl) .container-inside .list-group .pass-list > div::before {
content: "";
position: absolute;
width: 32px;
height: 32px;
top: -60px;
left: 0;
border-radius: 2px;
border: 4px solid var(--color-link-hover);
background-color: var(--bg-light);
transform: rotate(45deg);
}
:is(.ul, .fl) .container-inside .list-group .pass-list > div::after {
content: "";
position: absolute;
font-family: 'InterB';
top: -50px;
left: 15px;
}
:is(.ul, .fl) .container-inside .list-group .pass-list > div:nth-child(1)::after {
content: "1";
}
:is(.ul, .fl) .container-inside .list-group .pass-list > div:nth-child(2)::after {
content: "2";
}
:is(.ul, .fl) .container-inside .list-group .pass-list > div:nth-child(3)::after {
content: "3";
}
:is(.ul, .fl) .container-inside .list-group .pass-list > div:nth-child(4)::after {
content: "4";
}
:is(.ul, .fl) .container-inside .list-group .pass-list > div:nth-child(5)::after {
content: "5";
}
:is(.ul, .fl) .container-inside .list-group .pass-list > div + div {
margin-left: 40px;
}
:is(.ul, .fl) .container-inside .list-group .msg-list {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 8px;
}
:is(.ul, .fl) .container-inside .list-group .msg-list span {
width: 32px;
height: 32px;
padding-right: 16px;
background: url(img/svg/info-gr.svg) no-repeat 0 0;
}
:is(.ul, .fl) .container-inside .list-group .docs-list {
position: relative;
display: flex;
flex-direction: row;
}
:is(.ul, .fl) .container-inside .list-group .docs-list > div {
position: relative;
display: flex;
flex-direction: row;
align-items: center;
width: 20%;
}
:is(.ul, .fl) .container-inside .list-group .docs-list > div a {
width: 24px;
height: 24px;
padding-right: 8px;
background: url(img/svg/download-24x24.svg) no-repeat 0 0;
}
:is(.ul, .fl) .container-inside .list-group .docs-list > div + div {
margin-left: 40px;
}
:is(.ul, .fl) .container-inside .list-group.lk-what {
padding-top: var(--indent-huge);
padding-bottom: var(--indent-huge);
}
:is(.ul, .fl) .container-inside .list-group.lk-what::after {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 0.12;
background: url(img/svg/bg-star.svg) no-repeat calc(100% + 200px) -180px transparent;
z-index: 0;
}
:is(.ul, .fl) .container-inside .list-group.lk-what > div {
position: relative;
z-index: 1;
}
:is(.ul, .fl) .container-inside .list-group.lk-access {
color: var(--white);
padding-top: var(--indent-big);
padding-bottom: var(--indent-big);
background-color: var(--color-bg-main);
}
:is(.ul, .fl) .container-inside .list-group.lk-info {
padding-top: var(--indent-big);
padding-bottom: var(--indent-big);
}
:is(.ul, .fl) .container-inside .list-group.lk-pass {
padding-top: var(--indent-big);
padding-bottom: var(--indent-big);
background-color: var(--bg-light);
}
:is(.ul, .fl) .container-inside .list-group.lk-when {
color: var(--white);
padding-top: var(--indent-big);
padding-bottom: var(--indent-big);
background-color: var(--color-bg-main);
}
:is(.ul, .fl) .container-inside .list-group.lk-msg {
background-color: var(--border-light);
}
:is(.ul, .fl) .container-inside .list-group.lk-limits {
padding-top: var(--indent-big);
padding-bottom: var(--indent-big);
}
:is(.ul, .fl) .container-inside .list-group.lk-docs {
flex: 1;
color: var(--white);
padding-top: var(--indent-huge);
padding-bottom: var(--indent-huge);
background-color: var(--color-text-primary);
}
:is(.ul, .fl) .container-inside .list-group.lk-alert {
padding-top: var(--indent-big);
padding-bottom: var(--indent-big);
background-color: var(--bg-light);
}
:is(.ul, .fl) .container-inside .list-group.lk-footer {
padding-top: var(--indent-small);
padding-bottom: var(--indent-small);
background-color: var(--color-text-primary);
}
:is(.fl) .container-inside .list-group.lk-what .title {
color: var(--color-link);
margin-bottom: var(--indent-small);
}
:is(.fl) .container-inside .list-group.lk-what .title::after {
content: url(img/svg/star.svg);
top: 18px;
position: relative;
margin-left: var(--indent-big);
}
:is(.fl) .container-inside .list-group.lk-what .title + .short-text {
max-width: 25%;
}
:is(.fl) .container-inside .list-group.lk-what .title ~ .subtitle {
margin-top: var(--indent-big);
}
:is(.fl) .container-inside .list-group.lk-info .section-group > div {
justify-content: center;
}
:is(.fl) .container-inside .list-group.lk-pass .subtitle {
margin-bottom: 0;
}
:is(.fl) .container-inside .list-group.lk-pass .subtitle + div {
margin-top: var(--indent-small);
margin-bottom: var(--indent-big);
}
:is(.fl) .container-inside .list-group.lk-pass .pass-list::before {
display: none;
}
:is(.fl) .container-inside .list-group.lk-pass .pass-list > div {
position: relative;
width: 33.33%;
}
:is(.fl) .container-inside .list-group.lk-msg {
color: var(--color-link);
font-family: 'InterSB';
background-color: var(--bg-form);
}
:is(.fl) .container-inside .list-group.lk-msg span {
background: url(img/svg/info.svg) no-repeat 0 4px;
}
:is(.fl) .container-inside .list-group.lk-limits .subtitle {
margin-bottom: 0;
}
:is(.fl) .container-inside .list-group.lk-limits .subtitle + div {
margin-top: var(--indent-small);
margin-bottom: var(--indent-big);
}
:is(.fl) .container-inside .list-group.lk-limits .scheme {
width: 100%;
height: 204px;
background: url(img/svg/scheme.svg) no-repeat 0 0;
}
:is(.fl) .container-inside .list-group.lk-alert > .short-text {
margin-bottom: var(--indent-big);
}
:is(.fl) .container-inside .list-group.lk-alert .alert-block {
position: relative;
padding: var(--indent-small) 64px var(--indent-small) var(--indent-small);
border-radius: 4px;
border: 2px solid var(--border-light);
}
:is(.fl) .container-inside .list-group.lk-alert .alert-block::after {
content: url(img/svg/info.svg);
position: absolute;
top: var(--indent-small);
right: var(--indent-small);
}
:is(.fl) .container-inside .list-group.lk-alert .alert-block > div + div {
margin-top: var(--indent-small);
}
:is(.fl) .container-inside .list-group.lk-alert .alert-block > div:last-child {
color: var(--color-link);
}
/*@media ((max-width: 780px) or ((orientation: landscape) and (max-device-width : 1024px))) {*/
@media (max-width: 1024px) {
body {
--w-screen: 32px;
--size-text-maintitle: 32px;
--size-text-title: 28px;
--size-text-subtitle: 24px;
--indent-huge: 32px;
--indent-big: 24px;
--indent-medium: 24px;
--indent-small: 16px;
}
.container-inside .short-text {
max-width: 100% !important;
}
.container-inside .block-group {
flex-direction: column;
margin: 0;
}
.container-inside .block-group .block {
min-width: auto;
margin: var(--indent-huge) 0 0;
}
.container-inside .block-group .block > div {
max-width: inherit !important;
}
:is(.ul, .fl) .container-inside .list-group .paragraph {
flex-direction: column;
}
:is(.ul, .fl) .container-inside .list-group .paragraph [class*="paragraph-"] {
width: auto;
margin-left: 0;
}
:is(.ul, .fl) .container-inside .list-group .paragraph [class*="paragraph-"] + [class*="paragraph-"] {
margin-top: var(--indent-mini);
margin-left: 0;
}
:is(.ul, .fl) .container-inside .list-group .pass-list {
flex-direction: column;
padding-top: 0;
}
:is(.ul, .fl) .container-inside .list-group .pass-list::before {
display: none;
}
:is(.ul, .fl) .container-inside .list-group .pass-list > div {
display: flex;
align-items: center;
width: auto !important;
padding-left: 60px;
min-height: 40px;
}
:is(.ul, .fl) .container-inside .list-group .pass-list > div::before {
top: 0;
}
:is(.ul, .fl) .container-inside .list-group .pass-list > div::after {
top: 10px;
}
:is(.ul, .fl) .container-inside .list-group .pass-list > div + div {
margin-left: 0;
margin-top: var(--indent-mini);
}
}
@media (max-width: 480px) {
body {
--w-screen: 16px;
--size-text-maintitle: 28px;
--size-text-title: 24px;
--size-text-subtitle: 20px;
--indent-huge: 24px;
--indent-big: 24px;
--indent-medium: 16px;
--indent-small: 16px;
}
:is(.ul, .fl) .container-inside .list-group .docs-list {
flex-direction: column;
}
:is(.ul, .fl) .container-inside .list-group .docs-list > div {
width: 100%;
}
:is(.ul, .fl) .container-inside .list-group .docs-list > div + div {
margin-left: 0;
margin-top: var(--indent-mini);
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 2.8 MiB

View file

@ -0,0 +1,8 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.26814 12.0027H4.24414C3.41571 12.0027 2.74414 12.6743 2.74414 13.5027L2.74414 21.2559H8.26814" stroke="white" stroke-width="1.5" stroke-linejoin="round"/>
<path d="M8.26758 4.25158L8.26758 21.2549H21.2676V4.25158C21.2676 3.42315 20.596 2.75158 19.7676 2.75158H9.76758C8.93915 2.75158 8.26758 3.42315 8.26758 4.25158Z" stroke="white" stroke-width="1.5" stroke-linejoin="round"/>
<path d="M12.3672 9.55371V8.05371" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
<path d="M17.168 8.05371V9.55371" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
<path d="M12.3672 15.9541V14.4541" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
<path d="M17.168 14.4541V15.9541" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 867 B

View file

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.7158 3C9.35852 3 8.20421 3.9903 7.99782 5.33184L7.89503 6H4C2.89543 6 2 6.89543 2 8V18C2 19.6569 3.34315 21 5 21H19C20.6569 21 22 19.6569 22 18V8C22 6.89543 21.1046 6 20 6H16.105L16.0022 5.33184C15.7958 3.99031 14.6415 3 13.2842 3H10.7158ZM14.5873 6L14.5196 5.55993C14.4258 4.95014 13.9011 4.5 13.2842 4.5H10.7158C10.0989 4.5 9.57419 4.95014 9.48038 5.55993L9.41268 6H14.5873ZM4 7.5H20C20.2761 7.5 20.5 7.72386 20.5 8V10.9297C18.8456 11.9818 16.9613 12.684 15 13.0362V13C15 11.8954 14.1046 11 13 11H11C9.89543 11 9 11.8954 9 13V13.0362C7.03871 12.684 5.1544 11.9818 3.5 10.9297V8C3.5 7.72386 3.72386 7.5 4 7.5ZM9 14.5582C7.06675 14.2404 5.19401 13.6122 3.5 12.6736V18C3.5 18.8284 4.17157 19.5 5 19.5H19C19.8284 19.5 20.5 18.8284 20.5 18V12.6736C18.806 13.6122 16.9332 14.2404 15 14.5582V15C15 16.1046 14.1046 17 13 17H11C9.89543 17 9 16.1046 9 15V14.5582ZM11 12.5H13C13.2761 12.5 13.5 12.7239 13.5 13V15C13.5 15.2761 13.2761 15.5 13 15.5H11C10.7239 15.5 10.5 15.2761 10.5 15V13C10.5 12.7239 10.7239 12.5 11 12.5Z" fill="#FA773F"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.7158 3C9.35852 3 8.20421 3.9903 7.99782 5.33184L7.89503 6H4C2.89543 6 2 6.89543 2 8V18C2 19.6569 3.34315 21 5 21H19C20.6569 21 22 19.6569 22 18V8C22 6.89543 21.1046 6 20 6H16.105L16.0022 5.33184C15.7958 3.99031 14.6415 3 13.2842 3H10.7158ZM14.5873 6L14.5196 5.55993C14.4258 4.95014 13.9011 4.5 13.2842 4.5H10.7158C10.0989 4.5 9.57419 4.95014 9.48038 5.55993L9.41268 6H14.5873ZM4 7.5H20C20.2761 7.5 20.5 7.72386 20.5 8V10.9297C18.8456 11.9818 16.9613 12.684 15 13.0362V13C15 11.8954 14.1046 11 13 11H11C9.89543 11 9 11.8954 9 13V13.0362C7.03871 12.684 5.1544 11.9818 3.5 10.9297V8C3.5 7.72386 3.72386 7.5 4 7.5ZM9 14.5582C7.06675 14.2404 5.19401 13.6122 3.5 12.6736V18C3.5 18.8284 4.17157 19.5 5 19.5H19C19.8284 19.5 20.5 18.8284 20.5 18V12.6736C18.806 13.6122 16.9332 14.2404 15 14.5582V15C15 16.1046 14.1046 17 13 17H11C9.89543 17 9 16.1046 9 15V14.5582ZM11 12.5H13C13.2761 12.5 13.5 12.7239 13.5 13V15C13.5 15.2761 13.2761 15.5 13 15.5H11C10.7239 15.5 10.5 15.2761 10.5 15V13C10.5 12.7239 10.7239 12.5 11 12.5Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,4 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4 8C4 5.79086 5.79086 4 8 4H24C26.2091 4 28 5.79086 28 8V24C28 26.2091 26.2091 28 24 28H8C5.79086 28 4 26.2091 4 24V8Z" fill="#C64E1B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.0103 17.6088L10.57 12.1602L9.50989 13.2213L15.4802 19.2008C15.6207 19.3416 15.8114 19.4207 16.0102 19.4207C16.209 19.4207 16.3996 19.3417 16.5402 19.2009L30.4835 5.24004L29.4235 4.17871L16.0103 17.6088Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 522 B

View file

@ -0,0 +1,7 @@
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18.4938 17.7404L18.4938 12.3538C18.4938 11.636 17.9119 11.0541 17.1941 11.0542C16.4783 11.0542 15.8973 11.633 15.8945 12.3488L15.8757 18.0897C15.8701 19.5264 17.0283 20.6967 18.465 20.706C19.911 20.7154 21.0882 19.5458 21.0882 18.0998L21.0882 13.935" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
<path d="M18.4766 7.7563V2.46671C18.4766 1.91442 18.0288 1.46671 17.4766 1.46671H5.35156C4.79928 1.46671 4.35156 1.91443 4.35156 2.46671V18.0459H11.4141" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8.96094 11.335L8.96094 13.3369" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M13.8672 5.21777L13.8672 7.21973" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8.96094 5.21777L8.96094 7.21973" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -0,0 +1,4 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="15.9993" cy="15.9993" r="13.3333" fill="#C64E1B"/>
<path d="M16 9.375V15.8319C16 16.3666 16.2141 16.879 16.5945 17.2548L19.3333 19.9601" stroke="white" stroke-width="1.5"/>
</svg>

After

Width:  |  Height:  |  Size: 288 B

View file

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 5.5H11V4H7C5.34315 4 4 5.34315 4 7V17C4 18.6569 5.34315 20 7 20H17C18.6569 20 20 18.6569 20 17V13H18.5V17C18.5 17.8284 17.8284 18.5 17 18.5H7C6.17157 18.5 5.5 17.8284 5.5 17V7C5.5 6.17157 6.17157 5.5 7 5.5ZM15 5.5L17.4394 5.5L8.96967 13.9697L10.0303 15.0303L18.5001 6.56066V9.00001H20.0001V4.75C20.0001 4.33579 19.6643 4.00001 19.2501 4L15 4L15 5.5Z" fill="#FA773F"/>
</svg>

After

Width:  |  Height:  |  Size: 523 B

View file

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.44531 9.5C3.0311 9.5 2.69531 9.83579 2.69531 10.25C2.69531 10.6642 3.0311 11 3.44531 11H9.83731C10.2515 11 10.5873 10.6642 10.5873 10.25C10.5873 9.83579 10.2515 9.5 9.83731 9.5H3.44531ZM3.44531 13C3.0311 13 2.69531 13.3358 2.69531 13.75C2.69531 14.1642 3.0311 14.5 3.44531 14.5H15.4853C15.8995 14.5 16.2353 14.1642 16.2353 13.75C16.2353 13.3358 15.8995 13 15.4853 13H3.44531Z" fill="#FA773F"/>
<path d="M3.72852 16.9899C4.03952 17.3879 4.42752 17.7289 4.87852 17.9889L9.99952 20.9489C11.2375 21.6639 12.7615 21.6639 13.9995 20.9489L18.7495 18.2069C19.9875 17.4919 20.7495 16.1719 20.7495 14.7429V9.25788C20.7495 7.82888 19.9875 6.50788 18.7495 5.79388L13.9995 3.05188C12.7615 2.33688 11.2375 2.33688 9.99952 3.05188L4.87852 6.01188C4.42752 6.27288 4.03952 6.61387 3.72852 7.01088" stroke="#FA773F" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1,021 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.6 MiB

View file

@ -0,0 +1,4 @@
<svg width="33" height="33" viewBox="0 0 33 33" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle opacity="0.1" cx="16.5" cy="16.9495" r="12.8333" fill="black" stroke="black" stroke-linejoin="round"/>
<path d="M15.212 13.0138H17.788V10.5498H15.212V13.0138ZM15.324 14.9498V23.6165H17.676V14.9498H15.324Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 332 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 464 KiB

View file

@ -0,0 +1,3 @@
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.3627 3.88944C16.6803 3.88466 18.0641 4.55448 18.894 5.83335C19.7349 7.12922 19.9475 8.94322 19.152 11.1454C19.4509 11.3622 19.6741 11.6343 19.8331 11.9118C20.0961 12.3708 20.2005 12.87 20.2005 13.2484C20.2005 14.3912 19.466 15.705 18.2185 16.2708C16.4506 22.592 7.17108 22.7528 5.53967 16.1546C4.44756 15.5333 3.81445 14.3157 3.81445 13.2494C3.81445 12.7381 4.02849 11.8265 4.74947 11.237C4.48716 10.4063 4.35645 9.60421 4.35645 8.84336C4.35645 5.52209 6.47963 3.54106 8.89442 2.80599C11.1168 2.12949 13.7657 2.45649 15.3627 3.88944ZM16.8357 15.6264C16.8452 15.5408 16.8693 15.4581 16.9063 15.3818C17.0148 15.14 17.2437 14.975 17.5029 14.9445C18.2327 14.6655 18.7005 13.8776 18.7005 13.2484C18.7005 13.1137 18.6558 12.8744 18.5315 12.6574C18.4159 12.4555 18.2495 12.3002 17.9999 12.2313C17.7901 12.1734 17.6158 12.0272 17.5222 11.8307C17.4287 11.6341 17.4252 11.4066 17.5125 11.2073C18.4656 9.03295 18.2139 7.54095 17.6357 6.64987C17.04 5.73184 16.0199 5.31359 15.149 5.40064C14.9183 5.42371 14.6898 5.33872 14.5303 5.17045C13.4808 4.06385 11.3178 3.63628 9.33123 4.24098C7.41377 4.82466 5.85645 6.31263 5.85645 8.84336C5.85645 9.57304 6.01197 10.3955 6.35928 11.2966C6.50813 11.6829 6.31595 12.1167 5.92987 12.2659C5.71638 12.3484 5.56663 12.5029 5.46252 12.6997C5.35272 12.9073 5.31445 13.1263 5.31445 13.2494C5.31445 13.8568 5.74932 14.6306 6.44148 14.9307C6.6208 14.9938 6.77268 15.1238 6.86109 15.2967C6.89847 15.3693 6.92397 15.4477 6.93624 15.5289C8.01723 20.8672 15.5973 20.9003 16.8357 15.6264ZM16.0663 9.13749C16.3009 8.79606 16.2142 8.32916 15.8728 8.09464C15.5314 7.86011 15.0645 7.94677 14.8299 8.28819C13.4432 10.307 10.6719 11.1742 8.36184 10.3842C7.96991 10.2502 7.54353 10.4592 7.40949 10.8511C7.27546 11.2431 7.48452 11.6694 7.87645 11.8035C10.8004 12.8035 14.285 11.7307 16.0663 9.13749Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.5 8.83007H18.5L18.5 8.83999L18.5003 8.92876C18.5003 9.96687 18.3814 10.964 18.1609 11.9049L5.5 7.38315V4.75529C7.4809 5.16366 9.6853 5.38884 11.9996 5.38884C14.3142 5.38884 16.5189 5.16359 18.5 4.75511V8.83007ZM5.50008 8.97597C5.50178 9.46487 5.52987 9.9446 5.58252 10.4136L17.1884 14.5917C17.39 14.1925 17.5713 13.776 17.7301 13.3439L5.50008 8.97597ZM16.4097 15.9056L5.89162 12.1191C6.79191 15.6777 9.15187 18.4007 12.0002 19.4431C13.719 18.814 15.26 17.573 16.4097 15.9056ZM4.64183 3.01773C4.31938 2.93469 4 3.17475 4 3.50772V8.92791V8.92876C4 14.6869 7.32873 19.5349 11.8562 20.9789C11.9498 21.0088 12.0505 21.0088 12.1441 20.9789C16.6716 19.5349 20.0003 14.6869 20.0003 8.92876C20.0003 8.89583 20.0002 8.86294 20 8.83007V3.5075C20 3.17452 19.6806 2.93446 19.3581 3.01752C17.2113 3.57052 14.6929 3.88884 11.9996 3.88884C9.30662 3.88884 6.78849 3.5706 4.64183 3.01773Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.6 MiB

View file

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.76172 20.9419C4.76172 18.9559 5.58268 17.1559 6.90161 15.8529C7.56958 15.1929 8.36654 14.6609 9.24849 14.2969L11.9974 16.4647L14.7462 14.2969C15.6292 14.6609 16.4251 15.1929 17.0931 15.8529C18.412 17.1559 19.233 18.9559 19.233 20.9419" stroke="#FA773F" stroke-width="1.49996" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M15.2375 6.87359C15.2375 9.33359 13.6176 10.5636 11.9976 10.5636C10.3777 10.5636 8.75781 9.33359 8.75781 6.87359C8.75781 4.41359 10.3777 3.18359 11.9976 3.18359C13.6176 3.18359 15.2375 4.42359 15.2375 6.87359Z" stroke="#FA773F" stroke-width="1.49996" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 749 B

View file

@ -0,0 +1,9 @@
<div>
<button type="button"
[disabled]="!isEnabled()"
class="btn btn-secondary"
[ngbTooltip]="tooltip | emptyIfNull"
(click)="onClick()"
(focus)="onFocus()"
(blur)="onBlur()">{{caption}}</button>
</div>

View file

@ -0,0 +1,43 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef} from "@angular/core";
import {AbstractButton, NotNull} from "@webbpm/base-package";
import {HttpClient} from "@angular/common/http";
/**
* @author: Eduard Tihomirov
*/
@Component({
moduleId: module.id,
selector: 'ervu-download-file-button',
templateUrl: "./../../../../../src/resources/template/ervu/component/button/Button.html",
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ErvuDownloadFileButton extends AbstractButton {
private httpClient: HttpClient;
@NotNull()
public fileName: string;
constructor(el: ElementRef, cd: ChangeDetectorRef) {
super(el, cd);
}
initialize() {
super.initialize();
this.httpClient = this.injector.get(HttpClient);
}
public doClickActions(): Promise<any> {
return this.httpClient.get('kafka/excerpt', {
responseType: 'blob'
}).toPromise().then((response) => {
const url = window.URL.createObjectURL(response);
const a = document.createElement('a');
a.href = url;
a.download = this.fileName;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
a.remove();
});
}
}

View file

@ -4,7 +4,8 @@ import {
Visible,
Event,
MessagesService,
UnsupportedOperationError
UnsupportedOperationError,
AppConfigService
} from "@webbpm/base-package";
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef} from "@angular/core";
import {FileItem, FileUploader} from "ng2-file-upload";
@ -18,6 +19,8 @@ import {EmployeeInfoFileFormType} from "./EmployeeInfoFileFormType";
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ErvuFileUpload extends InputControl {
private static readonly BACKEND_URL: string = "backend.context";
@NotNull("true")
public selectFileFieldText: string;
@NotNull("true")
@ -46,17 +49,16 @@ export class ErvuFileUpload extends InputControl {
public fileUploadEndEvent: Event<any> = new Event<any>();
@Visible("false")
public fileUploadFailedEvent: Event<any> = new Event<any>();
@Visible("false")
public isDropZoneVisible: boolean = true;
@Visible("false")
public isFilesListVisible: boolean = true;
@Visible("false")
public isProgressBarVisible: boolean = false;
private fileInputEl: HTMLInputElement;
private url: string = '/backend/employee/document';
private messagesService: MessagesService;
private isUploadErrorOccurred = false;
private appConfigService: AppConfigService;
constructor(el: ElementRef, cd: ChangeDetectorRef) {
super(el, cd);
@ -66,6 +68,8 @@ export class ErvuFileUpload extends InputControl {
initialize() {
super.initialize();
this.messagesService = this.injector.get(MessagesService);
this.appConfigService = this.injector.get(AppConfigService);
this.url = `/${this.appConfigService.getParamValue(ErvuFileUpload.BACKEND_URL)}/employee/document`;
this.uploader.setOptions({
url: this.url,

View file

@ -24,6 +24,7 @@ import {AppProgressIndicationService} from "./service/app-progress-indication.se
import {FileUploadModule} from "ng2-file-upload";
import {ErvuFileUpload} from "../../ervu/component/fileupload/ErvuFileUpload";
import {InMemoryStaticGrid} from "../../ervu/component/grid/InMemoryStaticGrid";
import {ErvuDownloadFileButton} from "../../ervu/component/button/ErvuDownloadFileButton";
registerLocaleData(localeRu);
export const DIRECTIVES = [
@ -34,6 +35,7 @@ export const DIRECTIVES = [
forwardRef(() => AccessDeniedComponent),
forwardRef(() => AppProgressIndicationComponent),
forwardRef(() => ErvuFileUpload),
forwardRef(() => ErvuDownloadFileButton),
forwardRef(() => InMemoryStaticGrid)
];

View file

@ -91,11 +91,13 @@ module.exports = {
}),
new CopyWebpackPlugin([
{from: 'index.webpack.html', to: 'index.html'},
{from: 'home.html', to: 'home.html'},
{from: 'src/resources/img/progress.gif', to: 'src/resources/img/progress.gif'},
{from: 'src/resources/img/logo.png', to: 'src/resources/img/logo.png'},
{from: 'src/resources/app-config.json', to: 'src/resources/app-config.json'},
{from: 'src/resources/app.version', to: 'src/resources/app.version'},
{from: 'doc', to: 'doc'},
{from: 'src/resources/app.version', to: 'src/resources/app.version'}
{from: 'src/resources/landing', to: 'src/resources/landing'}
]),
new MiniCssExtractPlugin({
filename: '[name].[hash].css',

View file

@ -9,7 +9,6 @@
<modules>
<module>backend</module>
<module>resources</module>
<module>test</module>
</modules>
<scm>
<connection>scm:git:git://gitserver/webbpm/webbpm-components.git</connection>
@ -367,6 +366,11 @@
<artifactId>log4j-web</artifactId>
<version>2.23.1</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>1.12.759</version>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>

View file

@ -638,76 +638,6 @@
</entry>
</properties>
</scripts>
<scripts id="1996166f-7922-4f28-a571-9646d956ef37">
<properties>
<entry>
<key>enableCellTextSelection</key>
<value>
<simple>null</simple>
</value>
</entry>
<entry>
<key>fetchSize</key>
<value>
<simple>20.0</simple>
</value>
</entry>
<entry>
<key>headerHeight</key>
<value>
<simple>40.0</simple>
</value>
</entry>
<entry>
<key>loadingOverlayMessage</key>
<value>
<simple>"Загрузка данных, пожалуйста, подождите."</simple>
</value>
</entry>
<entry>
<key>loadingOverlayType</key>
<value>
<simple>"PROGRESS_BAR"</simple>
</value>
</entry>
<entry>
<key>noRowsOverlayMessage</key>
<value>
<simple>"Данные отсутствуют"</simple>
</value>
</entry>
<entry>
<key>rowClickSelectionType</key>
<value>
<simple>"SINGLE_SELECT_CLICK"</simple>
</value>
</entry>
<entry>
<key>rowHeight</key>
<value>
<simple>40.0</simple>
</value>
</entry>
<entry>
<key>rowModelType</key>
<value>
<simple>"CLIENT_SIDE"</simple>
</value>
</entry>
<entry>
<key>showRowNumber</key>
<value>
<simple>null</simple>
</value>
</entry>
<entry>
<key>theme</key>
<value>
<simple>null</simple>
</value>
</entry>
</properties>
</scripts>
<scripts id="be8fe0e1-4909-4224-8664-be55168595c6"/>
<scripts id="f0a59cd9-acf8-4b1d-89fa-a5d618fc4664">
<classRef type="JAVA">
@ -1347,6 +1277,16 @@
<container>false</container>
<childrenReordered>false</childrenReordered>
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
<removed>true</removed>
<expanded>false</expanded>
</scripts>
<scripts id="38036714-7fff-4404-98d3-b0f5cc846368">
<classRef type="TS">
<className>ErvuDownloadFileButton</className>
<packageName>ervu.component.button</packageName>
</classRef>
<enabled>true</enabled>
<expanded>true</expanded>
<properties>
<entry>
<key>caption</key>
@ -1355,9 +1295,15 @@
</value>
</entry>
<entry>
<key>tooltip</key>
<key>fileName</key>
<value>
<simple>null</simple>
<simple>"Выписка"</simple>
</value>
</entry>
<entry>
<key>visible</key>
<value>
<simple>true</simple>
</value>
</entry>
</properties>

View file

@ -180,7 +180,6 @@
<componentRootId>3ed7cd92-3c7a-4d6f-a22c-1f3c4031bb61</componentRootId>
<name>VB - левый</name>
<container>true</container>
<expanded>false</expanded>
<childrenReordered>false</childrenReordered>
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
<properties>
@ -242,6 +241,7 @@
<componentRootId>ab77b5e7-503a-4bb9-ad3e-a6bec053a0b0</componentRootId>
<name>VB 1</name>
<container>true</container>
<expanded>false</expanded>
<childrenReordered>false</childrenReordered>
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
<properties>
@ -577,6 +577,7 @@
<componentRootId>9b24887e-d260-47f5-a2f9-47050ec1f9ed</componentRootId>
<name>VB 1</name>
<container>true</container>
<expanded>false</expanded>
<childrenReordered>false</childrenReordered>
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
<properties>
@ -1362,341 +1363,10 @@
<componentRootId>18ade34c-a25f-44b8-8d90-79e24edb04b4</componentRootId>
<name>VB 3</name>
<container>true</container>
<childrenReordered>false</childrenReordered>
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
<properties>
<entry>
<key>cssClasses</key>
<value>
<item id="af01abdd-dcde-4139-a699-95521916fbf0" removed="false">
<value>
<simple>"paragraph-group"</simple>
</value>
</item>
</value>
</entry>
<entry>
<key>visible</key>
<value>
<simple>false</simple>
</value>
</entry>
</properties>
</scripts>
<scripts id="72befe90-1915-483f-b88c-d1ec5d4bdc8e"/>
<scripts id="87f3fefa-b77b-4137-aab6-b2bcd83ce380"/>
<scripts id="ef21ca22-3f81-4484-ba6f-58d670c12d4f"/>
<scripts id="277e6fbc-9e2e-4080-bf20-5d8be18e6764"/>
<children id="56f3b6ad-5cd1-4dde-9d7b-62bd453e6881">
<prototypeId>ba24d307-0b91-4299-ba82-9d0b52384ff2</prototypeId>
<componentRootId>56f3b6ad-5cd1-4dde-9d7b-62bd453e6881</componentRootId>
<name>Основной вид деятельности</name>
<container>false</container>
<childrenReordered>false</childrenReordered>
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
<properties>
<entry>
<key>cssClasses</key>
<value>
<item id="ddf92f21-aac9-4378-b2e7-3884fa0b1164" removed="false">
<value>
<simple>"font-bold"</simple>
</value>
</item>
</value>
</entry>
<entry>
<key>initialValue</key>
<value>
<simple>"Основной вид деятельности"</simple>
</value>
</entry>
</properties>
</scripts>
<scripts id="737b67e2-295f-4356-a1e1-9419344d8c85"/>
<scripts id="a6ccccd9-354c-4725-9d34-c716cf626048"/>
<scripts id="d38c1af5-2bfe-41cd-ab0f-67040f498127"/>
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
<enabled>false</enabled>
</scripts>
</children>
<children id="2cd4fdd3-7a68-4f2e-b2c9-468ca83ed63a">
<prototypeId>16071adb-3bdf-4c33-b29b-886876016415</prototypeId>
<componentRootId>2cd4fdd3-7a68-4f2e-b2c9-468ca83ed63a</componentRootId>
<name>Таблица</name>
<container>true</container>
<childrenReordered>false</childrenReordered>
<scripts id="07201df9-ff33-4c71-9aae-a2cfdd028234">
<properties>
<entry>
<key>autoStretchColumns</key>
<value>
<simple>true</simple>
</value>
</entry>
<entry>
<key>cssClasses</key>
<value>
<item id="a3216735-fb23-4653-a3f7-226a28b9a127" removed="false">
<value>
<simple>"okved-list"</simple>
</value>
</item>
</value>
</entry>
<entry>
<key>disabled</key>
<value>
<simple>true</simple>
</value>
</entry>
<entry>
<key>rowClickSelectionType</key>
<value>
<simple>null</simple>
</value>
</entry>
</properties>
</scripts>
<scripts id="1996166f-7922-4f28-a571-9646d956ef37">
<properties>
<entry>
<key>gridService</key>
<value>
<complex>
<entry>
<key>loadDao</key>
<value>
<complex>
<entry>
<key>graph</key>
<value>
<simple>{"conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"nodeByIndex":{"0":{"tableName":"org_okved","schemaName":"public","x":387.20000000000005,"y":282.4,"alias":"org_okved","conditionGroup":{"operator":"AND","conditions":[{"column":{"schema":"public","table":"org_okved","entity":"org_okved","name":"main_okved"},"operation":"EQUAL","typeCode":"CONST","values":["true"]}],"groups":[]},"emptyEntityAction":"IGNORE_OR_DELETE"}},"nodes":[{"tableName":"org_okved","schemaName":"public","x":387.20000000000005,"y":282.4,"alias":"org_okved","conditionGroup":{"operator":"AND","conditions":[{"column":{"schema":"public","table":"org_okved","entity":"org_okved","name":"main_okved"},"operation":"EQUAL","typeCode":"CONST","values":["true"]}],"groups":[]},"emptyEntityAction":"IGNORE_OR_DELETE"}],"nodeByEntityName":{"org_okved":{"tableName":"org_okved","schemaName":"public","x":387.20000000000005,"y":282.4,"alias":"org_okved","conditionGroup":{"operator":"AND","conditions":[{"column":{"schema":"public","table":"org_okved","entity":"org_okved","name":"main_okved"},"operation":"EQUAL","typeCode":"CONST","values":["true"]}],"groups":[]},"emptyEntityAction":"IGNORE_OR_DELETE"}},"matrix":[[null]],"mainNodeIndex":0}</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</entry>
</properties>
</scripts>
<scripts id="be8fe0e1-4909-4224-8664-be55168595c6"/>
<children id="a198d8e0-5886-4b86-a32e-cccbbf86f268">
<prototypeId>364c8faa-5e56-46cd-9203-d2ec6ef2dc74</prototypeId>
<componentRootId>a198d8e0-5886-4b86-a32e-cccbbf86f268</componentRootId>
<name>Столбец</name>
<container>false</container>
<childrenReordered>false</childrenReordered>
<scripts id="9c5c7a86-dc40-4b30-a5a7-5e7b4c7ea1e1"/>
<scripts id="fd653fca-12f9-4e35-baa4-b6b5dd3f6d59">
<properties>
<entry>
<key>disableHiding</key>
<value>
<simple>true</simple>
</value>
</entry>
<entry>
<key>displayColumns</key>
<value>
<item id="1fcc8084-6f93-42fd-80f4-61defe451897" removed="false">
<value>
<complex>
<entry>
<key>entityColumn</key>
<value>
<simple>{"schema":"public","table":"org_okved","entity":"org_okved","name":"code"}</simple>
</value>
</entry>
<entry>
<key>postfix</key>
<value>
<simple>" "</simple>
</value>
</entry>
</complex>
</value>
</item>
<item id="4b348c07-e14d-46cc-8c1d-0e079ebebc4c" removed="false">
<value>
<complex>
<entry>
<key>entityColumn</key>
<value>
<simple>{"schema":"public","table":"org_okved","entity":"org_okved","name":"okved"}</simple>
</value>
</entry>
</complex>
</value>
</item>
</value>
</entry>
<entry>
<key>displayPopup</key>
<value>
<simple>false</simple>
</value>
</entry>
<entry>
<key>displayType</key>
<value>
<simple>"MULTI_COLUMN"</simple>
</value>
</entry>
</properties>
</scripts>
</children>
</children>
<children id="19126951-2acd-4b6c-b576-2fbc82e288c3">
<prototypeId>ba24d307-0b91-4299-ba82-9d0b52384ff2</prototypeId>
<componentRootId>19126951-2acd-4b6c-b576-2fbc82e288c3</componentRootId>
<name>Дополнительные виды деятельности</name>
<container>false</container>
<childrenReordered>false</childrenReordered>
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
<properties>
<entry>
<key>cssClasses</key>
<value>
<item id="ddf92f21-aac9-4378-b2e7-3884fa0b1164" removed="false">
<value>
<simple>"font-bold"</simple>
</value>
</item>
</value>
</entry>
<entry>
<key>initialValue</key>
<value>
<simple>"Дополнительные виды деятельности"</simple>
</value>
</entry>
</properties>
</scripts>
<scripts id="737b67e2-295f-4356-a1e1-9419344d8c85"/>
<scripts id="a6ccccd9-354c-4725-9d34-c716cf626048"/>
<scripts id="d38c1af5-2bfe-41cd-ab0f-67040f498127"/>
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
<enabled>false</enabled>
</scripts>
</children>
<children id="efdeabec-a4db-4a71-b923-13af7581eff1">
<prototypeId>16071adb-3bdf-4c33-b29b-886876016415</prototypeId>
<componentRootId>efdeabec-a4db-4a71-b923-13af7581eff1</componentRootId>
<name>Таблица</name>
<container>true</container>
<childrenReordered>false</childrenReordered>
<scripts id="07201df9-ff33-4c71-9aae-a2cfdd028234">
<properties>
<entry>
<key>autoStretchColumns</key>
<value>
<simple>true</simple>
</value>
</entry>
<entry>
<key>cssClasses</key>
<value>
<item id="1e6df59d-6e5d-4c81-9f99-9f83b889757b" removed="false">
<value>
<simple>"okved-list"</simple>
</value>
</item>
</value>
</entry>
</properties>
</scripts>
<scripts id="1996166f-7922-4f28-a571-9646d956ef37">
<properties>
<entry>
<key>gridService</key>
<value>
<complex>
<entry>
<key>loadDao</key>
<value>
<complex>
<entry>
<key>graph</key>
<value>
<simple>{"conditionGroup":{"operator":"AND","conditions":[],"groups":[]},"nodeByIndex":{"0":{"tableName":"org_okved","schemaName":"public","x":387.20000000000005,"y":282.4,"alias":"org_okved","conditionGroup":{"operator":"OR","conditions":[{"column":{"schema":"public","table":"org_okved","entity":"org_okved","name":"main_okved"},"operation":"EQUAL","typeCode":"CONST","values":["false"]},{"column":{"schema":"public","table":"org_okved","entity":"org_okved","name":"main_okved"},"operation":"IS_NULL","typeCode":"CONST","values":[null]}],"groups":[]},"emptyEntityAction":"IGNORE_OR_DELETE"}},"nodes":[{"tableName":"org_okved","schemaName":"public","x":387.20000000000005,"y":282.4,"alias":"org_okved","conditionGroup":{"operator":"OR","conditions":[{"column":{"schema":"public","table":"org_okved","entity":"org_okved","name":"main_okved"},"operation":"EQUAL","typeCode":"CONST","values":["false"]},{"column":{"schema":"public","table":"org_okved","entity":"org_okved","name":"main_okved"},"operation":"IS_NULL","typeCode":"CONST","values":[null]}],"groups":[]},"emptyEntityAction":"IGNORE_OR_DELETE"}],"nodeByEntityName":{"org_okved":{"tableName":"org_okved","schemaName":"public","x":387.20000000000005,"y":282.4,"alias":"org_okved","conditionGroup":{"operator":"OR","conditions":[{"column":{"schema":"public","table":"org_okved","entity":"org_okved","name":"main_okved"},"operation":"EQUAL","typeCode":"CONST","values":["false"]},{"column":{"schema":"public","table":"org_okved","entity":"org_okved","name":"main_okved"},"operation":"IS_NULL","typeCode":"CONST","values":[null]}],"groups":[]},"emptyEntityAction":"IGNORE_OR_DELETE"}},"matrix":[[null]],"mainNodeIndex":0}</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</entry>
</properties>
</scripts>
<scripts id="be8fe0e1-4909-4224-8664-be55168595c6"/>
<children id="efc6f03c-2dda-4f18-9486-184b2437d76d">
<prototypeId>364c8faa-5e56-46cd-9203-d2ec6ef2dc74</prototypeId>
<componentRootId>efc6f03c-2dda-4f18-9486-184b2437d76d</componentRootId>
<name>Столбец</name>
<container>false</container>
<childrenReordered>false</childrenReordered>
<scripts id="9c5c7a86-dc40-4b30-a5a7-5e7b4c7ea1e1"/>
<scripts id="fd653fca-12f9-4e35-baa4-b6b5dd3f6d59">
<properties>
<entry>
<key>displayColumns</key>
<value>
<item id="1fcc8084-6f93-42fd-80f4-61defe451897" removed="false">
<value>
<complex>
<entry>
<key>entityColumn</key>
<value>
<simple>{"schema":"public","table":"org_okved","entity":"org_okved","name":"code"}</simple>
</value>
</entry>
<entry>
<key>postfix</key>
<value>
<simple>" "</simple>
</value>
</entry>
</complex>
</value>
</item>
<item id="4b348c07-e14d-46cc-8c1d-0e079ebebc4c" removed="false">
<value>
<complex>
<entry>
<key>entityColumn</key>
<value>
<simple>{"schema":"public","table":"org_okved","entity":"org_okved","name":"okved"}</simple>
</value>
</entry>
</complex>
</value>
</item>
</value>
</entry>
<entry>
<key>displayType</key>
<value>
<simple>"MULTI_COLUMN"</simple>
</value>
</entry>
</properties>
</scripts>
</children>
</children>
<children id="1331071a-d356-4bbb-85b9-b207e0fb4901">
<prototypeId>d7d54cfb-26b5-4dba-b56f-b6247183c24d</prototypeId>
<componentRootId>1331071a-d356-4bbb-85b9-b207e0fb4901</componentRootId>
<name>HB</name>
<container>true</container>
<removed>true</removed>
</children>
</children>
</children>
</children>
<children id="5e98c4eb-ec87-453d-9fcb-666ae05ed1db">
<prototypeId>f7504fc9-f501-43fe-a678-5c6ba756ba5c</prototypeId>
<componentRootId>5e98c4eb-ec87-453d-9fcb-666ae05ed1db</componentRootId>
@ -1812,13 +1482,6 @@
</properties>
</scripts>
</children>
<children id="ff8c83c6-747c-476b-af82-dba5b3614c72">
<prototypeId>ba24d307-0b91-4299-ba82-9d0b52384ff2</prototypeId>
<componentRootId>ff8c83c6-747c-476b-af82-dba5b3614c72</componentRootId>
<name>Текст</name>
<container>false</container>
<removed>true</removed>
</children>
</children>
<children id="b6f5ecec-228d-4b9b-981b-646ce1c8afb2">
<prototypeId>5ebd2885-0972-4e51-8376-1fa66aed9a90</prototypeId>
@ -1879,13 +1542,6 @@
<enabled>false</enabled>
</scripts>
</children>
<children id="ff8c83c6-747c-476b-af82-dba5b3614c72">
<prototypeId>ba24d307-0b91-4299-ba82-9d0b52384ff2</prototypeId>
<componentRootId>ff8c83c6-747c-476b-af82-dba5b3614c72</componentRootId>
<name>Текст</name>
<container>false</container>
<removed>true</removed>
</children>
<children id="7bc32d29-352c-4826-abbd-e2b5d381f3db">
<prototypeId>98594cec-0a9b-4cef-af09-e1b71cb2ad9e</prototypeId>
<componentRootId>7bc32d29-352c-4826-abbd-e2b5d381f3db</componentRootId>
@ -2019,13 +1675,6 @@
</properties>
</scripts>
</children>
<children id="9e03784a-d1bd-498c-84a1-93b2b681fd2d">
<prototypeId>98594cec-0a9b-4cef-af09-e1b71cb2ad9e</prototypeId>
<componentRootId>9e03784a-d1bd-498c-84a1-93b2b681fd2d</componentRootId>
<name>AC_text_cur_date</name>
<container>false</container>
<removed>true</removed>
</children>
<children id="4c5662ea-a411-4bdd-8f11-d3cbfbea6f98">
<prototypeId>e32ae1f5-5b14-45f1-abb6-f52c34b3b570</prototypeId>
<componentRootId>4c5662ea-a411-4bdd-8f11-d3cbfbea6f98</componentRootId>

View file

@ -1,201 +0,0 @@
<?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>
<parent>
<groupId>ru.micord.ervu.lkrp</groupId>
<artifactId>ul</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<groupId>ru.micord.ervu.lkrp.ul</groupId>
<artifactId>test</artifactId>
<properties>
<application.url>http://localhost:8080/test</application.url>
<selenium.grid.url>http://127.0.0.1:4444/wd/hub</selenium.grid.url>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>ru.cg.webbpm</groupId>
<artifactId>web-tests-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>ru.micord.fias</groupId>
<artifactId>client</artifactId>
</dependency>
<!--JWT-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
</dependency>
<dependency>
<groupId>ru.cg.webbpm.modules.database</groupId>
<artifactId>database-impl</artifactId>
</dependency>
<dependency>
<groupId>ru.cg.webbpm.modules.security</groupId>
<artifactId>security-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-suite-engine</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.2.5</version>
<inherited>true</inherited>
<configuration>
<trimStackTrace>false</trimStackTrace>
<systemPropertyVariables>
<application.url>${application.url}</application.url>
<selenium.grid.url>${selenium.grid.url}</selenium.grid.url>
</systemPropertyVariables>
<failIfNoTests>true</failIfNoTests>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<profiles>
<profile>
<id>chrome</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<browsers>chrome</browsers>
</properties>
</profile>
<profile>
<id>all-browsers</id>
<properties>
<browsers>all</browsers>
</properties>
</profile>
<profile>
<id>integration-tests-admin</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<includes>
<include>SuiteAdmin.java</include>
</includes>
<argLine>-Xmx4g -XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/tmp/integration-tests-admin-dump.hprof
</argLine>
<systemPropertyVariables>
<browsers>${browsers}</browsers>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>2.22.2</version>
<reportSets>
<reportSet>
<id>integration-tests-admin</id>
<reports>
<report>failsafe-report-only</report>
</reports>
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>
</profile>
</profiles>
</project>

View file

@ -1,27 +0,0 @@
import old.*;
import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;
import tests.AuthoritiesIT;
import tests.LoginIT;
import tests.OrganizationsIT;
import tests.ProcessesIT;
/**
* @author gulnaz
*/
@Suite
@SelectClasses({
AuthoritiesIT.class,
LoginIT.class,
OrganizationsIT.class,
ProcessesIT.class,
AdminGroupIT.class,
AdminRoleIT.class,
AdminUserIT.class,
JWTokensIT.class
})
public class SuiteAdmin {
SuiteAdmin() {
}
}

View file

@ -1,332 +0,0 @@
package old;
import com.google.common.collect.Comparators;
import old.core.Browser;
import old.core.BrowserArgumentProvider;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
import old.page.AdminGroupPage;
import old.page.AdminUserPage;
import java.util.Arrays;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author kote
*/
public class AdminGroupIT extends BaseComponentIT {
private static final String GROUP_ACCESS_LEVEL = "user access level";
private static final String ROLE = "BPMN User";
private static final String ROLE_2 = "BPMN Admin";
private static final String ROLE_3 = "BPMN Superuser";
private static final String COL_ID = "group$name";
private static final String COL_ID_CREATED = "group$created";
private static final String COL_ID_UPDATED = "group$updated";
private static final String BPMN_ADMIN_ROLE_ID = "aa14ba1d-0b61-4e33-8474-7c2d98944b12";
private static final String BPMN_USER_ROLE_ID = "767ae8cf-af01-44d4-86ef-fcb143373407";
private static final String BPMN_SUPERUSER_ROLE_ID = "2569ba58-1f8f-43ea-8b2c-0d373cf501fe";
private AdminGroupPage adminGroupPage;
private String oldName;
private String groupId;
private String roleId;
public AdminGroupIT() {
super();
}
@AfterEach
public void afterEachTest(TestInfo testInfo) {
String testName = testInfo.getTestMethod().toString();
if (testName.contains("User")) {
EXECUTION_MANAGER.deleteTestUser(name);
}
if (testName.contains("edit")) {
EXECUTION_MANAGER.deleteTestGroup(oldName);
}
if (testName.contains("linked")) {
EXECUTION_MANAGER.deleteUserGroupRole(name, groupId, roleId);
}
if (testName.contains("Sorting")) {
String groupIdToDelete = EXECUTION_MANAGER.getGroupIdByName(name);
EXECUTION_MANAGER.deleteLinkedRolesFromGroup(groupIdToDelete);
}
EXECUTION_MANAGER.deleteTestGroup(name);
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void createGroup(Browser browser) {
openBrowserAndAdminPage(browser);
adminGroupPage.clickCreateButton();
adminGroupPage.waitForPageLoad();
adminGroupPage.waitForVisibilityOf(adminGroupPage.nameField);
adminGroupPage.typeText(adminGroupPage.nameField, name);
adminGroupPage.typeAndSelectLevel(GROUP_ACCESS_LEVEL);
adminGroupPage.addRole(ROLE, false);
adminGroupPage.clickSaveButton();
String dateOfCreation = adminGroupPage.getLocalDate();
adminGroupPage.waitForPageLoad();
adminGroupPage.searchGroup(name);
assertEquals(1, adminGroupPage.getListOfGroupsNamesFromTable(name).size());
assertTrue(adminGroupPage.getActionTime(COL_ID, name, COL_ID_CREATED).getText().contains(dateOfCreation));
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void searchGroup(Browser browser) {
openBrowserAndAdminPage(browser);
EXECUTION_MANAGER.createTestGroup(name, ACCESS_LEVEL_ID);
adminGroupPage.searchGroup(name);
adminGroupPage.waitForPageLoad();
assertEquals(1, adminGroupPage.getListOfGroupsNamesFromTable(name).size());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void editGroup(Browser browser) {
openBrowserAndAdminPage(browser);
oldName = "old" + name;
EXECUTION_MANAGER.createTestGroup(oldName, ACCESS_LEVEL_ID);
adminGroupPage.chooseGroup(oldName);
adminGroupPage.clickEditButton();
adminGroupPage.waitForVisibilityOf(adminGroupPage.nameField);
adminGroupPage.typeText(adminGroupPage.nameField, name);
adminGroupPage.addRole(ROLE, false);
adminGroupPage.clickSaveButton();
adminGroupPage.searchGroup(oldName);
assertEquals(0, adminGroupPage.getListOfGroupsNamesFromTable(oldName).size());
adminGroupPage.chooseGroup(name);
assertEquals(1, adminGroupPage.getListOfGroupsNamesFromTable(name).size());
String timeOfCreate = adminGroupPage.getActionTime(COL_ID, name, COL_ID_CREATED).getText();
String timeOfUpdate = adminGroupPage.getActionTime(COL_ID, name, COL_ID_UPDATED).getText();
assertNotEquals(timeOfCreate, timeOfUpdate);
adminGroupPage.clickEditButton();
assertTrue(adminGroupPage.hasRolesInTable(AdminGroupPage.GroupPageGrids.ADDED_ROLES_GRID, ROLE));
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void deleteGroup(Browser browser) {
openBrowserAndAdminPage(browser);
EXECUTION_MANAGER.createTestGroup(name, ACCESS_LEVEL_ID);
adminGroupPage.chooseGroup(name);
adminGroupPage.deleteGroup();
assertTrue(adminGroupPage.isGridEmpty());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void linkedRolesTable(Browser browser) {
openBrowserAndAdminPage(browser);
roleId = EXECUTION_MANAGER.generateId();
groupId = EXECUTION_MANAGER.generateId();
EXECUTION_MANAGER.createBindGroupRole(name, groupId, ACCESS_LEVEL_ID, roleId);
adminGroupPage.chooseGroup(name);
assertEquals(1, adminGroupPage.getListOfRolesFromLinkedTable().size());
assertEquals(name, adminGroupPage.getListOfRolesFromLinkedTable().get(0).getText());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void attachRemoveRoleToGroup(Browser browser) {
openBrowserAndAdminPage(browser);
EXECUTION_MANAGER.createTestGroup(name, ACCESS_LEVEL_ID);
adminGroupPage.chooseGroup(name);
assertTrue(adminGroupPage.getListOfRolesFromLinkedTable().isEmpty());
adminGroupPage.clickEditButton();
assertFalse(adminGroupPage.getListOfRolesToAdd().isEmpty());
assertTrue(adminGroupPage.getListOfAddedRoles().isEmpty());
adminGroupPage.addRole(ROLE, false);
assertFalse(adminGroupPage.getWebElementTexts(adminGroupPage.getListOfRolesToAdd()).contains(ROLE));
assertTrue(adminGroupPage.getWebElementTexts(adminGroupPage.getListOfAddedRoles()).contains(ROLE));
assertEquals(1, adminGroupPage.getListOfAddedRoles().size());
adminGroupPage.clickSaveButton();
adminGroupPage.chooseGroup(name);
assertEquals(1, adminGroupPage.getListOfRolesFromLinkedTable().size());
assertTrue(adminGroupPage.getWebElementTexts(adminGroupPage.getListOfRolesFromLinkedTable()).contains(ROLE));
adminGroupPage.clickEditButton();
adminGroupPage.removeRole(ROLE);
assertTrue(adminGroupPage.getWebElementTexts(adminGroupPage.getListOfRolesToAdd()).contains(ROLE));
assertTrue(adminGroupPage.getListOfAddedRoles().isEmpty());
adminGroupPage.clickSaveButton();
adminGroupPage.chooseGroup(name);
assertTrue(adminGroupPage.getListOfRolesFromLinkedTable().isEmpty());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void attachRemoveAllRolesToGroup(Browser browser) {
openBrowserAndAdminPage(browser);
EXECUTION_MANAGER.createTestGroup(name, ACCESS_LEVEL_ID);
List<String> roleNames = EXECUTION_MANAGER.getRoleNamesFromUserRole();
List<String> expectedRoles = Arrays.asList(ROLE, ROLE_2, ROLE_3);
adminGroupPage.chooseGroup(name);
adminGroupPage.clickEditButton();
assertFalse(adminGroupPage.getListOfRolesToAdd().isEmpty());
assertTrue(adminGroupPage.getListOfAddedRoles().isEmpty());
adminGroupPage.addAllRoles();
assertTrue(adminGroupPage.isAvailableGridEmpty(roleNames));
assertFalse(adminGroupPage.getListOfAddedRoles().isEmpty());
/*
Нет возможности проверить сохранение привязки всех ролей к группе из-за создания/удаление ролей
параллельными тестами.
*/
adminGroupPage.removeAllRoles();
assertFalse(adminGroupPage.getListOfRolesToAdd().isEmpty());
assertTrue(adminGroupPage.getListOfAddedRoles().isEmpty());
adminGroupPage.addRole(ROLE, false);
adminGroupPage.addRole(ROLE_2, false);
adminGroupPage.addRole(ROLE_3, false);
adminGroupPage.clickSaveButton();
adminGroupPage.chooseGroup(name);
assertEquals(expectedRoles.size(), adminGroupPage.getListOfRolesFromLinkedTable().size());
assertTrue(adminGroupPage.getWebElementTexts(adminGroupPage.getListOfRolesFromLinkedTable())
.containsAll(expectedRoles));
adminGroupPage.clickEditButton();
adminGroupPage.removeAllRoles();
adminGroupPage.clickSaveButton();
adminGroupPage.chooseGroup(name);
assertTrue(adminGroupPage.getListOfRolesFromLinkedTable().isEmpty());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void addNewGroupToUser(Browser browser) {
openBrowserAndAdminPage(browser);
String userName = name;
EXECUTION_MANAGER.createUser(userName, ORGANIZATION_ID);
adminGroupPage.clickCreateButton();
adminGroupPage.waitForPageLoad();
adminGroupPage.waitForVisibilityOf(adminGroupPage.nameField);
adminGroupPage.typeText(adminGroupPage.nameField, name);
adminGroupPage.typeAndSelectLevel(GROUP_ACCESS_LEVEL);
adminGroupPage.clickSaveButton();
AdminUserPage adminUserPage = inboxPage.startAdminUser();
adminUserPage.searchUser(userName);
adminUserPage.clickOnUserInTable(userName);
adminUserPage.clickEditButton();
adminUserPage.fillPassAndEmail(userName, userName + "@test.ru");
adminUserPage.bindGroup(name);
assertTrue(adminUserPage.getWebElementTexts(adminUserPage.getListOfAddedGroups()).contains(name));
adminUserPage.clickSaveButton();
adminUserPage.searchUser(userName);
adminUserPage.clickOnUserInTable(userName);
assertEquals(1, adminUserPage.getListOfGroupsFromTable().size());
assertEquals(name, adminUserPage.getListOfGroupsFromTable().get(0).getText());
}
@Disabled("dev WEBBPMNEXT-7837")
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void groupRolesGridsSorting(Browser browser) {
openBrowserAndAdminPage(browser);
EXECUTION_MANAGER.createGroupBindRoles(name, ACCESS_LEVEL_ID, BPMN_ADMIN_ROLE_ID,
BPMN_USER_ROLE_ID, BPMN_SUPERUSER_ROLE_ID);
//main group page sorting
List<String> groupNamesNatural = adminGroupPage.getWebElementTexts(adminGroupPage.getListOfGroupNames());
assertTrue(Comparators.isInOrder(groupNamesNatural, String.CASE_INSENSITIVE_ORDER),
"Grid wasn't sorted");
adminGroupPage.changeGroupPageGridSort(AdminGroupPage.GroupPageGrids.GROUP_NAMES_GRID);
List<String> groupNamesReverse = adminGroupPage.getWebElementTexts(adminGroupPage.getListOfGroupNames());
assertTrue(Comparators.isInOrder(groupNamesReverse, String.CASE_INSENSITIVE_ORDER.reversed()),
"Grid wasn't sorted");
adminGroupPage.chooseGroup(name);
List<String> linkedRolesNatural = adminGroupPage.getWebElementTexts(adminGroupPage.getListOfRolesFromLinkedTable());
assertTrue(Comparators.isInOrder(linkedRolesNatural, String.CASE_INSENSITIVE_ORDER),
"Grid wasn't sorted");
adminGroupPage.changeGroupPageGridSort(AdminGroupPage.GroupPageGrids.LINKED_ROLES_GRID);
List<String> linkedRolesReverse = adminGroupPage.getWebElementTexts(adminGroupPage.getListOfRolesFromLinkedTable());
assertTrue(Comparators.isInOrder(linkedRolesReverse, String.CASE_INSENSITIVE_ORDER.reversed()),
"Grid wasn't sorted");
//edit group page sorting
adminGroupPage.clickEditButton();
List<String> availableToAddRolesNatural = adminGroupPage.getWebElementTexts(adminGroupPage.getListOfRolesToAdd());
assertTrue(Comparators.isInOrder(availableToAddRolesNatural, String.CASE_INSENSITIVE_ORDER),
"Grid wasn't sorted");
adminGroupPage.changeGroupPageGridSort(AdminGroupPage.GroupPageGrids.ROLES_TO_ADD_GRID);
List<String> availableToAddRolesReverse = adminGroupPage.getWebElementTexts(adminGroupPage.getListOfRolesToAdd());
assertTrue(Comparators.isInOrder(availableToAddRolesReverse,
String.CASE_INSENSITIVE_ORDER.reversed()), "Grid wasn't sorted");
adminGroupPage.removeAllRoles();
List<String> addedRolesNatural = adminGroupPage.getWebElementTexts(adminGroupPage.getListOfAddedRoles());
assertTrue(Comparators.isInOrder(addedRolesNatural, String.CASE_INSENSITIVE_ORDER),
"Grid wasn't sorted");
adminGroupPage.changeGroupPageGridSort(AdminGroupPage.GroupPageGrids.ADDED_ROLES_GRID);
List<String> addedRolesReverse = adminGroupPage.getWebElementTexts(adminGroupPage.getListOfAddedRoles());
assertTrue(Comparators.isInOrder(addedRolesReverse, String.CASE_INSENSITIVE_ORDER.reversed()),
"Grid wasn't sorted");
//create group page sorting
adminGroupPage.cancelAction();
adminGroupPage.clickCreateButton();
List<String> rolesToAddNatural = adminGroupPage.getWebElementTexts(adminGroupPage.getListOfRolesToAdd());
assertTrue(Comparators.isInOrder(rolesToAddNatural, String.CASE_INSENSITIVE_ORDER),
"Grid wasn't sorted");
adminGroupPage.changeGroupPageGridSort(AdminGroupPage.GroupPageGrids.ROLES_TO_ADD_GRID);
List<String> rolesToAddReverse = adminGroupPage.getWebElementTexts(adminGroupPage.getListOfRolesToAdd());
assertTrue(Comparators.isInOrder(rolesToAddReverse, String.CASE_INSENSITIVE_ORDER.reversed()),
"Grid wasn't sorted");
adminGroupPage.removeAllRoles();
List<String> addedRolesNaturalSort = adminGroupPage.getWebElementTexts(adminGroupPage.getListOfAddedRoles());
assertTrue(Comparators.isInOrder(addedRolesNaturalSort, String.CASE_INSENSITIVE_ORDER),
"Grid wasn't sorted");
adminGroupPage.changeGroupPageGridSort(AdminGroupPage.GroupPageGrids.ADDED_ROLES_GRID);
List<String> addedRolesReverseSort = adminGroupPage.getWebElementTexts(adminGroupPage.getListOfAddedRoles());
assertTrue(Comparators.isInOrder(addedRolesReverseSort, String.CASE_INSENSITIVE_ORDER.reversed()),
"Grid wasn't sorted");
}
private void openBrowserAndAdminPage(Browser browser) {
openBrowserAndLoginForAdmin(browser);
initAdminName();
adminGroupPage = inboxPage.startAdminGroup();
}
}

View file

@ -1,184 +0,0 @@
package old;
import com.google.common.collect.Comparators;
import old.core.Browser;
import old.core.BrowserArgumentProvider;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
import org.openqa.selenium.WebElement;
import old.page.AdminGroupPage;
import old.page.AdminRolePage;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author kote
*/
public class AdminRoleIT extends BaseComponentIT {
private static final String COL_ID = "role$name";
private static final String COL_ID_CREATED = "role$created";
private static final String COL_ID_UPDATED = "role$updated";
private AdminRolePage adminRolePage;
private String oldName;
public AdminRoleIT() {
super();
}
@AfterEach
public void afterEachTest(TestInfo testInfo) {
String testName = testInfo.getTestMethod().toString();
if (testName.contains("Group")) {
EXECUTION_MANAGER.deleteTestGroup(name);
}
if (testName.contains("edit")) {
EXECUTION_MANAGER.deleteTestRole(oldName);
}
if (testName.contains("Sorting")) {
String roleId = EXECUTION_MANAGER.getRoleIdByName(name);
EXECUTION_MANAGER.deleteLinkedGroupsFromRole(roleId);
}
EXECUTION_MANAGER.deleteTestRole(name);
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void createRole(Browser browser) {
openBrowserAndAdminPage(browser);
adminRolePage.clickCreateButton();
adminRolePage.typeText(adminRolePage.nameField, name);
adminRolePage.clickSaveButton();
String dateOfCreation = adminRolePage.getLocalDate();
adminRolePage.searchRole(name);
assertEquals(1, adminRolePage.getListOfRolesNamesFromTable(name).size());
assertTrue(adminRolePage.getActionTime(COL_ID, name, COL_ID_CREATED).getText().contains(dateOfCreation));
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void searchRole(Browser browser) {
openBrowserAndAdminPage(browser);
EXECUTION_MANAGER.createTestRole(name);
adminRolePage.searchRole(name);
assertEquals(1, adminRolePage.getListOfRolesNamesFromTable(name).size());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void editRole(Browser browser) {
openBrowserAndAdminPage(browser);
oldName = "old" + name;
EXECUTION_MANAGER.createTestRole(oldName);
adminRolePage.chooseRole(oldName);
adminRolePage.clickEditButton();
adminRolePage.typeText(adminRolePage.nameField, name);
adminRolePage.clickSaveButton();
adminRolePage.searchRole(oldName);
assertEquals(0, adminRolePage.getListOfRolesNamesFromTable(oldName).size());
adminRolePage.searchRole(name);
assertEquals(1, adminRolePage.getListOfRolesNamesFromTable(name).size());
String timeOfCreate = adminRolePage.getActionTime(COL_ID, name, COL_ID_CREATED).getText();
String timeOfUpdate = adminRolePage.getActionTime(COL_ID, name, COL_ID_UPDATED).getText();
assertNotEquals(timeOfCreate, timeOfUpdate);
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void deleteRole(Browser browser) {
openBrowserAndAdminPage(browser);
EXECUTION_MANAGER.createTestRole(name);
adminRolePage.waitForPageLoad();
adminRolePage.chooseRole(name);
adminRolePage.deleteRole();
assertEquals(0, adminRolePage.getListOfRolesNamesFromTable(name).size());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void roleGroupGridContainsAttachedGroup(Browser browser) {
openBrowserAndAdminPage(browser);
String roleId = EXECUTION_MANAGER.generateId();
String groupId = EXECUTION_MANAGER.generateId();
EXECUTION_MANAGER.createBindGroupRole(name, groupId, ACCESS_LEVEL_ID, roleId);
adminRolePage.chooseRole(name);
WebElement gridLinkedGroup = adminRolePage.getListOfRoleLinkedGroups().get(0);
adminRolePage.waitForTextToBePresentInElement(gridLinkedGroup, name);
assertEquals(1, adminRolePage.getListOfRoleLinkedGroups().size());
assertEquals(adminRolePage.getListOfRoleLinkedGroups().get(0).getText(), name);
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void addNewRoleToGroup(Browser browser) {
openBrowserAndAdminPage(browser);
String groupName = name;
EXECUTION_MANAGER.createTestGroup(groupName, ACCESS_LEVEL_ID);
adminRolePage.clickCreateButton();
adminRolePage.typeText(adminRolePage.nameField, name);
adminRolePage.clickSaveButton();
AdminGroupPage adminGroupPage = inboxPage.startAdminGroup();
adminGroupPage.chooseGroup(groupName);
adminGroupPage.clickEditButton();
adminGroupPage.bindRole(name);
assertTrue(adminGroupPage.hasRolesInTable(AdminGroupPage.GroupPageGrids.ADDED_ROLES_GRID, name));
adminGroupPage.clickSaveButton();
adminGroupPage.chooseGroup(groupName);
adminGroupPage.clickEditButton();
assertTrue(adminGroupPage.hasRolesInTable(AdminGroupPage.GroupPageGrids.ADDED_ROLES_GRID, name));
}
@Disabled("dev WEBBPMNEXT-7837")
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void roleGroupsGridSorting(Browser browser) {
openBrowserAndAdminPage(browser);
EXECUTION_MANAGER.createRoleBindGroups(name, BPMN_ADMIN_GROUP_ID, BPMN_USER_GROUP_ID, BPMN_SUPERUSER_GROUP_ID);
List<String> roleNamesNatural = adminRolePage.getWebElementTexts(adminRolePage.getListOfRoles());
assertTrue(Comparators.isInOrder(roleNamesNatural, String.CASE_INSENSITIVE_ORDER),
"Grid wasn't sorted");
adminRolePage.changeRolePageGridSort(AdminRolePage.RolePageGrids.ROLE_NAMES_GRID);
List<String> roleNamesReverse = adminRolePage.getWebElementTexts(adminRolePage.getListOfRoles());
assertTrue(Comparators.isInOrder(roleNamesReverse, String.CASE_INSENSITIVE_ORDER.reversed()),
"Grid wasn't sorted");
adminRolePage.chooseRole(name);
List<String> linkedGroupsNatural = adminRolePage.getWebElementTexts(adminRolePage.getListOfRoleLinkedGroups());
assertTrue(Comparators.isInOrder(linkedGroupsNatural, String.CASE_INSENSITIVE_ORDER),
"Grid wasn't sorted");
adminRolePage.changeRolePageGridSort(AdminRolePage.RolePageGrids.GROUP_NAMES_GRID);
List<String> linkedGroupsReverse = adminRolePage.getWebElementTexts(adminRolePage.getListOfRoleLinkedGroups());
assertTrue(Comparators.isInOrder(linkedGroupsReverse, String.CASE_INSENSITIVE_ORDER.reversed()),
"Grid wasn't sorted");
}
private void openBrowserAndAdminPage(Browser browser) {
openBrowserAndLoginForAdmin(browser);
initAdminName();
adminRolePage = inboxPage.startAdminRole();
}
}

View file

@ -1,370 +0,0 @@
package old;
import com.google.common.collect.Comparators;
import old.core.Browser;
import old.core.BrowserArgumentProvider;
import org.apache.commons.lang.RandomStringUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
import old.page.AdminUserPage;
import java.util.Arrays;
import java.util.List;
import static org.apache.commons.lang.StringUtils.containsIgnoreCase;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author kote
*/
public class AdminUserIT extends BaseComponentIT {
private AdminUserPage adminUserPage;
private String oldName;
private String email;
private static final String USER_PASSWORD = "test";
private static final String USER_PASSWORD_2 = "test2";
private static final String ORGANIZATION = "Default";
private static final String FULL_ORGANIZATION_NAME = "Default Organization";
private static final String BPMN_ADMIN_GROUP = "BPMN Admin";
private static final String BPMN_USER_GROUP = "BPMN User";
private static final String BPMN_SUPERUSER_GROUP = "BPMN Superuser";
private static final String SECURITY_GROUP = "Security Admin";
public AdminUserIT() {
super();
}
@AfterEach
public void afterEachTest(TestInfo testInfo) {
String testName = testInfo.getTestMethod().toString();
if (testName.contains("edit")) {
EXECUTION_MANAGER.deleteTestUser(oldName);
}
if (containsIgnoreCase(testName, "sorting")) {
String userAccId = EXECUTION_MANAGER.getUserAccountIdByName(name);
EXECUTION_MANAGER.deleteUserLinkedGroups(userAccId);
}
if (containsIgnoreCase(testName, "visibility")) {
String userAccountId = EXECUTION_MANAGER.getUserAccountIdByName(name);
EXECUTION_MANAGER.deleteUserLinkedGroups(userAccountId);
}
EXECUTION_MANAGER.deleteTestUser(name);
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void createUser(Browser browser) {
openBrowserAndAdminPage(browser);
adminUserPage.clickCreateButton();
adminUserPage.waitForVisibilityOf(adminUserPage.lastNameField);
adminUserPage.fillUserFullName(name);
email = randomEmail();
adminUserPage.fillUserCredentials(name, USER_PASSWORD, email, ORGANIZATION, FULL_ORGANIZATION_NAME);
adminUserPage.addGroup(BPMN_ADMIN_GROUP);
adminUserPage.clickSaveButton();
assertTrue(EXECUTION_MANAGER.hasUserByData(name, email));
adminUserPage.searchUser(name);
adminUserPage.clickOnUserInTable(name);
assertEquals(1, adminUserPage.getListOfGroupsFromTable().size());
assertEquals(BPMN_ADMIN_GROUP, adminUserPage.getListOfGroupsFromTable().get(0).getText());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void searchUser(Browser browser) {
openBrowserAndAdminPage(browser);
EXECUTION_MANAGER.createUser(name, ORGANIZATION_ID);
adminUserPage.searchUser(name);
assertEquals(1, adminUserPage.getListOfLastNamesFromTable().size());
assertEquals(1, adminUserPage.getListOfFirstNamesFromTable().size());
assertEquals(1, adminUserPage.getListOfMiddleNamesFromTable().size());
assertEquals(name, adminUserPage.getListOfLastNamesFromTable().get(0).getText());
assertEquals(name, adminUserPage.getListOfFirstNamesFromTable().get(0).getText());
assertEquals(name, adminUserPage.getListOfMiddleNamesFromTable().get(0).getText());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void editUser(Browser browser) {
openBrowserAndAdminPage(browser);
EXECUTION_MANAGER.createUser(name, ORGANIZATION_ID);
adminUserPage.searchUser(name);
adminUserPage.clickOnUserInTable(name);
adminUserPage.clickEditButton();
adminUserPage.waitForVisibilityOf(adminUserPage.lastNameField);
oldName = name;
name = name + "_edited";
adminUserPage.fillUserFullName(name);
email = randomEmail();
adminUserPage.fillPassAndEmail(USER_PASSWORD_2, email);
adminUserPage.addGroup(BPMN_USER_GROUP);
adminUserPage.clickSaveButton();
adminUserPage.waitForVisibilityOf(adminUserPage.filterPanel);
adminUserPage.searchUser(name);
assertEquals(1, adminUserPage.getListOfLastNamesFromTable().size());
assertEquals(1, adminUserPage.getListOfFirstNamesFromTable().size());
assertEquals(1, adminUserPage.getListOfMiddleNamesFromTable().size());
assertNotEquals(oldName, adminUserPage.getListOfLastNamesFromTable().get(0).getText());
assertNotEquals(oldName, adminUserPage.getListOfFirstNamesFromTable().get(0).getText());
assertNotEquals(oldName, adminUserPage.getListOfMiddleNamesFromTable().get(0).getText());
assertTrue(EXECUTION_MANAGER.hasUserByData(name, email));
adminUserPage.clickOnUserInTable(name);
assertEquals(1, adminUserPage.getListOfGroupsFromTable().size());
assertEquals(BPMN_USER_GROUP, adminUserPage.getListOfGroupsFromTable().get(0).getText());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void deleteUser(Browser browser) {
openBrowserAndAdminPage(browser);
EXECUTION_MANAGER.createUser(name, ORGANIZATION_ID);
adminUserPage.searchUser(name);
adminUserPage.clickOnUserInTable(name);
adminUserPage.deleteUser();
assertTrue(adminUserPage.getListOfLastNamesFromTable().isEmpty());
assertTrue(adminUserPage.getListOfFirstNamesFromTable().isEmpty());
assertTrue(adminUserPage.getListOfMiddleNamesFromTable().isEmpty());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void attachRemoveGroup(Browser browser) {
openBrowserAndAdminPage(browser);
EXECUTION_MANAGER.createUser(name, ORGANIZATION_ID);
adminUserPage.searchUser(name);
adminUserPage.clickOnUserInTable(name);
assertTrue(adminUserPage.getListOfGroupsFromTable().isEmpty());
adminUserPage.clickEditButton();
assertFalse(adminUserPage.getListOfAvailableGroupsToAdd().isEmpty());
assertTrue(adminUserPage.getListOfAddedGroups().isEmpty());
adminUserPage.addGroup(BPMN_ADMIN_GROUP);
assertFalse(adminUserPage.getWebElementTexts(adminUserPage.getListOfAvailableGroupsToAdd()).contains(BPMN_ADMIN_GROUP));
assertEquals(BPMN_ADMIN_GROUP, adminUserPage.getListOfAddedGroups().get(0).getText());
assertEquals(1, adminUserPage.getListOfAddedGroups().size());
adminUserPage.clickSaveButton();
adminUserPage.searchUser(name);
adminUserPage.clickOnUserInTable(name);
assertEquals(1, adminUserPage.getListOfGroupsFromTable().size());
assertEquals(BPMN_ADMIN_GROUP, adminUserPage.getListOfGroupsFromTable().get(0).getText());
adminUserPage.clickEditButton();
adminUserPage.removeGroup(BPMN_ADMIN_GROUP);
assertTrue(adminUserPage.getWebElementTexts(adminUserPage.getListOfAvailableGroupsToAdd()).contains(BPMN_ADMIN_GROUP));
assertTrue(adminUserPage.getListOfAddedGroups().isEmpty());
adminUserPage.clickSaveButton();
adminUserPage.searchUser(name);
adminUserPage.clickOnUserInTable(name);
assertTrue(adminUserPage.getListOfGroupsFromTable().isEmpty());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void attachRemoveAllGroups(Browser browser) {
openBrowserAndAdminPage(browser);
EXECUTION_MANAGER.createUser(name, ORGANIZATION_ID);
List<String> groupNamesFromTable = EXECUTION_MANAGER.getGroupNamesFromUserGroup();
List<String> expectedGroups = Arrays.asList(BPMN_ADMIN_GROUP, BPMN_USER_GROUP,
BPMN_SUPERUSER_GROUP);
adminUserPage.searchUser(name);
adminUserPage.clickOnUserInTable(name);
assertTrue(adminUserPage.getListOfGroupsFromTable().isEmpty());
adminUserPage.clickEditButton();
assertFalse(adminUserPage.getListOfAvailableGroupsToAdd().isEmpty());
assertTrue(adminUserPage.getListOfAddedGroups().isEmpty());
adminUserPage.addAllGroups();
assertTrue(adminUserPage.isAvailableGridEmpty(groupNamesFromTable));
assertFalse(adminUserPage.getListOfAddedGroups().isEmpty());
adminUserPage.removeAllGroups();
assertFalse(adminUserPage.getListOfAvailableGroupsToAdd().isEmpty());
assertTrue(adminUserPage.getListOfAddedGroups().isEmpty());
adminUserPage.addGroup(BPMN_ADMIN_GROUP);
adminUserPage.addGroup(BPMN_USER_GROUP);
adminUserPage.addGroup(BPMN_SUPERUSER_GROUP);
adminUserPage.clickSaveButton();
adminUserPage.searchUser(name);
adminUserPage.clickOnUserInTable(name);
assertEquals(3, adminUserPage.getListOfGroupsFromTable().size());
assertTrue(adminUserPage.getWebElementTexts(adminUserPage.getListOfGroupsFromTable()).containsAll(expectedGroups));
adminUserPage.clickEditButton();
adminUserPage.removeAllGroups();
adminUserPage.clickSaveButton();
adminUserPage.searchUser(name);
adminUserPage.clickOnUserInTable(name);
assertTrue(adminUserPage.getListOfGroupsFromTable().isEmpty());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void accessLevelGroupVisibility(Browser browser) {
openBrowserAndAdminPage(browser);
EXECUTION_MANAGER.createUserBindGroups(name, ORGANIZATION_ID, SECURITY_ADMIN_GROUP_ID);
adminUserPage.searchUser(name);
adminUserPage.clickOnUserInTable(name);
assertTrue(adminUserPage.getWebElementTexts(adminUserPage.getListOfGroupsFromTable()).contains(SECURITY_GROUP));
adminUserPage.clickEditButton();
assertFalse(adminUserPage.getWebElementTexts(adminUserPage.getListOfAvailableGroupsToAdd()).contains(SECURITY_GROUP));
assertTrue(adminUserPage.getWebElementTexts(adminUserPage.getListOfAddedGroups()).contains(SECURITY_GROUP));
adminUserPage.logout();
initQaAdminCredentials();
login(login, password);
adminUserPage = inboxPage.startAdminUser();
adminUserPage.searchUser(name);
adminUserPage.clickOnUserInTable(name);
assertFalse(adminUserPage.getWebElementTexts(adminUserPage.getListOfGroupsFromTable()).contains(SECURITY_GROUP));
adminUserPage.clickEditButton();
assertFalse(adminUserPage.getWebElementTexts(adminUserPage.getListOfAvailableGroupsToAdd()).contains(SECURITY_GROUP));
assertFalse(adminUserPage.getWebElementTexts(adminUserPage.getListOfAddedGroups()).contains(SECURITY_GROUP));
}
@Disabled("dev WEBBPMNEXT-7837")
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void userAdminPageGroupsGridSorting(Browser browser) {
openBrowserAndAdminPage(browser);
EXECUTION_MANAGER.createUserBindGroups(name, ORGANIZATION_ID, BPMN_ADMIN_GROUP_ID,
BPMN_USER_GROUP_ID, BPMN_SUPERUSER_GROUP_ID);
//User page sorting
List<String> lastNamesNatural = adminUserPage.getWebElementTexts(adminUserPage.getListOfLastNamesFromTable());
assertTrue(Comparators.isInOrder(lastNamesNatural, String.CASE_INSENSITIVE_ORDER),
"Grid wasn't sorted");
adminUserPage.changeUserPageGridsSort(AdminUserPage.UsersPageGrids.USERS_GRID);
List<String> lastNamesReverse = adminUserPage.getWebElementTexts(adminUserPage.getListOfLastNamesFromTable());
assertTrue(Comparators.isInOrder(lastNamesReverse, String.CASE_INSENSITIVE_ORDER.reversed()),
"Grid wasn't sorted");
adminUserPage.searchUser(name);
adminUserPage.clickOnUserInTable(name);
List<String> userLinkedGroupsNatural = adminUserPage.getWebElementTexts(adminUserPage.getListOfGroupsFromTable());
assertTrue(Comparators.isInOrder(userLinkedGroupsNatural, String.CASE_INSENSITIVE_ORDER),
"Grid wasn't sorted");
adminUserPage.changeUserPageGridsSort(AdminUserPage.UsersPageGrids.LINKED_GROUPS_GRID);
List<String> userLinkedGroupsReverse = adminUserPage.getWebElementTexts(adminUserPage.getListOfGroupsFromTable());
assertTrue(Comparators.isInOrder(userLinkedGroupsReverse, String.CASE_INSENSITIVE_ORDER.reversed()),
"Grid wasn't sorted");
//Edit user page sorting
adminUserPage.clickEditButton();
List<String> availableToAddGroupsNatural = adminUserPage.getWebElementTexts(adminUserPage.getListOfAvailableGroupsToAdd());
assertTrue(Comparators.isInOrder(availableToAddGroupsNatural, String.CASE_INSENSITIVE_ORDER),
"Grid wasn't sorted");
adminUserPage.changeUserPageGridsSort(AdminUserPage.UsersPageGrids.GROUPS_TO_ADD_GRID);
List<String> availableGroupsToAddReverse = adminUserPage.getWebElementTexts(adminUserPage.getListOfAvailableGroupsToAdd());
assertTrue(Comparators.isInOrder(availableGroupsToAddReverse, String.CASE_INSENSITIVE_ORDER.reversed()),
"Grid wasn't sorted");
List<String> addedGroupsNatural = adminUserPage.getWebElementTexts(adminUserPage.getListOfAddedGroups());
assertTrue(Comparators.isInOrder(addedGroupsNatural, String.CASE_INSENSITIVE_ORDER),
"Grid wasn't sorted");
adminUserPage.changeUserPageGridsSort(AdminUserPage.UsersPageGrids.ADDED_GROUPS_GRID);
List<String> addedGroupsReverse = adminUserPage.getWebElementTexts(adminUserPage.getListOfAddedGroups());
assertTrue(Comparators.isInOrder(addedGroupsReverse, String.CASE_INSENSITIVE_ORDER.reversed()),
"Grid wasn't sorted");
//Create user page sorting
adminUserPage.cancelAction();
adminUserPage.clickCreateButton();
List<String> groupsToAddNatural = adminUserPage.getWebElementTexts(adminUserPage.getListOfAvailableGroupsToAdd());
assertTrue(Comparators.isInOrder(groupsToAddNatural, String.CASE_INSENSITIVE_ORDER),
"Grid wasn't sorted");
adminUserPage.changeUserPageGridsSort(AdminUserPage.UsersPageGrids.GROUPS_TO_ADD_GRID);
List<String> groupsToAddReverse = adminUserPage.getWebElementTexts(adminUserPage.getListOfAvailableGroupsToAdd());
assertTrue(Comparators.isInOrder(groupsToAddReverse, String.CASE_INSENSITIVE_ORDER.reversed()),
"Grid wasn't sorted");
adminUserPage.addAllGroups();
List<String> addedGroupsInCreateFormNatural = adminUserPage.getWebElementTexts(adminUserPage.getListOfAddedGroups());
assertTrue(Comparators.isInOrder(addedGroupsInCreateFormNatural, String.CASE_INSENSITIVE_ORDER),
"Grid wasn't sorted");
adminUserPage.changeUserPageGridsSort(AdminUserPage.UsersPageGrids.ADDED_GROUPS_GRID);
List<String> addedGroupsInCreatedFormReverse = adminUserPage.getWebElementTexts(adminUserPage.getListOfAddedGroups());
assertTrue(Comparators.isInOrder(addedGroupsInCreatedFormReverse, String.CASE_INSENSITIVE_ORDER.reversed()),
"Grid wasn't sorted");
}
private void openBrowserAndAdminPage(Browser browser) {
openBrowserAndLoginForAdmin(browser);
initAdminName();
adminUserPage = inboxPage.startAdminUser();
}
private String randomEmail() {
String random1 = String.valueOf(20000 + (int) (Math.random() * 20000));
String random2 = String.valueOf(20000 + (int) (Math.random() * 20000));
return random1 + "@" + random2 + ".ru";
}
/*@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void addNewOrgToUser(Browser browser) {
openBrowserAndAdminPage(browser);
EXECUTION_MANAGER.createTestOrg(name);
EXECUTION_MANAGER.createUser(name, ORGANIZATION_ID);
organizationPage.clickCreateButton();
organizationPage.waitOrgEditingPageLoading();
organizationPage.fillOrgNameAndCode(name2);
organizationPage.chooseParentOrg(DEFAULT_ORG);
organizationPage.clickSaveButton();
AdminUserPage adminUserPage = inboxPage.startAdminUser();
adminUserPage.searchUser(name);
adminUserPage.clickOnUserInTable(name);
adminUserPage.clickEditButton();
adminUserPage.chooseUserOrganization(name2);
adminUserPage.fillPass(name);
adminUserPage.clickSaveButton();
}
private void openBrowserAndAdminPage(Browser browser) {
openBrowserAndLoginForAdmin(browser);
initAdminName();
name2 = name.substring(0, 3) + "2" + name.substring(3);
name3 = name.substring(0, 3) + "3" + name.substring(3);
organizationPage = inboxPage.startAdminOrganization();
assertFalse(isElementEnabled(DELETE_BUTTON));
}*/
}

View file

@ -1,141 +0,0 @@
package old;
import old.core.BaseTest;
import old.core.Browser;
import org.junit.jupiter.api.AfterEach;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import old.page.InboxPage;
import old.page.LoginPage;
import old.page.ProcessesPage;
import old.util.ExecutionManager;
import old.util.PropertyManager;
import java.io.IOException;
import java.util.Properties;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static old.page.BaseComponentPage.getLoginHeaderBy;
import static old.page.BaseComponentPage.getProgressBar;
import static old.util.DataUtil.BASE_PART_FOR_USER;
/**
* @author gulnaz
*/
public abstract class BaseComponentIT extends BaseTest {
protected static final String ACCESS_LEVEL_ID = "a6bf4b31-6648-4095-b269-2a950b548a10";
protected static final String ORGANIZATION_ID = "3516544f-64c5-4883-9047-28bcce74d1be";
protected static final String SECURITY_ADMIN_GROUP_ID = "84c5c1e2-081e-45e1-a874-d6bb232e57ad";
protected static final String BPMN_ADMIN_GROUP_ID = "ddfdc772-7aee-492f-be7d-7e95ea2f45b3";
protected static final String BPMN_USER_GROUP_ID = "62cd890b-99f7-47a8-be60-e330186b17a0";
protected static final String BPMN_SUPERUSER_GROUP_ID = "273d8bbd-0e82-4064-a548-850e9aa61756";
protected static ExecutionManager EXECUTION_MANAGER = new ExecutionManager();
protected InboxPage inboxPage;
protected ProcessesPage processPage;
protected String login;
protected String password;
protected String name;
private Properties config;
final Logger logger = LoggerFactory.getLogger(getClass());
BaseComponentIT() {
super();
initCredentialsConfig();
initCredentials();
}
@AfterEach
public void exit() {
if (processPage != null) {
assertTrue(processPage.thereIsNoError());
}
}
public void openBrowserAndLoginForAdmin(Browser browser) {
initDriver(browser);
initDemoCredentials();
login(login, password);
}
public void openBrowserAndLoginForJbpm(Browser browser) {
initDriver(browser);
initQaAdminCredentials();
login(login, password);
}
private void initCredentialsConfig() {
try {
config = PropertyManager.getProperties();
}
catch (IOException e) {
throw new RuntimeException("Failed to get properties. " + e);
}
}
protected void initCredentials() {
login = config.getProperty("login");
password = config.getProperty("password");
}
protected void initDemoCredentials() {
login = config.getProperty("demo_login");
password = config.getProperty("demo_password");
}
protected void initQaAdminCredentials() {
login = config.getProperty("qa_admin_login");
password = config.getProperty("qa_admin_password");
}
void login(String login, String password) {
WebDriverWait wait = getExplicitWait(getDefaultTimeout());
wait.until(ExpectedConditions.invisibilityOfElementLocated(getProgressBar()));
wait.until(ExpectedConditions.visibilityOfElementLocated(getLoginHeaderBy()));
LoginPage loginPage = PageFactory.initElements(driver, LoginPage.class);
try {
inboxPage = loginPage.login(login, password);
}
catch (TimeoutException e) {
throw new RuntimeException("Failed to login", e);
}
}
void initAdminName() {
initName(BASE_PART_FOR_USER);
}
void initName(String basePart) {
String random = String.valueOf(20000 + (int) (Math.random() * 20000));
name = basePart + "-" + random;
logger.info(name + " record has been initialized");
}
protected boolean isElementEnabled (String xpath){
return driver.findElement(By.xpath(String.format(xpath))).isEnabled();
}
protected LoginPage getLoginPage() {
return PageFactory.initElements(driver, LoginPage.class);
}
public void openBrowserAndLogin(Browser browser) {
initDriver(browser);
login(login, password);
}
protected InboxPage getInboxPage() {
return PageFactory.initElements(driver, InboxPage.class);
}
}

View file

@ -1,322 +0,0 @@
package old;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.*;
import javax.crypto.SecretKey;
import old.core.Browser;
import old.core.BrowserArgumentProvider;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import old.page.InboxPage;
import old.util.PropertyManager;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static old.page.BaseComponentPage.getLoginHeaderBy;
/**
* @author gulnaz
*/
public class JWTokensIT extends BaseComponentIT {
private static final String SURNAME = "demo";
private static final String SECRET_KEY = "ZjE5ZjMxNmYtODViZC00ZTQ5LWIxZmYtOGEzYzE3Yjc1MDVk}";
private static final SecretKey SIGNING_KEY;
private static final String ACCESS_TOKEN = "Access-token";
private static final String DEMO_GROUP_ID = "22ee608b-dd9d-4633-906d-7c4efca231a0";
private static final String PROCESS_NAME = "test_process";
private static final Logger LOGGER = LoggerFactory.getLogger(JWTokensIT.class);
private static PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(11);
private Properties config;
private WebDriver newDriver;
private Set<Cookie> cookies;
static {
byte[] encodedKey = Base64.getMimeDecoder().decode(SECRET_KEY);
SIGNING_KEY = Keys.hmacShaKeyFor(encodedKey);
}
public JWTokensIT() throws IOException {
super();
config = PropertyManager.getProperties();
}
@AfterEach
public void afterEachTest() {
if (newDriver != null) {
newDriver.close();
}
EXECUTION_MANAGER.deleteTestUser(login);
}
@Override
protected void initCredentials() {
initAdminName();
login = name;
password = login;
String encodedPassword = passwordEncoder.encode(password);
EXECUTION_MANAGER.insertUser(login, encodedPassword, login + "@test.ru", ORGANIZATION_ID,
DEMO_GROUP_ID
);
}
private void pasteDeadAccessToken() {
String deadAccessToken = createDeadAccessToken(config.getProperty("login"));
Cookie cookie = driver.manage().getCookieNamed(ACCESS_TOKEN);
driver.manage().deleteCookie(cookie);
addCookie(driver, cookie, deadAccessToken);
}
private void addCookie(WebDriver driver, Cookie cookie, String value) {
driver.manage().addCookie(
new Cookie.Builder(cookie.getName(), value)
.expiresOn(cookie.getExpiry())
.path(cookie.getPath())
.build()
);
}
private String createDeadAccessToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuer("ru.cg.webbpm.components")
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(
new Date(System.currentTimeMillis() - 3600 * 1000)
)
.signWith(SIGNING_KEY)
.compact();
}
private void reopenApp() throws MalformedURLException {
int attempts = 0;
while (attempts++ < 5) {
try {
newDriver = new Augmenter().augment(new RemoteWebDriver(getGridURL(), options));
break;
}
catch (WebDriverException ignored) {
LOGGER.info("The driver did not start on " + attempts + " attempt");
}
}
newDriver.get(applicationUrl);
cookies.forEach(cookie -> addCookie(newDriver, cookie, cookie.getValue()));
newDriver.get(applicationUrl); // reopen app again
inboxPage = PageFactory.initElements(newDriver, InboxPage.class);
inboxPage.waitForPageLoad();
}
private void initDriverAndLogin(Browser browser) {
initDriver(browser);
login(login, password);
inboxPage.waitForVisibilityOf(inboxPage.adminList);
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void refreshPageWithAliveAccessToken(Browser browser) {
initDriverAndLogin(browser);
inboxPage.refreshPage();
assertTrue(inboxPage.getEmailInputsFrom(driver).isEmpty());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void goToPageWithAliveAccessToken(Browser browser) {
initDriverAndLogin(browser);
inboxPage.startAdminUser();
inboxPage.waitForPageLoad();
assertTrue(inboxPage.getEmailInputsFrom(driver).isEmpty());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void filterWithAliveAccessToken(Browser browser) {
initDriverAndLogin(browser);
inboxPage.startAdminUser();
inboxPage.waitForPageLoad();
inboxPage.waitProgressBarNotVisible();
inboxPage.searchUser(SURNAME);
assertTrue(inboxPage.getEmailInputsFrom(driver).isEmpty());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void refreshPageWithDeadAccessToken(Browser browser) {
initDriverAndLogin(browser);
pasteDeadAccessToken();
inboxPage.refreshPage();
assertTrue(inboxPage.getEmailInputsFrom(driver).isEmpty());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void goToPageWithDeadAccessToken(Browser browser) {
initDriverAndLogin(browser);
pasteDeadAccessToken();
inboxPage.startAdminUser();
inboxPage.waitForPageLoad();
assertTrue(inboxPage.getEmailInputsFrom(driver).isEmpty());
}
@Disabled("qa WEBBPMNEXT-9052")
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void filterWithDeadAccessToken(Browser browser) {
initDriverAndLogin(browser);
inboxPage.startAdminUser();
inboxPage.waitProgressBarNotVisible();
pasteDeadAccessToken();
inboxPage.searchUser(SURNAME);
inboxPage.waitForPageLoad();
assertTrue(inboxPage.getEmailInputsFrom(driver).isEmpty());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void refreshPageWithDeadRefreshToken(Browser browser) {
initDriverAndLogin(browser);
driver.manage().deleteAllCookies();
inboxPage.refreshPage();
assertFalse(inboxPage.getEmailInputsFrom(driver).isEmpty());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void goToPageWithDeadRefreshToken(Browser browser) {
initDriverAndLogin(browser);
processPage = inboxPage.startProcess(PROCESS_NAME);
processPage.waitForInitializationOf(processPage.exitButton);
driver.manage().deleteAllCookies();
processPage.exitButton.click();
inboxPage.waitForPageLoad();
assertFalse(inboxPage.getEmailInputsFrom(driver).isEmpty());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void filterWithDeadRefreshToken(Browser browser) {
initDriverAndLogin(browser);
inboxPage.startAdminUser();
inboxPage.waitProgressBarNotVisible();
driver.manage().deleteAllCookies();
inboxPage.waitForPageLoad();
inboxPage.searchUser(SURNAME);
inboxPage.waitForPageLoad();
assertFalse(inboxPage.getEmailInputsFrom(driver).isEmpty());
}
@Disabled("dev WEBBPMNEXT-9052") //включить после решения задачи
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void checkTwoAuthorizedUsersCase(Browser browser) {
initDriverAndLogin(browser);
String firstTab = driver.getWindowHandle();
cookies = driver.manage().getCookies();
inboxPage.exitApp();
getExplicitWait(getDefaultTimeout()).until(
ExpectedConditions.visibilityOfElementLocated(getLoginHeaderBy()));
((JavascriptExecutor) driver).executeScript("window.open();");
List<String> windowHandles = new ArrayList<>(driver.getWindowHandles());
driver.switchTo().window(windowHandles.get(1));
driver.get(applicationUrl);
login(login, password);
driver.switchTo().window(firstTab);
driver.get(applicationUrl);
cookies.forEach(cookie -> addCookie(driver, cookie, cookie.getValue()));
pasteDeadAccessToken();
inboxPage.refreshPage();
inboxPage.waitEmailInput();
assertFalse(inboxPage.getEmailInputsFrom(driver).isEmpty());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void filterWithNoAccessToken(Browser browser) {
initDriverAndLogin(browser);
inboxPage.startAdminUser();
inboxPage.waitProgressBarNotVisible();
driver.manage().deleteCookieNamed(ACCESS_TOKEN);
inboxPage.searchUser(SURNAME);
assertTrue(inboxPage.getEmailInputsFrom(driver).isEmpty());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void reopenWithAliveAccessToken(Browser browser) throws MalformedURLException {
initDriverAndLogin(browser);
//don't close browser in the end, we'll do that explicitly
setCloseBrowser(false);
cookies = driver.manage().getCookies();
driver.close();
driver = null;
reopenApp();
assertTrue(inboxPage.getEmailInputsFrom(newDriver).isEmpty());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void reopenWithDeadAccessToken(Browser browser) throws MalformedURLException {
initDriverAndLogin(browser);
//don't close browser in the end, we'll do that explicitly
setCloseBrowser(false);
pasteDeadAccessToken();
cookies = driver.manage().getCookies();
driver.close();
driver = null;
reopenApp();
assertTrue(inboxPage.getEmailInputsFrom(newDriver).isEmpty());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void refreshWithNoSession(Browser browser) {
initDriverAndLogin(browser);
((JavascriptExecutor) driver).executeScript(
String.format("window.localStorage.clear();")); //clear localStorage
inboxPage.refreshPage();
assertTrue(inboxPage.getEmailInputsFrom(driver).isEmpty());
}
}

View file

@ -1,404 +0,0 @@
package old.core;
import java.time.Duration;
import java.util.List;
import java.util.function.Supplier;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
/**
* @author evgeny
*/
@SuppressWarnings("UnusedDeclaration")
public abstract class BasePage {
private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(20);
private static final int PROGRESS_VISIBILITY_TIMEOUT_MS = 700;
private static final By ERROR = By.xpath("//div[contains(@class, 'toast-error')]");
private static final By INPUT_IS_ACTIVE = By.xpath("//div[contains(@class, 'input-active')]");
protected static final By PROGRESS_BAR = By.xpath("//div[@class='progress']");
protected final WebDriver driver;
protected final String uri;
public BasePage(WebDriver driver, String uri) {
this.driver = driver;
this.uri = uri;
// Check that we're on the right page.
if (!isAtUri(uri))
throw new IllegalStateException("This is not the '" + uri + "' page");
PageFactory.initElements(driver, this);
}
protected Duration getDefaultTimeout() {
return DEFAULT_TIMEOUT;
}
public static By getProgressBar() {
return PROGRESS_BAR;
}
public static By getErrorBy() {
return ERROR;
}
public boolean isAtUri(String uri) {
if (((RemoteWebDriver) driver).getCapabilities().getBrowserName().equalsIgnoreCase("internet explorer")) {
return true;
}
else {
return waitForCorrectUrl(uri, getDefaultTimeout());
}
}
/**
* Ожидание того, что URL текущей страницы содержит определенный текст.
*
* @param uri адрес текущей страницы
* @param timeout timeout ожидания
* @return <code>true</code> при корректном url
*/
private boolean waitForCorrectUrl(String uri, Duration timeout) {
return new WebDriverWait(driver, timeout).until(ExpectedConditions.urlContains(uri));
}
/**
* Ожидание видимости элемента, присутствующего в DOM.
* Видимость означает не только то, что элемент отобразился, но и то, что высота и ширина элемента больше 0.
*
* @param webElement элемент, который присутствует в DOM
* @param timeout timeout ожидания
* @return веб-элемент, как только он видим
*/
public WebElement waitForVisibilityOf(WebElement webElement, Duration timeout) {
return new WebDriverWait(driver, timeout).until(ExpectedConditions.visibilityOf(webElement));
}
/**
* Ожидание видимости элемента, присутствующего в DOM.
* Видимость означает не только то, что элемент отобразился, но и то, что высота и ширина элемента больше 0.
*
* @param webElement элемент, который присутствует в DOM
* @return веб-элемент, как только он видим
*/
public WebElement waitForVisibilityOf(WebElement webElement) {
return waitForVisibilityOf(webElement, getDefaultTimeout());
}
/**
* Ожидание появления элемента в DOM и его видимости.
* Видимость означает не только то, что элемент отобразился, но и то, что высота и ширина элемента больше 0.
*
* @param locator локатор, по которому находится элемент
* @param timeout timeout ожидания
* @return веб-элемент, как только он найден и видим
*/
public WebElement waitForVisibilityOfElementLocated(By locator, Duration timeout) {
return new WebDriverWait(driver, timeout).until(ExpectedConditions.visibilityOfElementLocated(locator));
}
/**
* Ожидание появления элемента в DOM и его видимости.
* Видимость означает не только то, что элемент отобразился, но и то, что высота и ширина элемента больше 0.
*
* @param locator локатор, по которому находится элемент
* @return веб-элемент, как только он найден и видим
*/
public WebElement waitForVisibilityOfElementLocated(By locator) {
return waitForVisibilityOfElementLocated(locator, getDefaultTimeout());
}
/**
* Ожидание появления элемента в DOM и его видимости.
* Видимость означает не только то, что элемент отобразился, но и то, что высота и ширина элемента больше 0.
*
* @param locator локатор, по которому находится элемент
* @param timeout timeout ожидания
* @param sleep длительность между опросами
* @return веб-элемент, как только он найден и видим
*/
public WebElement waitForVisibilityOfElementLocated(By locator, Duration timeout, Duration sleep) {
return new WebDriverWait(driver, timeout, sleep).until(ExpectedConditions.visibilityOfElementLocated(locator));
}
/**
* Ожидание того, что элемент невидим или не представлен в DOM.
*
* @param locator локатор, по которому находится элемент
* @param timeout timeout ожидания
* @return <code>true</code>, когда элемент невидим или не найден в DOM
*/
public boolean waitForInvisibilityOfElementLocated(By locator, Duration timeout) {
return new WebDriverWait(driver, timeout).until(ExpectedConditions.invisibilityOfElementLocated(locator));
}
/**
* Ожидание того, что элемент невидим или не представлен в DOM.
*
* @param locator локатор, по которому находится элемент
* @return <code>true</code>, когда элемент невидим или не найден в DOM
*/
public boolean waitForInvisibilityOfElementLocated(By locator) {
return waitForInvisibilityOfElementLocated(locator, getDefaultTimeout());
}
/**
* Ожидание того, что элемент больше не прикреплен к DOM
*
* @param webElement проверяемый элемент
* @param timeout timeout ожидания
* @return <code>true</code>, когда элемент больше не прикреплен к DOM
*/
public boolean waitForStalenessOf(WebElement webElement, Duration timeout) {
return new WebDriverWait(driver, timeout).until(ExpectedConditions.stalenessOf(webElement));
}
/**
* Ожидание того, что элемент больше не прикреплен к DOM
*
* @param webElement проверяемый элемент
* @return <code>true</code>, когда элемент больше не прикреплен к DOM
*/
public boolean waitForStalenessOf(WebElement webElement) {
return waitForStalenessOf(webElement, getDefaultTimeout());
}
/**
* Ожидание наличия текста в элементе, соответствующем указанному локатору.
*
* @param locator локатор, по которому находится элемент
* @param text проверяемый текст
* @param timeout timeout ожидания
* @return <code>true</code> при наличии текста в элементе
*/
public boolean waitForTextToBePresentInElementLocated(By locator, String text, Duration timeout) {
return new WebDriverWait(driver, timeout).until(ExpectedConditions.textToBePresentInElementLocated(locator, text));
}
/**
* Ожидание наличия текста в элементе, соответствующем указанному локатору.
*
* @param locator локатор, по которому находится элемент
* @param text проверяемый текст
* @return <code>true</code> при наличии текста в элементе
*/
public boolean waitForTextToBePresentInElementLocated(By locator, String text) {
return waitForTextToBePresentInElementLocated(locator, text, getDefaultTimeout());
}
/**
* Ожидание наличия текста в определенном элементе
*
* @param webElement проверяемый элемент
* @param text проверяемый текст
* @param timeout timeout ожидания
* @return <code>true</code> при наличии текста в элементе
*/
public boolean waitForTextToBePresentInElement(WebElement webElement, String text, Duration timeout) {
return new WebDriverWait(driver, timeout).until(ExpectedConditions.textToBePresentInElement(webElement, text));
}
/**
* Ожидание наличия текста в определенном элементе
*
* @param webElement проверяемый элемент
* @param text проверяемый текст
* @return <code>true</code> при наличии текста в элементе
*/
public boolean waitForTextToBePresentInElement(WebElement webElement, String text) {
return waitForTextToBePresentInElement(webElement, text, getDefaultTimeout());
}
/**
* Ожидание видимости и доступности присутствующего в DOM элемента для нажатия.
*
* @param webElement проверяемый элемент
* @param timeout timeout ожидания
* @return веб-элемент, как только он доступен для нажатия
*/
public WebElement waitForElementToBeClickable(WebElement webElement, Duration timeout) {
return new WebDriverWait(driver, timeout).until(ExpectedConditions.elementToBeClickable(webElement));
}
/**
* Ожидание видимости и доступности присутствующего в DOM элемента для нажатия.
*
* @param webElement проверяемый элемент
* @return веб-элемент, как только он доступен для нажатия
*/
public WebElement waitForElementToBeClickable(WebElement webElement) {
return waitForElementToBeClickable(webElement, getDefaultTimeout());
}
/**
* Ожидание появления элемента в DOM, видимости и доступности элемента для нажатия.
*
* @param locator локатор, по которому находится элемент
* @param timeout timeout ожидания
* @return веб-элемент, как только он доступен для нажатия
*/
public WebElement waitForElementToBeClickable(By locator, Duration timeout) {
return new WebDriverWait(driver, timeout).until(ExpectedConditions.elementToBeClickable(locator));
}
/**
* Ожидание появления элемента в DOM, видимости и доступности элемента для нажатия.
*
* @param locator локатор, по которому находится элемент
* @return веб-элемент, как только он доступен для нажатия
*/
public WebElement waitForElementToBeClickable(By locator) {
return waitForElementToBeClickable(locator, getDefaultTimeout());
}
/**
* Ожидание определенного количества элементов с указанным локатором.
*
* @param locator локатор, по которому находится элемент
* @param number ожидаемое число элементов
* @param timeout timeout ожидания
* @return список элементов с определенным количеством
*/
public List<WebElement> waitForNumberOfElementsToBe(By locator, int number, Duration timeout) {
return new WebDriverWait(driver, timeout).until(ExpectedConditions.numberOfElementsToBe(locator, number));
}
/**
* Ожидание определенного количества элементов с указанным локатором.
*
* @param locator локатор, по которому находится элемент
* @param number ожидаемое число элементов
* @return список элементов с определенным количеством
*/
public List<WebElement> waitForNumberOfElementsToBe(By locator, int number) {
return waitForNumberOfElementsToBe(locator, number, getDefaultTimeout());
}
/**
* Ожидание того, что как минимум один элемент с указанным локатором представлен на странице.
* Полезно, когда нужно подождать динамический элемент.
*
* @param locator локатор, по которому находится элемент
* @param timeout timeout ожидания
* @return список элементов с указанным локатором
*/
public List<WebElement> waitForPresenceOfAllElementsLocatedBy(By locator, Duration timeout) {
return new WebDriverWait(driver, timeout).until(ExpectedConditions.presenceOfAllElementsLocatedBy(locator));
}
/**
* Ожидание того, что как минимум один элемент с указанным локатором представлен на странице.
* Полезно, когда нужно подождать динамический элемент.
*
* @param locator локатор, по которому находится элемент
* @return список элементов с указанным локатором
*/
public List<WebElement> waitForPresenceOfAllElementsLocatedBy(By locator) {
return waitForPresenceOfAllElementsLocatedBy(locator, getDefaultTimeout());
}
/**
* Ожидание того, что указзнный элемент содержит атрибут с определенным значением
*
* @param webElement проверяемый элемент
* @param attribute проверяемый атрибут
* @param value проверяемое значение
* @param timeout timeout ожидания
* @return <code>true</code> при наличии значения в атрибуте
*/
public boolean waitForAttributeContains(WebElement webElement, String attribute, String value, Duration timeout) {
return new WebDriverWait(driver, timeout).until(ExpectedConditions.attributeContains(webElement, attribute, value));
}
/**
* Ожидание того, что указзнный элемент содержит атрибут с определенным значением
*
* @param webElement проверяемый элемент
* @param attribute проверяемый атрибут
* @param value проверяемое значение
* @return <code>true</code> при наличии значения в атрибуте
*/
public boolean waitForAttributeContains(WebElement webElement, String attribute, String value) {
return waitForAttributeContains(webElement, attribute, value, getDefaultTimeout());
}
public void sleep(long millis) {
BaseTest.sleep(millis);
}
private void waitForCondition(Supplier<Boolean> condition, long timeOutInMillis) {
long startTime = System.currentTimeMillis();
while (!condition.get()) {
if (System.currentTimeMillis() - startTime >= timeOutInMillis) {
break;
}
sleep(100);
}
}
private void waitProgressBarVisible(long timeOutInMillis) {
waitForCondition(
() -> driver.findElements(PROGRESS_BAR).size() > 0,
timeOutInMillis
);
}
//ожидается, что последний инпут, по которому был клик, выбран
public void waitForInputFieldSelected() {
waitForNumberOfElementsToBe(INPUT_IS_ACTIVE, 1);
}
//ожидается пока пропадет прогресс бар
public void waitProgressBarNotVisible(Duration timeout) {
waitForInvisibilityOfElementLocated(PROGRESS_BAR, timeout);
}
//ожидается пока пропадет прогресс бар с таймаутом по умолчанию
public void waitProgressBarNotVisible() {
waitForInvisibilityOfElementLocated(PROGRESS_BAR, getDefaultTimeout());
}
//проверяется отсутствие ошибок
public boolean thereIsNoError() {
return getErrors().isEmpty();
}
//получить первую ошибку
public WebElement getError() {
return getErrors().get(0);
}
//получить все ошибки
public List<WebElement> getErrors() {
waitForCondition(
() -> driver.findElements(ERROR).size() > 0,
500
);
return driver.findElements(ERROR);
}
//переключиться на другую вкладку
public void goToAnotherTab(String tab) {
waitProgressBarNotVisible(Duration.ofSeconds(10));
driver.switchTo().window(tab);
}
//обновить страницу
public void refreshPage() {
driver.navigate().refresh();
waitProgressBarNotVisible();
}
public void waitForPageLoad() {
waitProgressBarNotVisible();
waitProgressBarVisible(PROGRESS_VISIBILITY_TIMEOUT_MS);
waitProgressBarNotVisible();
}
}

View file

@ -1,273 +0,0 @@
package old.core;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.TimeZone;
import java.util.logging.Level;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.AbstractDriverOptions;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import static old.core.BasePage.getErrorBy;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author gulnaz
*/
public abstract class BaseTest {
protected static final String gridUrl;
protected static final String applicationUrl;
private static final Logger LOGGER = LoggerFactory.getLogger(BaseTest.class);
private static final String UNDERSCORE = "_";
private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(20);
private static final Duration TIMEOUT = Duration.ofSeconds(3);
private static final int WINDOW_WIDTH = 945;
@RegisterExtension
protected ScreenWatcher screenWatcher = new ScreenWatcher();
protected WebDriver driver;
protected AbstractDriverOptions options;
private boolean closeBrowser = true;
private TestInfo testInfo;
static {
gridUrl = System.getProperty("selenium.grid.url");
applicationUrl = System.getProperty("application.url");
LOGGER.info("application.url: {}", applicationUrl);
LOGGER.info("grid.url: {}", gridUrl);
}
@BeforeEach
void beforeEach(TestInfo testInfo) {
this.testInfo = testInfo;
}
@AfterEach
void tearDown() {
if (closeBrowser && driver != null) {
driver.quit();
}
}
public static void sleep(long millis) {
try {
Thread.sleep(millis);
}
catch (InterruptedException e) {
throw new RuntimeException("Something went wrong...", e);
}
}
public URL getGridURL() throws MalformedURLException {
return new URL(gridUrl);
}
protected void initDriver(Browser browser) {
System.setProperty("webdriver.http.factory", "jdk-http-client");
try {
options = browser.getOptions().newInstance();
}
catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException("Failed to create capabilities", e);
}
options.setCapability("selenoid:options", new HashMap<String, Object>() {
{
put("enableLog", Boolean.valueOf(System.getProperty("enableLog")));
put("enableVNC", Boolean.valueOf(System.getProperty("enableVNC")));
put("enableVideo", Boolean.valueOf(System.getProperty("enableVideo")));
put("sessionTimeout", "3m");
put("logName", getFileName(testInfo.getTestClass(), testInfo.getTestMethod(), testInfo.getDisplayName() + ".log"));
put("videoName", getFileName(testInfo.getTestClass(), testInfo.getTestMethod(), testInfo.getDisplayName() + ".mp4"));
}
});
if (System.getProperty("enableLog") != null && browser == Browser.CHROME) {
LoggingPreferences logPrefs = new LoggingPreferences();
logPrefs.enable(LogType.BROWSER, Level.ALL);
logPrefs.enable(LogType.CLIENT, Level.ALL);
logPrefs.enable(LogType.DRIVER, Level.ALL);
logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
logPrefs.enable(LogType.PROFILER, Level.ALL);
logPrefs.enable(LogType.SERVER, Level.ALL);
options.setCapability("goog:loggingPrefs", logPrefs);
}
LOGGER.info("try to create RemoteWebDriver, " + testInfo.getDisplayName());
int attempts = 0;
while (attempts++ < 5) {
try {
URL gridUrl = getGridURL();
driver = new RemoteWebDriver(gridUrl, options);
break;
}
catch (WebDriverException ignored) {
LOGGER.info("The driver did not start on " + attempts + " attempt");
}
catch (MalformedURLException e) {
throw new RuntimeException("Invalid grid URL", e);
}
}
if (driver == null) {
throw new RuntimeException("Failed to create driver for " + testInfo.getDisplayName());
}
LOGGER.info("RemoteWebDriver created, " + testInfo.getDisplayName());
// Configure to upload local files to remote Selenium instance
((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
driver.manage().window().maximize();
//TODO после обновления selenium (4.9.0 <) необходимо перепроверить maximize()
if (getWindowWidth(driver) < WINDOW_WIDTH) { //.maximize() не срабатывает с первого раза
driver.manage().window().maximize();
}
driver.manage().window().maximize();
driver.get(applicationUrl);
assertTrue(waitForCorrectWindowWidth(),
String.format("browser window size is less than and not equal to as expected: expected - %dpx, actual - %dpx",
WINDOW_WIDTH, driver.manage().window().getSize().getWidth()));
assertTrue(getExplicitWait(TIMEOUT)
.until(ExpectedConditions.invisibilityOfElementLocated(getErrorBy())),
"an error occurred while opening application");
}
private int getWindowWidth(WebDriver webDriver) {
return webDriver.manage().window().getSize().getWidth();
}
protected Duration getDefaultTimeout() {
return DEFAULT_TIMEOUT;
}
protected WebDriverWait getExplicitWait(Duration timeout) {
return new WebDriverWait(driver, timeout);
}
protected void setCloseBrowser(boolean closeBrowser) {
this.closeBrowser = closeBrowser;
}
private boolean waitForCorrectWindowWidth() {
try {
return getExplicitWait(TIMEOUT)
.until(webDriver -> webDriver.manage().window().getSize().getWidth() >= WINDOW_WIDTH);
}
catch (TimeoutException ignored) {
return false;
}
}
private String getFileName(Optional<Class<?>> testClass, Optional<Method> testMethod, String displayName) {
String fileName = "";
if (testClass.isPresent()) {
fileName = testClass.get().getSimpleName() + UNDERSCORE;
}
if (testMethod.isPresent()) {
fileName += testMethod.get().getName() + UNDERSCORE;
}
fileName += displayName;
return fileName;
}
private String getFileName(ExtensionContext context) {
return getFileName(context.getTestClass(), context.getTestMethod(), context.getDisplayName());
}
public class ScreenWatcher implements AfterTestExecutionCallback {
private static final String PATH = "target";
private static final String EXTENSION = "jpg";
private File scrFile;
@Override
public void afterTestExecution(ExtensionContext context) throws Exception {
LOGGER.info("afterTestExecution");
boolean failed = context.getExecutionException().isPresent();
if (!failed) {
if (scrFile != null)
scrFile.delete();
}
else {
LOGGER.info("test failed");
if (driver == null)
return;
saveScreen(getFileName(context));
for (String type : driver.manage().logs().getAvailableLogTypes()) {
List<LogEntry> logEntries = driver.manage().logs().get(type).getAll();
if (logEntries.isEmpty()) {
continue;
}
LOGGER.info("Logging browser messages for type: " + type);
for (LogEntry entry : logEntries) {
LocalDateTime localdateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(entry.getTimestamp()), TimeZone.getDefault().toZoneId());
String dateTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(localdateTime);
LOGGER.warn(dateTime + " " + entry.getLevel() + " " + entry.getMessage());
}
LOGGER.info("Logged browser messages for type: " + type);
}
}
}
public void saveScreen(String fileName) {
try {
TakesScreenshot takesScreenshot = (TakesScreenshot) driver;
scrFile = takesScreenshot.getScreenshotAs(OutputType.FILE);
Path destFile = Paths.get("", PATH, fileName + "." + EXTENSION);
Files.copy(scrFile.toPath(), destFile, StandardCopyOption.REPLACE_EXISTING);
}
catch (IOException e) {
throw new RuntimeException("Failed to capture screen", e);
}
}
}
}

View file

@ -1,28 +0,0 @@
package old.core;
import org.openqa.selenium.remote.AbstractDriverOptions;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.firefox.FirefoxOptions;
/**
* @author gulnaz
*/
public enum Browser {
CHROME(ChromeOptions.class),
FIREFOX(FirefoxOptions.class);
private final Class<? extends AbstractDriverOptions> options;
Browser(Class<? extends AbstractDriverOptions> options) {
this.options = options;
}
public Class<? extends AbstractDriverOptions> getOptions() {
return options;
}
@Override
public String toString() {
return name().toLowerCase();
}
}

View file

@ -1,24 +0,0 @@
package old.core;
import java.util.stream.Stream;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.ArgumentsProvider;
public class BrowserArgumentProvider implements ArgumentsProvider {
@Override
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
String browsers = System.getProperty("browsers");
if ("all".equals(browsers)) {
return Stream.of(
Arguments.of(Browser.CHROME),
Arguments.of(Browser.FIREFOX));
}
return Stream.of(
Arguments.of(Browser.CHROME));
}
}

View file

@ -1,199 +0,0 @@
package old.page;
import org.openqa.selenium.*;
import java.util.List;
import java.util.stream.Collectors;
import java.time.Duration;
/**
* @author kote
*/
public class AdminGroupPage extends BaseComponentPage {
private static final String AVAILABLE_TO_ADD_TABLE = "//*[@object-name='AvailableRecordsGrid']";
private static final String ADDED_TABLE = "//*[@object-name='LinkFieldDialog']";
private static final String LINKED_ROLE_TABLE = "//*[@object-name='RolesGrid']";
private static final String GROUP_NAMES_TABLE = "//*[@object-name='Grid']";
private static final String ROW_BY_NAME = "//div[@role='row']//div[contains(.,'%s')]";
private static final String CELL_WITH_GROUP_NAME = "//div[@col-id='group$name']//span[contains(text(),'%s')]";
private static final String ROLE_TO_ADD_BY_NAME = AVAILABLE_TO_ADD_TABLE + ROW_BY_NAME;
private static final By LINKED_ROLES_GRID = By.xpath(
LINKED_ROLE_TABLE + "//div[@col-id='role$name']" + EXCLUDE_HEADER);
private static final By ROLES_AVAILABLE_TO_ADD_GRID = By.xpath(
AVAILABLE_TO_ADD_TABLE + "//div[@col-id='role$name']" + EXCLUDE_HEADER);
private static final By ADDED_ROLES_GRID = By.xpath(
ADDED_TABLE + "//div[@role='gridcell']" + EXCLUDE_HEADER + "[@col-id='role$name']");
private static final By GROUP_NAMES_GRID = By.xpath(
GROUP_NAMES_TABLE + "//div[@col-id='role$name']" + EXCLUDE_HEADER);
private static final By GRID_BODY = By.xpath(
"//div[@class='ag-center-cols-container']" + "[//div[@role='row']" + EXCLUDE_HEADER + "]");
private static final By ROLE_TO_ADD_TABLE_HEADER = By.xpath(
AVAILABLE_TO_ADD_TABLE + "//div[@col-id='role$name']" + AG_HEADER);
private static final By ADDED_ROLES_TABLE_HEADER = By.xpath(
ADDED_TABLE + "//div[@col-id='role$name']" + AG_HEADER);
private static final By GROUP_NAMES_TABLE_HEADER = By.xpath(
GROUP_NAMES_TABLE + "//div[@col-id='role$name']" + AG_HEADER);
private static final By LINKED_ROLES_TABLE_HEADER = By.xpath(
LINKED_ROLE_TABLE + "//div[@col-id='role$name']" + AG_HEADER);
public AdminGroupPage(WebDriver browser) {
super(browser, "/#/");
}
public void searchGroup(String groupName) {
waitProgressBarNotVisible();
waitForVisibilityOf(searchField);
typeTextOnAdminFilter(searchField, groupName);
waitForInvisibilityGridDownloader();
}
public void chooseGroup(String groupName) {
searchGroup(groupName);
getListOfGroupsNamesFromTable(groupName).get(0).click();
waitProgressBarNotVisible();
waitForPageLoad();
}
public void deleteGroup() {
waitProgressBarNotVisible();
clickDeleteButton();
clickConfirmButton();
}
public List<WebElement> getListOfGroupsNamesFromTable(String name) {
return driver.findElements(By.xpath(String.format(CELL_WITH_GROUP_NAME, name)));
}
public List<WebElement> getListOfRolesFromLinkedTable() {
return driver.findElements(LINKED_ROLES_GRID);
}
public List<WebElement> getListOfRolesToAdd() {
return driver.findElements(ROLES_AVAILABLE_TO_ADD_GRID);
}
public boolean isGridEmpty() {
try {
waitForInvisibilityOfElementLocated(GRID_BODY, Duration.ofSeconds(5));
return true;
}
catch (TimeoutException t) {
return false;
}
}
/**
* Method to avoid parallel test conflicts.
* <p>
* If the list of roles available to adding is not empty, checks if the list contains only newly
* created roles.
* </p>
*
* @param roleNames list retrieved from the database before the parallel test created a role.
* @return value of {@link Boolean} type.
* <p>
* True - if list of roles available for adding is empty, or contains only newly created roles
* from parallel tests.
* </p>
* <p>
* False - if list of roles available for adding contains values from roleNames list.
* </p>
*/
public boolean isAvailableGridEmpty(List<String> roleNames) {
List<String> possibleParallelAddedRole = getListOfRolesToAdd()
.stream()
.map(WebElement::getText)
.collect(Collectors.toList());
if (possibleParallelAddedRole.isEmpty()) {
return true;
}
else {
return roleNames
.stream()
.noneMatch(possibleParallelAddedRole::contains);
}
}
public void addRole(String roleName, boolean needSort) {
if (needSort) {
waitForVisibilityOfElementLocated(ROLE_TO_ADD_TABLE_HEADER).click();
}
By cell = By.xpath(String.format(ROLE_TO_ADD_BY_NAME, roleName));
waitForVisibilityOfElementLocated(By.xpath(String.format(ROLE_TO_ADD_BY_NAME, roleName))).click();
waitForPageLoad();
clickAddButton();
waitProgressBarNotVisible();
}
public void removeRole(String roleName) {
waitForVisibilityOfElementLocated(By.xpath(String.format(ADDED_TABLE + ROW_BY_NAME, roleName))).click();
clickRemoveButton();
waitProgressBarNotVisible();
}
public void addAllRoles() {
clickAddAllButton();
waitProgressBarNotVisible();
}
public void removeAllRoles() {
clickRemoveAllButton();
waitProgressBarNotVisible();
}
public boolean hasRolesInTable(GroupPageGrids tableName, String... roleNames) {
String table = tableName == GroupPageGrids.ADDED_ROLES_GRID ? ADDED_TABLE :
AVAILABLE_TO_ADD_TABLE;
for (String roleName : roleNames) {
List<WebElement> roles = driver.findElements(By.xpath(table + String.format(ROW_BY_NAME, roleName)));
if (roles.isEmpty()) {
return false;
}
}
return true;
}
public List<WebElement> getListOfAddedRoles() {
return driver.findElements(ADDED_ROLES_GRID);
}
public List<WebElement> getListOfGroupNames() {
return driver.findElements(GROUP_NAMES_GRID);
}
public void bindRole(String roleName) {
waitForVisibilityOf(addButton);
addRole(roleName, false);
waitProgressBarNotVisible();
}
public void typeAndSelectLevel(String level) {
typeTextAndSelectOption("access_level", level, level);
}
public void changeGroupPageGridSort(GroupPageGrids value) {
switch (value) {
case ROLES_TO_ADD_GRID:
driver.findElement(ROLE_TO_ADD_TABLE_HEADER).click();
break;
case LINKED_ROLES_GRID:
driver.findElement(LINKED_ROLES_TABLE_HEADER).click();
break;
case ADDED_ROLES_GRID:
driver.findElement(ADDED_ROLES_TABLE_HEADER).click();
case GROUP_NAMES_GRID:
driver.findElement(GROUP_NAMES_TABLE_HEADER).click();
}
waitForPageLoad();
}
public enum GroupPageGrids {
ADDED_ROLES_GRID,
ROLES_TO_ADD_GRID,
LINKED_ROLES_GRID,
GROUP_NAMES_GRID
}
}

View file

@ -1,92 +0,0 @@
package old.page;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import java.util.List;
import java.time.Duration;
/**
* @author kote
*/
public class AdminOrgPage extends BaseComponentPage {
private static final By CELL_WITH_NAME = By.xpath(
"//*[@object-name='Древовидная таблица']//div[@col-id='name'][not(contains(@class,'ag-header'))]//span[@class='ag-group-value']");
private static final By GRID_BODY =
By.xpath("//div[@class='ag-center-cols-container'][//div[@role='row'][not(contains(@class,'ag-header'))]]");
private static final String PLUS_IN_CELL_WITH_NAME =
"//div[@col-id='name'][//span[contains(text(), '%s')]]//span[@ref='eContracted']";
private static final String CHECKBOX_BY_NAME =
"//div[@col-id='name'][.//span[contains(text(), '%s')]]//div[contains(@class,'ag-selection-checkbox')]";
//Organization Editing Page
@FindBy(xpath = "//*[@object-name='Группа фильтров']//input")
private WebElement searchField;
@FindBy(xpath = "//div[label[span[contains(.,'Наименование')]]]//input")
public WebElement nameField;
@FindBy(xpath = "//div[label[span[contains(.,'Код')]]]//input")
private WebElement codeField;
public AdminOrgPage(WebDriver browser) {
super(browser, "/#/");
}
public void fillOrgNameAndCode(String name) {
typeText(nameField, name);
typeText(codeField, name);
}
public void chooseParentOrg(String parentOrgName) {
typeTextAndSelectOption("Выпадающий список (с возможностью сохранения)", parentOrgName, parentOrgName);
}
public void searchOrg(String name) {
typeTextOnAdminFilter(searchField, name);
waitForInvisibilityGridDownloader();
}
public List<WebElement> getListOfOrganizationsFromTable() {
return driver.findElements(CELL_WITH_NAME);
}
public void clickOnPlusSign(String orgName) {
waitForVisibilityOfElementLocated(By.xpath(String.format(PLUS_IN_CELL_WITH_NAME, orgName))).click();
waitProgressBarNotVisible();
}
public void searchAndClickOnOrg(String name) {
if (driver.findElements(By.xpath(String.format(CHECKBOX_BY_NAME, name))).isEmpty()) {
searchOrg(name);
}
waitForVisibilityOfElementLocated(By.xpath(String.format(CHECKBOX_BY_NAME, name))).click();
waitForPageLoad();
}
public void deleteOrg() {
clickDeleteButton();
confirmAction();
}
public void cancelEditingOrg() {
clickCancelButton();
confirmAction();
}
private void confirmAction() {
clickConfirmButton();
waitProgressBarNotVisible();
waitForPageLoad();
}
public void waitGridEmpty() {
waitForInvisibilityOfElementLocated(GRID_BODY, Duration.ofSeconds(60));
}
public void waitOrgEditingPageLoading() {
waitForPageLoad();
waitForVisibilityOf(nameField);
}
}

View file

@ -1,73 +0,0 @@
package old.page;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
public class AdminProcessPage extends BaseComponentPage {
private static final By modalMessage = By.xpath("//div[contains(@class, 'modal-body')][contains(., 'Вы действительно хотите')]");
@FindBy(css = "div[col-id = 'process$start_date']")
private List<WebElement> dates;
private static final String PROCESS_XPATH = "//div[@row-id='%s'][.//div[contains(.,'%s')]]";
public AdminProcessPage(WebDriver browser) {
super(browser, "/#/process/instance");
}
private By getProcessBy(String processId, String processName) {
return By.xpath(String.format(PROCESS_XPATH, processId, processName));
}
public WebElement getProcessFromProcessInstanceTable(String processName, String processId) {
By processLocator = (getProcessBy(processId, processName));
return waitForVisibilityOfElementLocated(processLocator);
}
public boolean isNoProcessFound(String processName, String processId) {
By processLocator = (getProcessBy(processId, processName));
if (!driver.findElements(FIRST_ROW_BY).isEmpty()) {
}
return driver.findElements(processLocator).isEmpty();
}
//прервать процесс
public void stopProcess(String processName, String processId) {
getProcessFromProcessInstanceTable(processName, processId).click();
clickStopButton();
waitForVisibilityOfElementLocated(modalMessage);
clickConfirmButton();
waitForInvisibilityOfElementLocated(modalMessage);
}
//переключиться между вкладками с помощью радиобатона
public void changeRadioTab(String radioButtonTab) {
waitProgressBarNotVisible();
WebElement radioTab = driver.findElement(By.xpath("//label[.//span[contains(.,'" + radioButtonTab + "')]]//input"));
radioTab.click();
waitProgressBarNotVisible();
}
//переключится на вкладку завершенных процессов
public void goToFinishedTab() {
changeRadioTab("Завершенные");
waitForPageLoad();
}
//переключится на вкладку прерванных процессов
public void goToStopedTab() {
changeRadioTab("Прерванные");
waitForPageLoad();
}
public String getDateStringByRowNumber(Integer rowNumber) {
return dates.get(rowNumber).getText();
}
}

View file

@ -1,76 +0,0 @@
package old.page;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import java.util.List;
/**
* @author kote
*/
public class AdminRolePage extends BaseComponentPage {
private static final String CELL_WITH_ROLE_NAME = "//div[@col-id='role$name']//span[contains(text(),'%s')]";
private static final String LINK_GROUP_TABLE = "//*[@object-name='GroupsGrid']";
private static final String ROLE_NAME_TABLE = "//*[@object-name='Grid']";
private static final By LINKED_GROUP_GRID = By.xpath(LINK_GROUP_TABLE + "//div[@col-id='group$name']" + EXCLUDE_HEADER);
private static final By ROLE_NAMES_GRID = By.xpath(ROLE_NAME_TABLE + "//div[@col-id='role$name']" + EXCLUDE_HEADER);
private static final By LINKED_GROUP_GRID_HEADER = By.xpath(LINK_GROUP_TABLE + "//div[@col-id='group$name']" + AG_HEADER);
private static final By ROLE_NAMES_GRID_HEADER = By.xpath(ROLE_NAME_TABLE + "//div[@col-id='role$name']" + AG_HEADER);
public AdminRolePage(WebDriver browser) {
super(browser, "/#/");
}
public void searchRole(String roleName) {
waitProgressBarNotVisible();
waitForVisibilityOf(searchField);
typeTextOnAdminFilter(searchField, roleName);
waitForInvisibilityGridDownloader();
waitForPageLoad();
}
public void chooseRole(String roleName) {
searchRole(roleName);
getListOfRolesNamesFromTable(roleName).get(0).click();
waitForInvisibilityGridDownloader();
}
public void deleteRole() {
waitProgressBarNotVisible();
clickDeleteButton();
clickConfirmButton();
waitProgressBarNotVisible();
}
public List<WebElement> getListOfRolesNamesFromTable(String name) {
return driver.findElements(By.xpath(String.format(CELL_WITH_ROLE_NAME, name)));
}
public List<WebElement> getListOfRoleLinkedGroups() {
return driver.findElements(LINKED_GROUP_GRID);
}
public List<WebElement> getListOfRoles() {
return driver.findElements(ROLE_NAMES_GRID);
}
public void changeRolePageGridSort(RolePageGrids value) {
switch (value) {
case GROUP_NAMES_GRID:
driver.findElement(LINKED_GROUP_GRID_HEADER).click();
break;
case ROLE_NAMES_GRID:
driver.findElement(ROLE_NAMES_GRID_HEADER).click();
break;
}
waitForPageLoad();
}
public enum RolePageGrids {
ROLE_NAMES_GRID,
GROUP_NAMES_GRID
}
}

View file

@ -1,246 +0,0 @@
package old.page;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.FindBy;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author kote
*/
public class AdminUserPage extends BaseComponentPage {
private static final String TABLE_TO_ADD = "//*[@object-name='AvailableRecordsGrid']";
private static final String TABLE_ADDED = "//*[@object-name='LinkFieldDialog for save']";
private static final String USER_TABLE = "//*[@object-name='Grid']";
private static final String LINK_GROUP_TABLE = "//*[@object-name='DependentGrid']";
private static final String ROW_BY_NAME = "//div[@role='row']//div[contains(.,'%s')]";
private static final By CELL_WITH_LAST_NAME = By.xpath(USER_TABLE + "//div[@col-id='user$lastName']" + EXCLUDE_HEADER);
private static final By CELL_WITH_FIRST_NAME = By.xpath(USER_TABLE + "//div[@col-id='user$firstName']" + EXCLUDE_HEADER);
private static final By CELL_WITH_MIDDLE_NAME = By.xpath(USER_TABLE + "//div[@col-id='user$middleName']" + EXCLUDE_HEADER);
private static final By GROUP_IN_TABLE = By.xpath(LINK_GROUP_TABLE + "//div[@col-id='group$name']" + EXCLUDE_HEADER);
private static final By CELL_WITH_LAST_NAME_HEADER = By.xpath(USER_TABLE + "//div[@col-id='user$lastName']" + AG_HEADER);
private static final By GROUP_IN_TABLE_HEADER = By.xpath(LINK_GROUP_TABLE + "//div[@col-id='group$name']" + AG_HEADER);
private static final By GROUP_TO_ADD_HEADER = By.xpath(TABLE_TO_ADD + "//div[@col-id='group$name']" + AG_HEADER);
private static final By ADDED_GROUPS_HEADER = By.xpath(TABLE_ADDED + "//div[@col-id='group$name']" + AG_HEADER);
private static final By GROUP_TO_ADD = By.xpath(TABLE_TO_ADD + "//div[@col-id='group$name']" + EXCLUDE_HEADER);
private static final By ADDED_GROUPS = By.xpath(TABLE_ADDED + "//div[@role='gridcell']" + EXCLUDE_HEADER + "[@col-id='group$name']");
private static final By LOGOUT_BUTTON = By.xpath("//div[@class ='fa fa-power-off']");
//User Administration Page
@FindBy(xpath = "//*[contains(text(),'Фильтр по пользователям')]")
public WebElement filterPanel;
//User Editing Page
@FindBy(xpath = "//*[@object-name='last-name']//input")
public WebElement lastNameField;
@FindBy(xpath = "//div[@class='logout']//button[contains(@class,'nav-link')]")
public WebElement userMenuButton;
@FindBy(xpath = "//button[contains(.,'Выход')]")
public WebElement exitButton;
@FindBy(xpath = "//*[@object-name='first-name']//input")
private WebElement firstNameField;
@FindBy(xpath = "//*[@object-name='middleName']//input")
private WebElement middleNameField;
@FindBy(xpath = "//*[@object-name='login']//input")
private WebElement loginField;
@FindBy(xpath = "//*[@object-name='last-name']//input")
private WebElement surNameField;
@FindBy(xpath = "//*[@object-name='password']//input")
private WebElement passwordField;
@FindBy(xpath = "//*[@object-name='password-repeat']//input")
private WebElement passwordRepeatField;
@FindBy(xpath = "//*[@object-name='email']//input")
private WebElement emailField;
@FindBy(xpath = "//div[@row-index='0']//div[@col-id='checkbox_uid']")
private List<WebElement> listGroupsToAdd;
public AdminUserPage(WebDriver browser) {
super(browser, "/#/");
}
public void fillUserFullName(String userName) {
typeText(lastNameField, userName);
typeText(firstNameField, userName);
typeText(middleNameField, userName);
}
public void fillUserCredentials(String userName, String userPassword, String userEmail,
String userOrganization, String fullOrganizationName) {
typeText(loginField, userName);
fillPassAndEmail(userPassword, userEmail);
chooseUserOrganization(userOrganization, fullOrganizationName);
}
public void chooseUserOrganization(String userOrganization, String fullOrganizationName) {
typeTextAndSelectOption("org_unit_id", userOrganization, fullOrganizationName);
}
public void chooseUserOrganization(String userOrganization) {
typeTextAndSelectOption("org_unit_id", userOrganization, userOrganization);
}
public void fillPassAndEmail(String userPassword, String userEmail) {
fillPass(userPassword);
typeText(emailField, userEmail);
}
public void fillPass(String userPassword) {
typeText(passwordField, userPassword);
typeText(passwordRepeatField, userPassword);
}
public void searchUser(String userSurName) {
filterPanel.click();
waitForPageLoad();
typeTextOnAdminFilter(surNameField, userSurName);
waitForInvisibilityGridDownloader();
}
public void deleteUser() {
waitProgressBarNotVisible();
clickDeleteButton();
clickConfirmButton();
waitProgressBarNotVisible();
}
public List<WebElement> getListOfLastNamesFromTable() {
return driver.findElements(CELL_WITH_LAST_NAME);
}
public List<WebElement> getListOfFirstNamesFromTable() {
return driver.findElements(CELL_WITH_FIRST_NAME);
}
public List<WebElement> getListOfMiddleNamesFromTable() {
return driver.findElements(CELL_WITH_MIDDLE_NAME);
}
public List<WebElement> getListOfGroupsFromTable() {
return driver.findElements(GROUP_IN_TABLE);
}
public List<WebElement> getListOfAddedGroups() {
return driver.findElements(ADDED_GROUPS);
}
public List<WebElement> getListOfAvailableGroupsToAdd() {
return driver.findElements(GROUP_TO_ADD);
}
public void clickOnUserInTable(String userName) {
driver.findElement(By.xpath(String.format(USER_TABLE + ROW_BY_NAME, userName))).click();
waitForPageLoad();
}
public void addGroup(String groupName) {
waitForVisibilityOfElementLocated(By.xpath(String.format(TABLE_TO_ADD + ROW_BY_NAME, groupName))).click();
clickAddButton();
waitProgressBarNotVisible();
}
public void removeGroup(String groupName) {
waitForVisibilityOfElementLocated(By.xpath(String.format(TABLE_ADDED + ROW_BY_NAME, groupName))).click();
clickRemoveButton();
waitForInvisibilityGridDownloader();
}
public void addAllGroups() {
clickAddAllButton();
waitProgressBarNotVisible();
}
public void removeAllGroups() {
clickRemoveAllButton();
waitProgressBarNotVisible();
}
/**
* Method to avoid parallel test conflicts.
* <p>
* If the list of groups available for adding is not empty, checks if the list contains only newly created groups.
* </p>
*
* @param groupNames list retrieved from the database before the parallel test created a new group.
* Instance of {@link List<String>} type.
*
* @return value of {@link Boolean} type.
* <p>
* True - if list of groups available for adding is empty, or contains only newly created groups from parallel tests.
* </p>
* <p>
* False - if list of groups available for adding contains values from groupNames list.
* </p>
*/
public boolean isAvailableGridEmpty(List<String> groupNames) {
List<String> possibleParallelAddedGroups = getListOfAvailableGroupsToAdd()
.stream()
.map(WebElement::getText)
.collect(Collectors.toList());
if (possibleParallelAddedGroups.isEmpty()) {
return true;
}
else {
return groupNames
.stream()
.noneMatch(possibleParallelAddedGroups::contains);
}
}
public void bindGroup(String roleName) {
changeUserPageGridsSort(UsersPageGrids.GROUPS_TO_ADD_GRID);
//проходим вниз все группы пока не найдем нужную
listGroupsToAdd.get(0).click();
Actions actions = new Actions(driver);
int numberOfScrolls = 10;
while (driver.findElements(By.xpath(String.format(TABLE_TO_ADD + ROW_BY_NAME, roleName)))
.isEmpty() && numberOfScrolls != 0) {
actions.sendKeys(Keys.PAGE_DOWN).perform();
numberOfScrolls--;
}
waitProgressBarNotVisible();
addGroup(roleName);
waitProgressBarNotVisible();
}
public void logout() {
waitProgressBarNotVisible();
userMenuButton.click();
exitButton.click();
}
public void changeUserPageGridsSort(UsersPageGrids value) {
switch (value) {
case USERS_GRID:
driver.findElement(CELL_WITH_LAST_NAME_HEADER).click();
break;
case LINKED_GROUPS_GRID:
driver.findElement(GROUP_IN_TABLE_HEADER).click();
break;
case GROUPS_TO_ADD_GRID:
driver.findElement(GROUP_TO_ADD_HEADER).click();
case ADDED_GROUPS_GRID:
driver.findElement(ADDED_GROUPS_HEADER).click();
break;
}
waitForPageLoad();
}
public enum UsersPageGrids {
USERS_GRID,
LINKED_GROUPS_GRID,
GROUPS_TO_ADD_GRID,
ADDED_GROUPS_GRID
}
}

View file

@ -1,287 +0,0 @@
package old.page;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.TimeoutException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import old.core.BasePage;
import old.util.ExecutionManager;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertTrue;
public abstract class BaseComponentPage extends BasePage {
private static final By PROGRESS_BAR = By.xpath("//img[contains(@src, 'progress.gif')]");
private static final By NGB_MODAL_WINDOW = By.xpath("//ngb-modal-window");
private static final By LOGIN_HEADER_BY = By.xpath("//h2[contains(.,'Вход')]");
private static final String SELECTIZE_BY_OBJECT_NAME = "//*[@object-name='%s']";
private static final By INPUT_IS_ACTIVE = By.xpath("//div[contains(@class, 'input-active')]");
private static final String DATE_TIME_CREATE_OR_UPDATE =
"//div[@col-id='%s']//span[contains(text(),'%s')]/parent::span/parent::div/parent::div/following-sibling::div[@col-id='%s']//span";
private static final By GRID_PROGRESS_BAR = By.xpath(
"//span[contains(text(), 'Загрузка данных, пожалуйста, подождите.')]");
protected static final By EMAIL_INPUT_BY = By.name("username");
protected static final By FIRST_ROW_BY = By.cssSelector(".ag-center-cols-container [row-index='0']");
protected static final By MODAL_DIALOG_FIRST_ROW_BY = By.cssSelector(
".modal-dialog .ag-center-cols-container [row-index='0']");
protected static final String SELECTIZE_INPUT_BY_OBJECT_NAME = SELECTIZE_BY_OBJECT_NAME + "//input";
protected static final String INPUT_WITH_SELECTED_OPTION = SELECTIZE_BY_OBJECT_NAME + "//div[contains(.,'%s')]";
protected static final String OPTION_TO_SELECT = SELECTIZE_BY_OBJECT_NAME + "//div[@data-selectable][contains(.,'%s')]";
protected static final String SELECTIZE_FULL = SELECTIZE_BY_OBJECT_NAME + "//div[contains(@class, 'full has-items')]";
protected static final String EXCLUDE_HEADER = "[not(contains(@class,'ag-header'))]";
protected static final String AG_HEADER = "[contains(@class,'ag-header')]";
private static final String PAGE_HEADER = "//*[contains(text(),'%s')]";
//Administration Page
@FindBy(xpath = "//*[contains(text(),'Фильтр по пользователям')]")
public WebElement filterPanel;
@FindBy(xpath = "//*[@object-name='last-name']//input")
public WebElement surNameField;
@FindBy(xpath = "//*[@object-name='search']//input")
protected WebElement searchField;
@FindBy(xpath = "//*[@object-name='create-button']//button['Создать']")
protected WebElement createButton;
@FindBy(xpath = "//*[@object-name='edit-button']//button['Редактировать']")
protected WebElement editButton;
@FindBy(xpath = "//*[@object-name='delete-button']//button['Удалить']")
protected WebElement deleteButton;
@FindBy(xpath = "//div[@class='modal-dialog']//button[@test-id='yes-btn']")
protected WebElement confirmButton;
@FindBy(xpath = "//button[contains(.,'Отменить')]")
public WebElement cancelButton;
//Editing/Creating Pages
@FindBy(xpath = "//*[@object-name='name']//input")
public WebElement nameField;
@FindBy(xpath = "//button[contains(.,'Сохранить')]")
public WebElement saveButton;
@FindBy(xpath = "//*[@object-name='Add']//button[text()='>']")
protected WebElement addButton;
@FindBy(xpath = "//*[@object-name='Remove']//button[text()='<']")
protected WebElement removeButton;
@FindBy(xpath = "//*[@object-name='AddAll']//button[text()='>>']")
protected WebElement addAllButton;
@FindBy(xpath = "//*[@object-name='RemoveAll']//button[text()='<<']")
protected WebElement removeAllButton;
@FindBy(xpath = "//button[contains(.,'Прервать')]")
private WebElement stopButton;
final Logger logger = LoggerFactory.getLogger(getClass());
protected static ExecutionManager EXECUTION_MANAGER = new ExecutionManager();
public BaseComponentPage(WebDriver browser, String uri) {
super(browser, uri);
}
@Override
public void waitForPageLoad() {
super.waitForPageLoad();
assertTrue(thereIsNoError());
waitForInvisibilityOfElementLocated(NGB_MODAL_WINDOW);
}
@Override
public void refreshPage() {
driver.navigate().refresh();
waitForPageLoad();
}
public void waitForPageLoadWithoutCheckingForError() {
super.waitForPageLoad();
waitForInvisibilityOfElementLocated(NGB_MODAL_WINDOW);
}
public void doubleClick(WebElement element) {
Actions action = new Actions(driver);
action.doubleClick(element).perform();
}
public void typeText(WebElement input, String text) {
waitForVisibilityOf(input);
input.clear();
input.sendKeys(text);
waitProgressBarNotVisible();
}
protected void typeTextFromJS(WebElement input, String text) {
input.click();
input.clear();
((JavascriptExecutor) driver).executeScript("arguments[0].value='" + text + "';", input);
}
public void typeTextOnAdminFilter(WebElement input, String text) {
typeTextFromJS(input, text);
input.sendKeys(" ");
input.sendKeys(Keys.ENTER);
blur(input);
}
protected String getErrorText(By locator) {
WebElement errorMessage = waitForVisibilityOfElementLocated(locator);
return errorMessage.getText();
}
public String getErrorTextFromPage() {
return getErrorText(getErrorBy());
}
protected void typeTextAndSelectOption(String objectName, String inputText, String optionText) {
WebElement selectize = findElement(
By.xpath(String.format(SELECTIZE_BY_OBJECT_NAME, objectName)));
waitForElementToBeClickable(selectize).click();
WebElement input = findElement(
By.xpath(String.format(SELECTIZE_INPUT_BY_OBJECT_NAME, objectName)));
input.sendKeys(Keys.BACK_SPACE);
typeText(input, inputText);
By optionToSelectBy = By.xpath(String.format(OPTION_TO_SELECT, objectName, optionText));
waitForVisibilityOfElementLocated(optionToSelectBy).click();
waitForInvisibilityOfElementLocated(optionToSelectBy);
waitForVisibilityOfElementLocated(By.xpath(String.format(SELECTIZE_FULL, objectName)));
waitForVisibilityOfElementLocated(By.xpath(String.format(INPUT_WITH_SELECTED_OPTION, objectName, optionText)));
}
public String getLocalDate() {
return LocalDateTime.now().minusHours(3).format(DateTimeFormatter.ofPattern("dd.MM.yyyy"));
}
public WebElement getActionTime(String colId, String name, String сolIdAction) {
return waitForVisibilityOfElementLocated(By.xpath(String.format
(DATE_TIME_CREATE_OR_UPDATE, colId, name, сolIdAction)));
}
public void waitForInitializationOf(WebElement... elements) {
long pageLoadStart = System.currentTimeMillis();
waitForPageLoad();
logger.info("page loaded in " + (System.currentTimeMillis() - pageLoadStart) + " ms");
for (WebElement element : elements) {
long elementVisibilityStart = System.currentTimeMillis();
waitForVisibilityOf(element);
logger.info(element + " became visible in " + (System.currentTimeMillis() - elementVisibilityStart) + " ms");
}
}
// ожидается, что последний инпут, по котрому был клик, выбран
public void waitForInputFieldSelected() {
waitForNumberOfElementsToBe(INPUT_IS_ACTIVE, 1);
}
public static By getProgressBar() {
return PROGRESS_BAR;
}
public static By getLoginHeaderBy() {
return LOGIN_HEADER_BY;
}
public List<String> getWebElementTexts(List<WebElement> elements) {
return elements.stream()
.map(WebElement::getText)
.collect(Collectors.toList());
}
protected WebElement findElement(By by) {
return driver.findElement(by);
}
protected List<WebElement> findElements(By by) {
return driver.findElements(by);
}
public void waitForInvisibilityGridDownloader() {
try {
waitForVisibilityOfElementLocated(GRID_PROGRESS_BAR, Duration.ofMillis(1000));
waitForInvisibilityOfElementLocated(GRID_PROGRESS_BAR);
}
catch (TimeoutException ignored) {
logger.info("progress bar not visible");
}
}
protected void blur(WebElement input) {
((JavascriptExecutor) driver).executeScript("arguments[0].blur()", input);
((JavascriptExecutor) driver).executeScript("document.body.click()");
}
public void cancelAction() {
waitForElementToBeClickable(cancelButton).click();
waitForPageLoad();
clickConfirmButton();
}
public void clickSaveButton() {
waitForElementToBeClickable(saveButton).click();
waitProgressBarNotVisible();
waitForPageLoad();
}
public void clickEditButton() {
waitForElementToBeClickable(editButton).click();
waitForPageLoad();
}
public void clickCreateButton() {
waitForElementToBeClickable(createButton).click();
waitForPageLoad();
}
public void clickDeleteButton() {
waitForElementToBeClickable(deleteButton).click();
waitProgressBarNotVisible();
}
public void clickConfirmButton() {
waitForElementToBeClickable(confirmButton).click();
waitProgressBarNotVisible();
}
public void clickAddButton() {
waitForElementToBeClickable(addButton).click();
waitForPageLoad();
}
public void clickRemoveButton() {
waitForElementToBeClickable(removeButton).click();
waitForPageLoad();
}
public void clickAddAllButton() {
waitForElementToBeClickable(addAllButton).click();
waitForPageLoad();
}
public void clickRemoveAllButton() {
waitForElementToBeClickable(removeAllButton).click();
waitForPageLoad();
}
public void clickCancelButton() {
waitForElementToBeClickable(cancelButton).click();
}
public void clickStopButton() {
waitForElementToBeClickable(stopButton).click();
waitProgressBarNotVisible();
}
public void searchUser(String userSurName) {
filterPanel.click();
waitForPageLoad();
typeTextOnAdminFilter(surNameField, userSurName);
waitForInvisibilityGridDownloader();
}
public void checkTitle(String labelName) {
waitForVisibilityOfElementLocated(By.xpath(String.format(PAGE_HEADER, labelName)));
}
}

View file

@ -1,128 +0,0 @@
package old.page;
import java.time.Duration;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class InboxPage extends BaseComponentPage {
private static final String XPATH_FOR_MENU_ITEM = "//button[@class='dropdown-item'][contains(.,'%s')]";
private static final By PROCESS_LIST_BY = By.xpath("//div[@id='process-instance-list']");
private static final By PROCESS_DATE_BY = By.xpath("//span[contains(.,'Дата запуска')]");
private static final By MENU_ADMINISTRATION = By.xpath("//button[contains(.,'Администрирование')]");
private static final By START_PAGE = By.xpath("//div[@class='logo']");
@FindBy(xpath = "//button[@id='adminDropdownMenu']")
public WebElement adminList;
@FindBy(xpath = "//div[@class='logout']//button[contains(@class,'nav-link')]")
public WebElement userMenuButton;
@FindBy(xpath = "//button[contains(.,'Выход')]")
public WebElement exitButton;
@FindBy(xpath = "//button[@id='startProcessDropdownMenu']")
private WebElement startButton;
@FindBy(xpath = "//button[@routerlink='/user-management/groups']")
private WebElement groupPage;
@FindBy(xpath = "//button[@routerlink='/user-management/roles']")
private WebElement rolePage;
@FindBy(xpath = "//button[@routerlink='/user-management/users']")
private WebElement userPage;
@FindBy(xpath = "//button[@routerlink='/user-management/org-units']")
private WebElement orgPage;
@FindBy(xpath = "//button[@routerlink='/user-management/authorities']")
private WebElement authoritiesPage;
@FindBy(xpath = "//button[@routerlink='/process/instance']")
private WebElement processPage;
@FindBy(xpath = "//div[@class='user-info']//div[@class='user-fio']")
private WebElement userFIO;
public InboxPage(WebDriver browser) {
super(browser, "/#/");
}
//выход из приложения
public void exitApp() {
waitProgressBarNotVisible();
userMenuButton.click();
exitButton.click();
assertTrue(thereIsNoError());
}
//открыть Экземпляры процессов
public AdminProcessPage openAdminProcessPage() {
waitForPageLoad();
adminList.click();
waitForElementToBeClickable(processPage, Duration.ofSeconds(10));
processPage.click();
waitForPageLoad();
waitForVisibilityOfElementLocated(PROCESS_LIST_BY);
waitForVisibilityOfElementLocated(PROCESS_DATE_BY);
return PageFactory.initElements(driver, AdminProcessPage.class);
}
//начать процесс
public ProcessesPage startProcess(String processName) {
waitForPageLoad();
startButton.click();
By menuItem = By.xpath(String.format(XPATH_FOR_MENU_ITEM, processName));
WebElement process = waitForVisibilityOfElementLocated(menuItem);
process.click();
waitForPageLoad();
return PageFactory.initElements(driver, ProcessesPage.class);
}
public AdminUserPage startAdminUser() {
adminList.click();
userPage.click();
waitForPageLoad();
return PageFactory.initElements(driver, AdminUserPage.class);
}
public AdminGroupPage startAdminGroup() {
adminList.click();
groupPage.click();
waitForPageLoad();
return PageFactory.initElements(driver, AdminGroupPage.class);
}
public AdminRolePage startAdminRole() {
adminList.click();
rolePage.click();
waitForPageLoad();
return PageFactory.initElements(driver, AdminRolePage.class);
}
public AdminOrgPage startAdminOrganization() {
adminList.click();
orgPage.click();
waitForPageLoad();
return PageFactory.initElements(driver, AdminOrgPage.class);
}
public List<WebElement> getListOfAdminPanels() {
return findElements(MENU_ADMINISTRATION);
}
public String getUserFIOFromPage() {
return userFIO.getText();
}
public List<WebElement> getEmailInputsFrom(WebDriver element) {
return element.findElements(EMAIL_INPUT_BY);
}
public void waitEmailInput() {
waitForVisibilityOfElementLocated(EMAIL_INPUT_BY);
}
public boolean startPageDisplay() {
waitForPageLoad();
return waitForVisibilityOfElementLocated(START_PAGE).isDisplayed();
}
}

View file

@ -1,78 +0,0 @@
package old.page;
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class LoginPage extends BaseComponentPage {
private static final By ERROR_LOGIN = By.xpath("//div[@class='form-signin']//div[contains(@class,'alert-danger')]");
private static final By TEXT_ERROR_DEPLOY_MESSAGE = By.xpath("//*[contains(., 'Приложение стартует')]");
private static final By LOGIN_PAGE_HEADER = By.xpath("//*[contains(text(), 'Вход')]");
@FindBy(name = "username")
private WebElement emailInput;
@FindBy(name = "password")
private WebElement passwordInput;
@FindBy(css = "button[class='btn btn-primary']")
private WebElement enterButton;
@FindBy(xpath = "//*[contains(text(), 'Забыли пароль?')]")
private WebElement resetPasswordLink;
@FindBy(xpath = "//*[contains(text(), 'Зарегистрироваться')]")
private WebElement registrationLink;
public LoginPage(WebDriver browser) {
super(browser, "/#/login");
}
public void typeLoginPasswordAndEnter(String login, String password) {
waitForVisibilityOfElementLocated(EMAIL_INPUT_BY);
passwordInput.clear();
passwordInput.sendKeys(password);
emailInput.clear();
emailInput.sendKeys(login);
enterButton.click();
}
public InboxPage login(String login, String password) {
typeLoginPasswordAndEnter(login, password);
assertTrue(hasNoErrorOnLoginPage(TEXT_ERROR_DEPLOY_MESSAGE), "Failed to deploy backend");
assertTrue(hasNoErrorOnLoginPage(ERROR_LOGIN), "Failed to login");
waitProgressBarNotVisible();
assertTrue(thereIsNoError());
return PageFactory.initElements(driver, InboxPage.class);
}
private boolean hasNoErrorOnLoginPage(By locator) {
try {
waitForInvisibilityOfElementLocated(locator, Duration.ofSeconds(5));
}
catch (TimeoutException ignored) {
logger.error(getErrorText(locator));
return false;
}
return true;
}
public String getErrorTextFromLoginForm() {
return getErrorText(ERROR_LOGIN);
}
public void goToResetPage() {
waitForVisibilityOfElementLocated(LOGIN_PAGE_HEADER);
resetPasswordLink.click();
}
public void goToRegistPage(){
waitForPageLoad();
registrationLink.click();
}
}

View file

@ -1,43 +0,0 @@
package old.page;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ProcessesPage extends BaseComponentPage {
private static final String TEXT = "//div[@class='form-group']//*[text()='%s']";
@FindBy(xpath = "//navigation-button[@object-name='NavigationButton']//button[contains(.,'Завершить')]")
public WebElement exitButton;
@FindBy(xpath = "//div[@id='page']")
public WebElement pageID;
public ProcessesPage(WebDriver browser) {
super(browser, "/#/process/");
}
public String getTestProcessText() {
return getWebElementTexts(driver.findElements(By.xpath(String.format(TEXT, "Тестовая страница")))).get(0);
}
//----- different
public String getProcessId() {
String str = driver.getCurrentUrl();
Pattern p = Pattern.compile("process\\/(\\d+)");
Matcher m = p.matcher(str);
m.find();
return m.group(1);
}
public void exitProcess() {
waitForElementToBeClickable(exitButton);
exitButton.click();
waitForPageLoadWithoutCheckingForError();
}
}

View file

@ -1,11 +0,0 @@
package old.util;
/**
* @author gulnaz
*/
public final class DataUtil {
private DataUtil() {
}
public static final String BASE_PART_FOR_USER = "qa";
}

View file

@ -1,508 +0,0 @@
package old.util;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import com.zaxxer.hikari.HikariDataSource;
import org.jooq.DSLContext;
import org.jooq.Table;
import org.jooq.TableField;
import org.jooq.Record;
import org.jooq.conf.RenderNameCase;
import org.jooq.conf.Settings;
import org.jooq.impl.DSL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.cg.webbpm.modules.database.bean.config.Datasource;
import ru.cg.webbpm.modules.database.impl.data_source.HikariDataSourceFactory;
import static ru.cg.webbpm.modules.security.api.impl.bean.Tables.LINK_USER_ACCOUNT_USER_GROUP;
import static ru.cg.webbpm.modules.security.api.impl.bean.Tables.LINK_USER_GROUP_USER_ROLE;
import static ru.cg.webbpm.modules.security.api.impl.bean.Tables.LINK_USER_ROLE_AUTHORITY;
import static ru.cg.webbpm.modules.security.api.impl.bean.Tables.ORG_UNIT;
import static ru.cg.webbpm.modules.security.api.impl.bean.Tables.SIMPLE_CREDENTIALS;
import static ru.cg.webbpm.modules.security.api.impl.bean.Tables.USER_ACCOUNT;
import static ru.cg.webbpm.modules.security.api.impl.bean.Tables.USER_ACCOUNT_VERIFICATION;
import static ru.cg.webbpm.modules.security.api.impl.bean.Tables.USER_GROUP;
import static ru.cg.webbpm.modules.security.api.impl.bean.Tables.USER_ROLE;
/**
* @author gulnaz
*/
public class ExecutionManager {
private static final Logger LOGGER = LoggerFactory.getLogger(ExecutionManager.class);
private static final int POOL_SIZE = 2;
private HikariDataSource testDataSource;
public HikariDataSource securityDataSource;
private DSLContext dslContext;
private Settings settings;
public ExecutionManager() {
LOGGER.info("Execution manager creation");
HikariDataSourceFactory hikariDataSourceFactory = new HikariDataSourceFactory(POOL_SIZE);
testDataSource = hikariDataSourceFactory.createDataSource(getDataSource(DataSourceName.TEST));
securityDataSource = hikariDataSourceFactory.createDataSource(getDataSource(DataSourceName.SECURITY));
securityDataSource.setLeakDetectionThreshold(60000);
settings = new Settings();
settings.setRenderNameCase(RenderNameCase.LOWER);
//TODO enable and change wrong port to right
// jbpmDataSource = hikariDataSourceFactory.createDataSource(getDataSource(DataSourceName.JBPM));
// jbpmDataSource.setMaximumPoolSize(5);
}
public enum DataSourceName {
JBPM,
SECURITY,
TEST
}
public String generateId() {
return UUID.randomUUID().toString();
}
private Datasource getDataSource(DataSourceName dataSourceName) {
String host = System.getenv("HOSTNAME");
String databaseName;
String user;
String password;
Datasource datasource = new Datasource();
switch (dataSourceName) {
case JBPM:
databaseName = System.getenv("DB_JBPM_NAME");
user = System.getenv("DB_JBPM_USERNAME");
password = System.getenv("DB_JBPM_PASSWORD");
break;
case SECURITY:
host = System.getenv("DB_SEC_HOST");
databaseName = System.getenv("DB_SEC_NAME");
user = System.getenv("DB_SEC_USERNAME");
password = System.getenv("DB_SEC_PASSWORD");
break;
case TEST:
host = System.getenv("DB_APP_HOST");
databaseName = System.getenv("DB_APP_NAME");
user = System.getenv("DB_APP_USERNAME");
password = System.getenv("DB_APP_PASSWORD");
break;
default:
throw new IllegalStateException("Unexpected value: " + dataSourceName);
}
datasource.setUrl(String.format("jdbc:postgresql://%s:%s/%s",
host,
System.getenv("DB_PORT"),
databaseName));
datasource.setUser(user);
datasource.setPassword(password);
datasource.setDriverClassName("org.postgresql.Driver");
return datasource;
}
public <R extends Record> int countTableRows(Table<R> table) {
try (Connection connection = testDataSource.getConnection()) {
dslContext = DSL.using(connection);
return dslContext.selectCount()
.from(table)
.fetchOne(0, int.class);
}
catch (SQLException e) {
throw new RuntimeException("Failed to count rows", e);
}
}
public List<String> getGroupNamesFromUserGroup() {
try (Connection connection = securityDataSource.getConnection()) {
dslContext = DSL.using(connection, settings);
return dslContext.select()
.from(USER_GROUP)
.fetch()
.getValues(USER_GROUP.NAME);
}
catch (SQLException e) {
throw new RuntimeException("Failed to get group names from user group table", e);
}
}
public String getTokenByUserId(String id) {
try (Connection connection = securityDataSource.getConnection()) {
dslContext = DSL.using(connection, settings);
return dslContext.select()
.from(USER_ACCOUNT_VERIFICATION)
.where(USER_ACCOUNT_VERIFICATION.USER_ACCOUNT_ID.eq(id))
.fetch()
.getValue(0, USER_ACCOUNT_VERIFICATION.TOKEN);
}
catch (SQLException e) {
throw new RuntimeException("Failed to get token from user_account_verification", e);
}
}
public List<String> getRoleNamesFromUserRole() {
try (Connection connection = securityDataSource.getConnection()) {
dslContext = DSL.using(connection, settings);
return dslContext.select()
.from(USER_ROLE)
.fetch()
.getValues(USER_ROLE.NAME);
}
catch (SQLException e) {
throw new RuntimeException("Failed to get roles from user_role table", e);
}
}
public String getUserAccountIdByName(String userName) {
try (Connection connection = securityDataSource.getConnection()) {
dslContext = DSL.using(connection, settings);
return dslContext.select()
.from(USER_ACCOUNT)
.where(USER_ACCOUNT.FIRST_NAME.eq(userName))
.fetch()
.getValue(0, USER_ACCOUNT.USER_ACCOUNT_ID);
}
catch (SQLException e) {
throw new RuntimeException("Failed to get user_account_id from user_account table", e);
}
}
public String getRoleIdByName(String roleName) {
try (Connection connection = securityDataSource.getConnection()) {
dslContext = DSL.using(connection, settings);
return dslContext.select()
.from(USER_ROLE)
.where(USER_ROLE.NAME.eq(roleName))
.fetch()
.getValue(0, USER_ROLE.USER_ROLE_ID);
}
catch (SQLException e) {
throw new RuntimeException("Failed to get user_role_id from user_role table", e);
}
}
public String getGroupIdByName(String groupName) {
try (Connection connection = securityDataSource.getConnection()) {
dslContext = DSL.using(connection, settings);
return dslContext.select()
.from(USER_GROUP)
.where(USER_GROUP.NAME.eq(groupName))
.fetch()
.getValue(0, USER_GROUP.USER_GROUP_ID);
}
catch (SQLException e) {
throw new RuntimeException("Failed to get user_group_id from user_group table", e);
}
}
/*
Queries with security datasource
*/
private <R extends Record> void insertSecurityRecord(Table<R> table,
TableField<R, String> field1, TableField<R, String> field2, TableField<R, String> field3,
String value1, String value2, String value3) {
try (Connection connection = securityDataSource.getConnection()) {
dslContext = DSL.using(connection, settings);
dslContext.insertInto(table, field1, field2, field3)
.values(value1, value2, value3)
.execute();
}
catch (SQLException e) {
throw new RuntimeException("Failed to delete record", e);
}
}
private <R extends Record> void deleteSecurityRecord(Table<R> table, TableField<R, String> field, String value) {
try (Connection connection = securityDataSource.getConnection()) {
dslContext = DSL.using(connection, settings);
dslContext.delete(table)
.where(field.eq(value))
.execute();
}
catch (SQLException e) {
throw new RuntimeException("Failed to delete record", e);
}
}
public void insertUser(String username, String password, String email, String orgId, String groupId) {
//TODO SUPPORT-3761
try (Connection connection = securityDataSource.getConnection()) {
String userId = generateId();
dslContext = DSL.using(connection, settings);
dslContext.batch(
dslContext
.insertInto(USER_ACCOUNT,
USER_ACCOUNT.USER_ACCOUNT_ID, USER_ACCOUNT.USERNAME, USER_ACCOUNT.EMAIL,
USER_ACCOUNT.FIRST_NAME, USER_ACCOUNT.LAST_NAME, USER_ACCOUNT.ORG_UNIT_ID)
.values(userId, username, email, username, username, orgId),
dslContext
.insertInto(SIMPLE_CREDENTIALS,
SIMPLE_CREDENTIALS.USER_ACCOUNT_ID, SIMPLE_CREDENTIALS.PASSWORD)
.values(userId, password),
dslContext.insertInto(LINK_USER_ACCOUNT_USER_GROUP, LINK_USER_ACCOUNT_USER_GROUP.LINK_USER_ACCOUNT_USER_GROUP_ID,
LINK_USER_ACCOUNT_USER_GROUP.USER_ACCOUNT_ID, LINK_USER_ACCOUNT_USER_GROUP.USER_GROUP_ID)
.values(generateId(), userId, groupId))
.execute();
}
catch (SQLException e) {
throw new RuntimeException("Failed to insert user", e);
}
}
public void deleteTestOrg(String orgName) {
deleteSecurityRecord(ORG_UNIT, ORG_UNIT.NAME, orgName);
}
public void createTestOrg(String orgName) {
insertSecurityRecord(ORG_UNIT, ORG_UNIT.ID, ORG_UNIT.NAME, ORG_UNIT.CODE, generateId(), orgName, orgName);
}
public void createParentAndChildOrgs(String orgName1, String orgName2) {
try (Connection connection = securityDataSource.getConnection()) {
String parentOrgId = generateId();
dslContext = DSL.using(connection, settings);
dslContext.batch(
dslContext.insertInto(ORG_UNIT, ORG_UNIT.ID, ORG_UNIT.NAME, ORG_UNIT.CODE)
.values(parentOrgId, orgName1, orgName1),
dslContext.insertInto(ORG_UNIT, ORG_UNIT.ID, ORG_UNIT.NAME, ORG_UNIT.CODE, ORG_UNIT.PARENT_ID)
.values(generateId(), orgName2, orgName2, parentOrgId))
.execute();
}
catch (SQLException e) {
throw new RuntimeException("Failed to create organizations", e);
}
}
public void deleteTestUser(String userName) {
deleteSecurityRecord(USER_ACCOUNT, USER_ACCOUNT.FIRST_NAME, userName);
}
public void createUser(String username, String organizationID) {
String userAccountId = generateId();
try (Connection connection = securityDataSource.getConnection()) {
dslContext = DSL.using(connection, settings);
dslContext.batch(
dslContext
.insertInto(USER_ACCOUNT,
USER_ACCOUNT.USER_ACCOUNT_ID, USER_ACCOUNT.USERNAME, USER_ACCOUNT.EMAIL,
USER_ACCOUNT.FIRST_NAME, USER_ACCOUNT.LAST_NAME, USER_ACCOUNT.MIDDLE_NAME,
USER_ACCOUNT.ORG_UNIT_ID)
.values(userAccountId, username, username + "@test.com", username, username, username, organizationID),
dslContext
.insertInto(SIMPLE_CREDENTIALS,
SIMPLE_CREDENTIALS.USER_ACCOUNT_ID, SIMPLE_CREDENTIALS.PASSWORD)
.values(userAccountId, username))
.execute();
}
catch (SQLException e) {
throw new RuntimeException("Failed to create user", e);
}
}
public void createGroupBindRoles(String groupName, String accessLevel, String... roles) {
String groupId = generateId();
try (Connection connection = securityDataSource.getConnection()) {
dslContext = DSL.using(connection, settings);
dslContext.insertInto(USER_GROUP, USER_GROUP.NAME, USER_GROUP.USER_GROUP_ID, USER_GROUP.ACCESS_LEVEL_ID)
.values(groupName, groupId, accessLevel)
.execute();
Arrays.asList(roles).forEach(role -> bindRoleToGroup(role, groupId));
}
catch (SQLException e) {
throw new RuntimeException("Failed to create Group");
}
}
public void createRoleBindGroups(String roleName, String... groupIds) {
String userRoleId = generateId();
try (Connection connection = securityDataSource.getConnection()) {
dslContext = DSL.using(connection, settings);
dslContext.insertInto(USER_ROLE, USER_ROLE.NAME, USER_ROLE.USER_ROLE_ID)
.values(roleName, userRoleId)
.execute();
Arrays.asList(groupIds).forEach(groupId -> bindRoleToGroup(userRoleId, groupId));
}
catch (SQLException e) {
throw new RuntimeException("Failed to create role");
}
}
public void createUserBindGroups(String userName, String organizationID, String... groupIDs) {
String userAccountId = generateId();
try (Connection connection = securityDataSource.getConnection()) {
dslContext = DSL.using(connection, settings);
dslContext.batch(
dslContext.insertInto(USER_ACCOUNT, USER_ACCOUNT.USER_ACCOUNT_ID, USER_ACCOUNT.EMAIL,
USER_ACCOUNT.FIRST_NAME,
USER_ACCOUNT.LAST_NAME, USER_ACCOUNT.MIDDLE_NAME, USER_ACCOUNT.ORG_UNIT_ID,
USER_ACCOUNT.USERNAME)
.values(userAccountId, userName + "@test.com", userName, userName, userName,
organizationID, userName),
dslContext.insertInto(SIMPLE_CREDENTIALS, SIMPLE_CREDENTIALS.USER_ACCOUNT_ID,
SIMPLE_CREDENTIALS.PASSWORD)
.values(userAccountId, userName))
.execute();
Arrays.asList(groupIDs).forEach(group -> bindGroupToUser(group, userAccountId));
}
catch (SQLException e) {
throw new RuntimeException("Failed to create user", e);
}
}
private void bindRoleToGroup(String roleId, String groupId) {
String linkUserGroupUserRoleId = generateId();
dslContext.insertInto(LINK_USER_GROUP_USER_ROLE,
LINK_USER_GROUP_USER_ROLE.LINK_USER_GROUP_USER_ROLE_ID,
LINK_USER_GROUP_USER_ROLE.USER_GROUP_ID, LINK_USER_GROUP_USER_ROLE.USER_ROLE_ID)
.values(linkUserGroupUserRoleId, groupId, roleId)
.execute();
}
private void bindGroupToUser(String groupId, String userAccountId) {
String linkUserAccountUserGroupId = generateId();
dslContext.insertInto(LINK_USER_ACCOUNT_USER_GROUP,
LINK_USER_ACCOUNT_USER_GROUP.LINK_USER_ACCOUNT_USER_GROUP_ID,
LINK_USER_ACCOUNT_USER_GROUP.USER_ACCOUNT_ID,
LINK_USER_ACCOUNT_USER_GROUP.USER_GROUP_ID)
.values(linkUserAccountUserGroupId, userAccountId, groupId)
.execute();
}
public void deleteLinkedRolesFromGroup(String groupId) {
try (Connection connection = securityDataSource.getConnection()) {
dslContext = DSL.using(connection, settings);
dslContext.delete(LINK_USER_GROUP_USER_ROLE)
.where(LINK_USER_GROUP_USER_ROLE.USER_ROLE_ID.eq(groupId))
.execute();
}
catch (SQLException e) {
throw new RuntimeException("Failed to delete linked group roles", e);
}
}
public void deleteLinkedGroupsFromRole(String roleId) {
try (Connection connection = securityDataSource.getConnection()) {
dslContext = DSL.using(connection, settings);
dslContext.delete(LINK_USER_GROUP_USER_ROLE)
.where(LINK_USER_GROUP_USER_ROLE.USER_ROLE_ID.eq(roleId))
.execute();
}
catch (SQLException e) {
throw new RuntimeException("Failed to delete linked role groups", e);
}
}
public void deleteUserLinkedGroups(String userAccountID) {
try (Connection connection = securityDataSource.getConnection()) {
dslContext = DSL.using(connection, settings);
dslContext.delete(LINK_USER_ACCOUNT_USER_GROUP)
.where(LINK_USER_ACCOUNT_USER_GROUP.USER_ACCOUNT_ID.eq(userAccountID))
.execute();
}
catch (SQLException e) {
throw new RuntimeException("Failed to delete linked user groups", e);
}
}
public void deleteTestGroup(String groupName) {
deleteSecurityRecord(USER_GROUP, USER_GROUP.NAME, groupName);
}
public void createTestGroup(String groupName, String accessLevelId) {
insertSecurityRecord(USER_GROUP, USER_GROUP.USER_GROUP_ID, USER_GROUP.NAME, USER_GROUP.ACCESS_LEVEL_ID,
generateId(), groupName, accessLevelId);
}
public void createBindGroupRole(String name, String groupId, String accessLevelId, String roleId) {
try (Connection connection = securityDataSource.getConnection()) {
dslContext = DSL.using(connection, settings);
dslContext.batch(
dslContext.insertInto(USER_GROUP, USER_GROUP.USER_GROUP_ID, USER_GROUP.NAME, USER_GROUP.ACCESS_LEVEL_ID)
.values(groupId, name, accessLevelId),
dslContext.insertInto(USER_ROLE, USER_ROLE.USER_ROLE_ID, USER_ROLE.NAME)
.values(roleId, name),
dslContext.insertInto(LINK_USER_GROUP_USER_ROLE, LINK_USER_GROUP_USER_ROLE.LINK_USER_GROUP_USER_ROLE_ID,
LINK_USER_GROUP_USER_ROLE.USER_GROUP_ID, LINK_USER_GROUP_USER_ROLE.USER_ROLE_ID)
.values(generateId(), groupId, roleId))
.execute();
}
catch (SQLException e) {
throw new RuntimeException("Failed to create and bind group with role", e);
}
}
public void deleteUserGroupRole(String name, String groupId, String roleId) {
try (Connection connection = securityDataSource.getConnection()) {
dslContext = DSL.using(connection, settings);
dslContext.batch(
dslContext.delete(USER_ACCOUNT)
.where(USER_ACCOUNT.FIRST_NAME.eq(name)),
dslContext.delete(USER_GROUP)
.where(USER_GROUP.USER_GROUP_ID.eq(groupId)),
dslContext.delete(USER_ROLE)
.where(USER_ROLE.USER_ROLE_ID.eq(roleId)))
.execute();
}
catch (SQLException e) {
throw new RuntimeException("Failed to delete user, group, role", e);
}
}
public void linkRoleToAuthority(String roleId, String authorityId) {
insertSecurityRecord(LINK_USER_ROLE_AUTHORITY, LINK_USER_ROLE_AUTHORITY.USER_ROLE_AUTHORITY_ID,
LINK_USER_ROLE_AUTHORITY.USER_ROLE_ID, LINK_USER_ROLE_AUTHORITY.AUTHORITY_ID,
generateId(), roleId, authorityId);
}
public void deleteTestRole(String roleName) {
deleteSecurityRecord(USER_ROLE, USER_ROLE.NAME, roleName);
}
public void createTestRole(String roleName) {
try (Connection connection = securityDataSource.getConnection()) {
dslContext = DSL.using(connection, settings);
dslContext.insertInto(USER_ROLE, USER_ROLE.USER_ROLE_ID, USER_ROLE.NAME)
.values(generateId(), roleName)
.execute();
}
catch (SQLException e) {
throw new RuntimeException("Failed to create role", e);
}
}
public boolean hasUserByData(String username, String email) {
try (Connection connection = securityDataSource.getConnection()) {
dslContext = DSL.using(connection, settings);
int count = dslContext.selectCount()
.from(USER_ACCOUNT)
.where(USER_ACCOUNT.EMAIL.eq(email))
.and(USER_ACCOUNT.FIRST_NAME.eq(username))
.and(USER_ACCOUNT.LAST_NAME.eq(username))
.and(USER_ACCOUNT.MIDDLE_NAME.eq(username))
.execute();
return count == 1;
}
catch (SQLException e) {
throw new RuntimeException("Failed to fetch user count", e);
}
}
}

View file

@ -1,21 +0,0 @@
package old.util;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* @author: besedin
*/
public final class PropertyManager {
private static final Properties property = new Properties();
private static final String propFileName = "test.properties";
private PropertyManager() {
}
public static Properties getProperties() throws IOException {
InputStream inputStream = PropertyManager.class.getClassLoader().getResourceAsStream(propFileName);
property.load(inputStream);
return property;
}
}

View file

@ -1,61 +0,0 @@
package pages;
import core.BasePage;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import java.util.Arrays;
/**
* @author kote
*/
public class AuthoritiesPage extends BasePage {
private static final String ARROW_BY_SIBLING_LABEL =
"//span[contains(@class,'ag-row-group')][span[contains(.,'%s')]]//span[contains(@class,'closed')]";
private static final String ACTION_BY_NAME = "//static-column-tree-grid//*[text()='%s']";
private static final String BUTTON_BY_NAME = "//button[contains(.,'%s')]";
private static final String BUTTON_ON_DIALOG_BY_NAME = "//div[@class='modal-body']//button[contains(.,'%s')]";
private static final String MODAL_TITLE_BY_NAME = "//*[@class='modal-title'][contains(.,'%s')]";
private static final String ROLE_BY_NAME = "//static-column-grid//div[@class='ag-cell-wrapper']//span[contains(.,'%s')]";
private static final By COMBOBOX_INPUT = By.xpath(
"//combo-box//div[contains(@class,'selectize-input')]//input");
public AuthoritiesPage(WebDriver browser) {
super(browser, "/#/user-management/authorities");
}
public void openActionTree(String... actions) {
Arrays.asList(actions)
.forEach(action -> waitForElementToBeClickable(getBy(ARROW_BY_SIBLING_LABEL, action)).click());
}
public void clickOnAction(String action) {
waitForElementToBeClickable(getBy(ACTION_BY_NAME, action)).click();
}
public void clickOnButton(String name) {
waitForElementToBeClickable(getBy(BUTTON_BY_NAME, name)).click();
}
public void clickOnButtonOnDialog(String name) {
waitForElementToBeClickable(getBy(BUTTON_ON_DIALOG_BY_NAME, name)).click();
}
public boolean isDialogOpened(String title) {
return isPresent(getBy(MODAL_TITLE_BY_NAME, title));
}
public void selectRole(String value) {
typeAndSelectValue(COMBOBOX_INPUT, value);
}
public void clickOnRole(String role) {
waitForElementToBeClickable(getBy(ROLE_BY_NAME, role)).click();
}
public boolean isRoleOnTheList(String role) {
return isPresent(getBy(ROLE_BY_NAME, role));
}
}

View file

@ -1,65 +0,0 @@
package pages;
import core.BasePage;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author kote
*/
public class OrganizationsPage extends BasePage {
private static final String TEXT_ON_PAGE = "//text//div[contains(.,'%s')]";
private static final String BUTTON_BY_NAME = "//button[contains(.,'%s')]";
private static final String ROW_BY_TEXTS = "//div[@role='row'][.//span[contains(.,'%s')]][.//span[contains(.,'%s')]]";
private static final String ARROW_IN_ROW = ROW_BY_TEXTS + "//span[@ref='eContracted']";
private static final String MODAL_TITLE_BY_NAME = "//*[@class='modal-title'][contains(.,'%s')]";
@FindBy(xpath = "//div[label[span[contains(.,'Наименование')]]]//input")
private WebElement orgName;
@FindBy(xpath = "//div[label[span[contains(.,'Код')]]]//input")
private WebElement orgCode;
@FindBy(xpath = "//combo-box//div[contains(@class,'selectize-input')]")
private WebElement parentOrg;
public OrganizationsPage(WebDriver browser) {
super(browser, "/#/user-management/org-units");
}
public boolean isTitleVisible(String title) {
return isPresent(getBy(TEXT_ON_PAGE, title));
}
public boolean isOrganizationVisible(String name, String code) {
return isPresent(getBy(ROW_BY_TEXTS, name, code));
}
public void clickOnButton(String name) {
waitForElementToBeClickable(getBy(BUTTON_BY_NAME, name)).click();
}
public void clickOnOrganization(String name, String code) {
waitForElementToBeClickable(getBy(ROW_BY_TEXTS, name, code)).click();
}
public void clickOnArrowInParentOrganization(String name, String code) {
waitForElementToBeClickable(getBy(ARROW_IN_ROW, name, code)).click();
}
public void editOrgName(String value) {
editField(orgName, value);
}
public void editOrgCode(String value) {
editField(orgCode, value);
}
public void selectParentOrg(String value) {
clickAndSelectValue(parentOrg, value);
}
public boolean isDialogOpened(String title) {
return isPresent(getBy(MODAL_TITLE_BY_NAME, title));
}
}

View file

@ -1,51 +0,0 @@
package pages;
import core.BasePage;
import org.openqa.selenium.WebDriver;
public class ProcessesPage extends BasePage {
private static final String SELECTED_TAB = "//div[@class='radio-content'][@title='%s']";
private static final String TEXT_ON_PAGE = "//text//div[contains(.,'%s')]";
private static final String TAB_INPUT_BY_NAME = "//label[.//span[contains(.,'%s')]]//input";
private static final String BUTTON_BY_NAME = "//button[contains(.,'%s')]";
private static final String LINK_BY_NAME = "//a[@class='nav-link'][contains(.,'%s')]";
private static final String MODAL_TITLE_BY_NAME = "//*[@class='modal-title'][contains(.,'%s')]";
private static final String PROCESS_IN_GRID_BY_ID = "//static-column-grid//div[@row-id='%s']";
public ProcessesPage(WebDriver browser) {
super(browser, "/#/process/instance");
}
public void clickOnButton(String name) {
waitForElementToBeClickable(getBy(BUTTON_BY_NAME, name)).click();
}
public void clickOnLink(String name) {
waitForElementToBeClickable(getBy(LINK_BY_NAME, name)).click();
}
public void clickOnTab(String name) {
waitForElementToBeClickable(getBy(TAB_INPUT_BY_NAME, name)).click();
}
public boolean isTabSelected(String name) {
return isPresent(getBy(SELECTED_TAB, name));
}
public boolean isTitleVisible(String title) {
return isPresent(getBy(TEXT_ON_PAGE, title));
}
public boolean isProcessVisibleInGrid(String processId) {
return isPresent(getBy(PROCESS_IN_GRID_BY_ID, processId));
}
public void clickOnProcessInGrid(String processId) {
waitForElementToBeClickable(getBy(PROCESS_IN_GRID_BY_ID, processId)).click();
}
public boolean isDialogOpened(String title) {
return isPresent(getBy(MODAL_TITLE_BY_NAME, title));
}
}

View file

@ -1,96 +0,0 @@
package pages;
import core.BasePage;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author kote
*/
public class RegistrationPage extends BasePage {
private static final By HEADER = By.xpath("//h2[contains(.,'Регистрация')]");
private static final By PASSWORD_AS_TEXT = By.xpath("//input[@name='password'][@type='text']");
private static final By PASSWORD_AS_SYMBOLS = By.xpath(
"//input[@name='password'][@type='password']");
private static final By REGISTRATION_BUTTON = By.xpath(
"//div[@class='register-btn-box']//button");
private static final By REGISTRATION_ERROR = By.xpath(
"//div[@class='form-register']//div[contains(@class,'alert-danger')]");
private static final String COUNTRY_BY_NAME = "//span[@class='country-name'][contains(.,'%s')]";
@FindBy(xpath = "//a[contains(text(), 'Войти')]")
private WebElement loginLink;
@FindBy(xpath = "//span[@class='arrow-down']")
private WebElement selectCountryArrowButton;
@FindBy(xpath = "//div[@class='input-group-append'][.//i[contains(@class,'eye')]]")
private WebElement passwordEyeButton;
@FindBy(xpath = "//div//input[@name='username']")
private WebElement usernameInput;
@FindBy(xpath = "//div//input[@name='email']")
private WebElement emailInput;
@FindBy(xpath = "//div[contains(label,'Номер телефона')]//input")
private WebElement phoneInput;
@FindBy(xpath = "//div//input[@name='password']")
private WebElement passwordInput;
public RegistrationPage(WebDriver browser) {
super(browser, "/#/registration");
}
public boolean isHeaderVisible() {
return isPresent(HEADER);
}
public void loginLinkClick() {
loginLink.click();
}
public String getMaskForPhone() {
return phoneInput.getAttribute("value");
}
public void selectCountry(String countryName) {
selectCountryArrowButton.click();
waitForVisibilityOfElementLocated(getBy(COUNTRY_BY_NAME, countryName)).click();
}
public void passwordEyeButtonClick() {
passwordEyeButton.click();
}
public boolean isPasswordDisplayedAsText() {
return isPresent(PASSWORD_AS_TEXT);
}
public boolean isPasswordDisplayedAsSymbols() {
return isPresent(PASSWORD_AS_SYMBOLS);
}
public void editUsername(String value) {
editField(usernameInput, value);
}
public void editEmail(String value) {
editField(emailInput, value);
}
public void editPhone(String value) {
editField(phoneInput, value);
}
public void editPassword(String value) {
editField(passwordInput, value);
}
public void registerButtonClick() {
waitForElementToBeClickable(REGISTRATION_BUTTON).click();
}
public String getRegistrationErrorText() {
return waitForVisibilityOfElementLocated(REGISTRATION_ERROR).getText();
}
}

View file

@ -1,58 +0,0 @@
package pages;
import core.BasePage;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author kote
*/
public class ResetPasswordPage extends BasePage {
private static final By HEADER = By.xpath("//p[contains(.,'Вспомнили пароль?')]");
private static final By RESET_BUTTON = By.xpath("//div[@class='reset-password-btn-box']//button");
private static final By CHANGE_BUTTON = By.xpath("//button[contains(.,'Изменить пароль')]");
@FindBy(xpath = "//a[contains(text(), 'Войти')]")
private WebElement loginLink;
@FindBy(xpath = "//div//input[@name='email']")
private WebElement emailInput;
@FindBy(xpath = "//div//input[@name='password']")
private WebElement passwordInput;
@FindBy(xpath = "//div//input[@name='confirmPassword']")
private WebElement confirmPasswordInput;
public ResetPasswordPage(WebDriver browser) {
super(browser, "/#/reset-password");
}
public boolean isHeaderVisible() {
return isPresent(HEADER);
}
public void loginLinkClick() {
loginLink.click();
}
public void resetButtonClick() {
waitForElementToBeClickable(RESET_BUTTON).click();
}
public void changeButtonClick() {
waitForElementToBeClickable(CHANGE_BUTTON).click();
}
public void editEmail(String value) {
editField(emailInput, value);
}
public void editPassword(String value) {
editField(passwordInput, value);
}
public void editConfirmPassword(String value) {
editField(confirmPasswordInput, value);
}
}

View file

@ -1,33 +0,0 @@
package pages;
import core.BasePage;
import org.openqa.selenium.WebDriver;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TestProcessPage extends BasePage {
private static final String PAGE_TITLE_BY_TEXT = "//div[@class='form-group']//*[text()='%s']";
private static final String BUTTON_BY_NAME = "//button[contains(.,'%s')]";
public TestProcessPage(WebDriver browser) {
super(browser, "/#/process/");
}
public boolean isPageTitleVisible(String title) {
return isPresent(getBy(PAGE_TITLE_BY_TEXT, title));
}
public String getProcessId() {
String currentUrl = driver.getCurrentUrl();
Pattern pattern = Pattern.compile("process\\/(\\d+)");
Matcher matcher = pattern.matcher(currentUrl);
matcher.find();
return matcher.group(1);
}
public void clickOnButton(String name) {
waitForElementToBeClickable(getBy(BUTTON_BY_NAME, name)).click();
}
}

View file

@ -1,119 +0,0 @@
package tests;
import core.BaseTest;
import core.Browser;
import core.BrowserArgumentProvider;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import pages.AuthoritiesPage;
import pages.InboxPage;
import pages.LoginPage;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.openqa.selenium.support.PageFactory.initElements;
/**
* @author kote
*/
public class AuthoritiesIT extends BaseTest {
private static final String ADMINISTRATION = "Администрирование";
private static final String AUTHORITIES = "Безопасность действий";
private static final String ALLOW_FOR_ROLE = "Разрешить для роли";
private static final String BPMN_ACTION = "BPMN";
private static final String ADMIN_ACTION = "ADMIN";
private static final String PROCESS_INSTANCE_ACTION = "PROCESS_INSTANCE";
private static final String LIST_ACTION = "LIST";
private static final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(11);
private static String generatedName;
public AuthoritiesIT() {
super();
}
@BeforeAll
public static void beforeAll() {
generatedName = generateName("userForAuthorities");
String encodedPassword = passwordEncoder.encode(generatedName);
String groupId = EXECUTION_MANAGER.insertGroupAndLinkedRole(generatedName);
String userAccountId = EXECUTION_MANAGER.insertUser(generatedName, generatedName + "@test.ru", encodedPassword);
EXECUTION_MANAGER.linkGroupToUser(userAccountId, groupId);
}
@AfterAll
public static void afterAll() {
EXECUTION_MANAGER.deleteUserByEmail(generatedName);
EXECUTION_MANAGER.deleteGroupByName(generatedName);
EXECUTION_MANAGER.deleteRoleByName(generatedName);
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void checkPermissionsForRole(Browser browser) {
//check action allowed for a role:
InboxPage inboxPage = loginInAppByAdmin(browser);
assertTrue(inboxPage.pageLoadSuccessfully());
inboxPage.clickOnMenu(ADMINISTRATION);
inboxPage.clickOnSubMenu(AUTHORITIES);
AuthoritiesPage authoritiesPage = initElements(driver, AuthoritiesPage.class);
assertTrue(authoritiesPage.pageLoadSuccessfully());
authoritiesPage.openActionTree(BPMN_ACTION, ADMIN_ACTION, PROCESS_INSTANCE_ACTION);
authoritiesPage.clickOnAction(LIST_ACTION);
assertTrue(authoritiesPage.pageLoadSuccessfully());
authoritiesPage.clickOnButton(ALLOW_FOR_ROLE);
assertTrue(authoritiesPage.isDialogOpened(ALLOW_FOR_ROLE));
authoritiesPage.selectRole(generatedName);
authoritiesPage.clickOnButtonOnDialog("Разрешить");
assertTrue(authoritiesPage.pageLoadSuccessfully());
assertTrue(authoritiesPage.isRoleOnTheList(generatedName));
logout(inboxPage);
LoginPage loginPage = initElements(driver, LoginPage.class);
assertTrue(loginPage.pageLoadSuccessfully());
loginPage.typeLoginPasswordAndEnter(generatedName, generatedName);
assertTrue(inboxPage.pageLoadSuccessfully());
inboxPage.clickOnMenu(ADMINISTRATION);
assertTrue(inboxPage.isSubMenuVisible("Экземпляры процессов"));
//check action prohibited for a role:
logout(inboxPage);
reloginInAppByAdmin();
assertTrue(inboxPage.pageLoadSuccessfully());
inboxPage.clickOnMenu(ADMINISTRATION);
inboxPage.clickOnSubMenu(AUTHORITIES);
assertTrue(authoritiesPage.pageLoadSuccessfully());
authoritiesPage.openActionTree(BPMN_ACTION, ADMIN_ACTION, PROCESS_INSTANCE_ACTION);
authoritiesPage.clickOnAction(LIST_ACTION);
assertTrue(authoritiesPage.pageLoadSuccessfully());
authoritiesPage.clickOnRole(generatedName);
authoritiesPage.clickOnButton("Запретить");
assertTrue(authoritiesPage.isDialogOpened("Подтверждение действия"));
authoritiesPage.clickOnButton("Да");
assertTrue(authoritiesPage.pageLoadSuccessfully());
assertFalse(authoritiesPage.isRoleOnTheList(generatedName));
//todo dev WEBBPMNEXT-9095
/*logout(inboxPage);
assertTrue(loginPage.pageLoadSuccessfully());
loginPage.typeLoginPasswordAndEnter(generatedName, generatedName);
assertTrue(inboxPage.pageLoadSuccessfully());
assertFalse(inboxPage.isMenuVisible(ADMINISTRATION));*/
}
}

View file

@ -1,168 +0,0 @@
package tests;
import core.BaseTest;
import core.Browser;
import core.BrowserArgumentProvider;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
import pages.InboxPage;
import pages.LoginPage;
import pages.RegistrationPage;
import pages.ResetPasswordPage;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.openqa.selenium.support.PageFactory.initElements;
/**
* @author kote
*/
public class LoginIT extends BaseTest {
private static final String PART_FOR_NAME = "userForLogin";
private static final String REG_EMAIL = "qa_new_account@mail.ru";
private static final String RESET_EMAIL = "password_recovery_account@mail.ru";
public LoginIT() {
super();
}
@AfterAll
public static void afterAll() {
EXECUTION_MANAGER.deleteUserByEmail(REG_EMAIL);
EXECUTION_MANAGER.deleteUserByEmail(RESET_EMAIL);
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void checkLoginWithWrongData(Browser browser) {
LoginPage loginPage = openApp(browser);
assertTrue(loginPage.pageLoadSuccessfully());
String wrongData = "wrong_test";
loginPage.typeLoginPasswordAndEnter(wrongData, wrongData);
assertEquals("Неправильный логин или пароль", loginPage.getLoginErrorText());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void checkDisplayUserFio(Browser browser) {
InboxPage inboxPage = loginInApp(browser);
assertTrue(inboxPage.pageLoadSuccessfully());
inboxPage.clickOnMenu("Пользователь");
assertEquals("Основной-Тестовый Пользователь", inboxPage.getUserFIO());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void checkTransitionsBetweenForms(Browser browser) {
LoginPage loginPage = openApp(browser);
assertTrue(loginPage.pageLoadSuccessfully());
//check transition to registration page:
loginPage.registrationLinkClick();
RegistrationPage registrationPage = initElements(driver, RegistrationPage.class);
assertTrue(registrationPage.pageLoadSuccessfully());
assertTrue(registrationPage.isHeaderVisible());
//check phone mask:
assertEquals("+7 ", registrationPage.getMaskForPhone());
registrationPage.selectCountry("Albania");
assertEquals("+355 ", registrationPage.getMaskForPhone());
//check password view:
assertTrue(registrationPage.isPasswordDisplayedAsSymbols());
registrationPage.passwordEyeButtonClick();
assertTrue(registrationPage.isPasswordDisplayedAsText());
//check transition to login page from registration page:
registrationPage.loginLinkClick();
assertTrue(loginPage.pageLoadSuccessfully());
assertTrue(loginPage.isHeaderVisible());
//check transition to password recovery page:
loginPage.resetPasswordLinkClick();
ResetPasswordPage resetPasswordPage = initElements(driver, ResetPasswordPage.class);
assertTrue(resetPasswordPage.pageLoadSuccessfully());
assertTrue(resetPasswordPage.isHeaderVisible());
//check transition to login page from password recovery page:
resetPasswordPage.loginLinkClick();
assertTrue(loginPage.pageLoadSuccessfully());
assertTrue(loginPage.isHeaderVisible());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void checkRegistration(Browser browser) {
LoginPage loginPage = openApp(browser);
assertTrue(loginPage.pageLoadSuccessfully());
loginPage.registrationLinkClick();
RegistrationPage registrationPage = initElements(driver, RegistrationPage.class);
assertTrue(registrationPage.pageLoadSuccessfully());
String logPas = generateName(PART_FOR_NAME);
registrationPage.editUsername(logPas);
registrationPage.editEmail("qa_test@micord.ru");
registrationPage.editPhone("+79999999999");
registrationPage.editPassword(logPas);
registrationPage.registerButtonClick();
registrationPage.waitForPageToLoad();
assertEquals("Пользователь с данным почтовым адресом уже существует",
registrationPage.getRegistrationErrorText());
registrationPage.editEmail(REG_EMAIL);
registrationPage.registerButtonClick();
assertTrue(registrationPage.pageLoadSuccessfully());
String id = EXECUTION_MANAGER.getUserAccountIdByLogin(logPas);
String token = EXECUTION_MANAGER.getTokenByUserAccountId(id);
String link = applicationUrl + "#confirm?link=" + token;
driver.get(link);
registrationPage.loginLinkClick();
assertTrue(loginPage.pageLoadSuccessfully());
loginPage.typeLoginPasswordAndEnter(logPas, logPas);
InboxPage inboxPage = initElements(driver, InboxPage.class);
assertTrue(inboxPage.pageLoadSuccessfully());
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void checkPasswordRecovery(Browser browser) {
LoginPage loginPage = openApp(browser);
assertTrue(loginPage.pageLoadSuccessfully());
String logPas = generateName(PART_FOR_NAME);
EXECUTION_MANAGER.insertUser(logPas, RESET_EMAIL, logPas);
//здесь создаем пользователя с незакодированным паролем, тк нам не нужно будет по нему логиниться
loginPage.resetPasswordLinkClick();
ResetPasswordPage resetPasswordPage = initElements(driver, ResetPasswordPage.class);
assertTrue(resetPasswordPage.pageLoadSuccessfully());
resetPasswordPage.editEmail(RESET_EMAIL);
resetPasswordPage.resetButtonClick();
assertTrue(resetPasswordPage.pageLoadSuccessfully());
String id = EXECUTION_MANAGER.getUserAccountIdByLogin(logPas);
String token = EXECUTION_MANAGER.getTokenByUserAccountId(id);
String link = applicationUrl + "#new-password?token=" + token;
driver.get(link);
String newPass = generateName("NewPass");
resetPasswordPage.editPassword(newPass);
resetPasswordPage.editConfirmPassword(newPass);
resetPasswordPage.changeButtonClick();
assertTrue(resetPasswordPage.pageLoadSuccessfully());
resetPasswordPage.loginLinkClick();
loginPage.typeLoginPasswordAndEnter(RESET_EMAIL, newPass);
InboxPage inboxPage = initElements(driver, InboxPage.class);
assertTrue(inboxPage.pageLoadSuccessfully());
}
}

View file

@ -1,122 +0,0 @@
package tests;
import core.BaseTest;
import core.Browser;
import core.BrowserArgumentProvider;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
import pages.InboxPage;
import pages.OrganizationsPage;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.openqa.selenium.support.PageFactory.initElements;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author kote
*/
public class OrganizationsIT extends BaseTest {
private static final String CREATE = "Создать";
private static final String EDIT = "Редактировать";
private static final String SAVE = "Сохранить";
private static final String PARENT_ORG_NAME = "Управление ЗАГС г. Казани";
private static final String SUBSIDIARY_ORG_NAME = "ЗАГС Советского р-на";
private static final String PART_FOR_CODE = "org_code_";
public OrganizationsIT() {
super();
}
@AfterAll
public static void afterAll() {
EXECUTION_MANAGER.deleteOrganizationByName(PARENT_ORG_NAME);
EXECUTION_MANAGER.deleteOrganizationByName(SUBSIDIARY_ORG_NAME);
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void crudOrganizationAndSubsidiary(Browser browser) {
InboxPage inboxPage = loginInAppByAdmin(browser);
assertTrue(inboxPage.pageLoadSuccessfully());
inboxPage.clickOnMenu("Администрирование");
inboxPage.clickOnSubMenu("Организации");
OrganizationsPage organizationsPage = initElements(driver, OrganizationsPage.class);
assertTrue(organizationsPage.pageLoadSuccessfully());
assertTrue(organizationsPage.isTitleVisible("Администрирование организаций"));
//check create organization:
organizationsPage.clickOnButton(CREATE);
assertTrue(organizationsPage.pageLoadSuccessfully());
organizationsPage.editOrgName(PARENT_ORG_NAME);
String parentOrgCode = generateName(PART_FOR_CODE);
organizationsPage.editOrgCode(parentOrgCode);
organizationsPage.clickOnButton(SAVE);
assertTrue(organizationsPage.pageLoadSuccessfully());
assertTrue(organizationsPage.isOrganizationVisible(PARENT_ORG_NAME, parentOrgCode));
//check create subsidiary:
organizationsPage.clickOnButton(CREATE);
assertTrue(organizationsPage.pageLoadSuccessfully());
organizationsPage.editOrgName(SUBSIDIARY_ORG_NAME);
String subsidiaryOrgCode = generateName(PART_FOR_CODE);
organizationsPage.editOrgCode(subsidiaryOrgCode);
organizationsPage.selectParentOrg(PARENT_ORG_NAME);
organizationsPage.clickOnButton(SAVE);
assertTrue(organizationsPage.pageLoadSuccessfully());
organizationsPage.clickOnArrowInParentOrganization(PARENT_ORG_NAME, parentOrgCode);
assertTrue(organizationsPage.isOrganizationVisible(SUBSIDIARY_ORG_NAME, subsidiaryOrgCode));
//check that a subsidiary cannot be the same as an organization:
organizationsPage.clickOnOrganization(SUBSIDIARY_ORG_NAME, subsidiaryOrgCode);
organizationsPage.clickOnButton(EDIT);
assertTrue(organizationsPage.pageLoadSuccessfully());
organizationsPage.selectParentOrg(SUBSIDIARY_ORG_NAME);
organizationsPage.clickOnButton(SAVE);
organizationsPage.waitForPageToLoad();
assertFalse(organizationsPage.thereIsNoError());
assertTrue(organizationsPage.getErrorText().contains("Обнаружен цикл при попытке сменить родителя"));
//check edit subsidiary:
organizationsPage.selectParentOrg(PARENT_ORG_NAME);
String newSubsidiaryOrgCode = generateName(PART_FOR_CODE);
organizationsPage.editOrgCode(newSubsidiaryOrgCode);
organizationsPage.clickOnButton(SAVE);
assertTrue(organizationsPage.pageLoadSuccessfully());
organizationsPage.clickOnArrowInParentOrganization(PARENT_ORG_NAME, parentOrgCode);
assertTrue(organizationsPage.isOrganizationVisible(SUBSIDIARY_ORG_NAME, newSubsidiaryOrgCode));
assertFalse(organizationsPage.isOrganizationVisible(PARENT_ORG_NAME, subsidiaryOrgCode));
//check edit parent organization:
organizationsPage.clickOnOrganization(PARENT_ORG_NAME, parentOrgCode);
organizationsPage.clickOnButton(EDIT);
assertTrue(organizationsPage.pageLoadSuccessfully());
String newParentOrgCode = generateName(PART_FOR_CODE);
organizationsPage.editOrgCode(newParentOrgCode);
organizationsPage.clickOnButton(SAVE);
assertTrue(organizationsPage.pageLoadSuccessfully());
assertTrue(organizationsPage.isOrganizationVisible(PARENT_ORG_NAME, newParentOrgCode));
assertFalse(organizationsPage.isOrganizationVisible(PARENT_ORG_NAME, parentOrgCode));
organizationsPage.clickOnArrowInParentOrganization(PARENT_ORG_NAME, newParentOrgCode);
assertTrue(organizationsPage.isOrganizationVisible(SUBSIDIARY_ORG_NAME, newSubsidiaryOrgCode));
//check delete parent organization:
organizationsPage.clickOnOrganization(PARENT_ORG_NAME, newParentOrgCode);
organizationsPage.clickOnButton("Удалить");
assertTrue(organizationsPage.isDialogOpened("Подтверждение действия"));
organizationsPage.clickOnButton("Да");
assertTrue(organizationsPage.pageLoadSuccessfully());
assertFalse(organizationsPage.isOrganizationVisible(PARENT_ORG_NAME, newParentOrgCode));
assertFalse(organizationsPage.isOrganizationVisible(SUBSIDIARY_ORG_NAME, newSubsidiaryOrgCode));
}
}

View file

@ -1,104 +0,0 @@
package tests;
import core.BaseTest;
import core.Browser;
import core.BrowserArgumentProvider;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
import pages.InboxPage;
import pages.ProcessesPage;
import pages.TestProcessPage;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.openqa.selenium.support.PageFactory.initElements;
/**
* @author kote
*/
public class ProcessesIT extends BaseTest {
private static final String ADMINISTRATION = "Администрирование";
private static final String PROCESSES_INSTANCES = "Экземпляры процессов";
private static final String COMPLETED = "Завершенные";
private static final String ABORTED = "Прерванные";
private static final String TEST_PROCESS = "test_process";
private static final String TEST_PAGE_TITLE = "Тестовая страница";
public ProcessesIT() {
super();
}
@ParameterizedTest
@ArgumentsSource(BrowserArgumentProvider.class)
public void checkActionsWithProcessesInstances(Browser browser) {
InboxPage inboxPage = loginInAppByAdmin(browser);
assertTrue(inboxPage.pageLoadSuccessfully());
//check start process:
inboxPage.startProcess(TEST_PROCESS);
TestProcessPage testProcessPage = initElements(driver, TestProcessPage.class);
assertTrue(testProcessPage.pageLoadSuccessfully());
assertTrue(testProcessPage.isPageTitleVisible(TEST_PAGE_TITLE));
String processId = testProcessPage.getProcessId();
//check active processes:
inboxPage.clickOnMenu(ADMINISTRATION);
inboxPage.clickOnSubMenu(PROCESSES_INSTANCES);
ProcessesPage processesPage = initElements(driver, ProcessesPage.class);
assertTrue(processesPage.pageLoadSuccessfully());
assertTrue(processesPage.isTitleVisible("Процессы"));
assertTrue(processesPage.isTabSelected("Активные"));
assertTrue(processesPage.isProcessVisibleInGrid(processId));
//check view process instance:
processesPage.clickOnProcessInGrid(processId);
processesPage.clickOnButton("Просмотреть");
assertTrue(processesPage.pageLoadSuccessfully());
assertTrue(processesPage.isTitleVisible("Экземпляр процесса"));
processesPage.clickOnLink("Текст");
assertTrue(processesPage.thereIsNoError());
processesPage.clickOnLink("Изображение");
assertTrue(processesPage.thereIsNoError());
processesPage.clickOnButton("Закрыть");
assertTrue(processesPage.pageLoadSuccessfully());
//check aborted processes:
processesPage.clickOnProcessInGrid(processId);
processesPage.clickOnButton("Прервать");
assertTrue(processesPage.isDialogOpened("Подтверждение действия"));
processesPage.clickOnButton("Да");
assertTrue(processesPage.pageLoadSuccessfully());
assertFalse(processesPage.isProcessVisibleInGrid(processId));
processesPage.clickOnTab(ABORTED);
assertTrue(processesPage.pageLoadSuccessfully());
assertTrue(processesPage.isTabSelected(ABORTED));
assertTrue(processesPage.isProcessVisibleInGrid(processId));
//check complete process:
inboxPage.startProcess(TEST_PROCESS);
assertTrue(testProcessPage.pageLoadSuccessfully());
String newProcessId = testProcessPage.getProcessId();
testProcessPage.clickOnButton("Завершить");
assertTrue(inboxPage.pageLoadSuccessfully());
assertFalse(testProcessPage.isPageTitleVisible(TEST_PAGE_TITLE));
//check completed processes:
inboxPage.clickOnMenu(ADMINISTRATION);
inboxPage.clickOnSubMenu(PROCESSES_INSTANCES);
assertTrue(processesPage.pageLoadSuccessfully());
assertFalse(processesPage.isProcessVisibleInGrid(newProcessId));
processesPage.clickOnTab(COMPLETED);
assertTrue(processesPage.pageLoadSuccessfully());
assertTrue(processesPage.isTabSelected(COMPLETED));
assertTrue(processesPage.isProcessVisibleInGrid(newProcessId));
}
}

View file

@ -1,29 +0,0 @@
# параметр включения/выключения параллельного выполнения тестов.
junit.jupiter.execution.parallel.enabled = true
# протестирована стратегия параллельности fixed и dynamic (оба режима на параллельность запуска тестов не повлияли).
junit.jupiter.execution.parallel.config.strategy = dynamic
# параметр желаемого параллелизма (проверено с разными значениями (1-10), на параллельность запуска тестов не повлияло).
# junit.jupiter.execution.parallel.config.dynamic.factor = 1.0
# параметр максимального размера пула (проверено с разными значениями (1-10), на параллельность запуска тестов не повлияло).
junit.jupiter.execution.parallel.config.dynamic.max-pool-size-factor = 6.0
# параллель внутри класса (настроено последовательно, т.к. параллельно создаётся очередь и падает ошибка Failed to create driver).
junit.jupiter.execution.parallel.mode.default = concurrent
# параллель внутри сьюта
#junit.jupiter.execution.parallel.mode.classes.default = concurrent
# возможные стратегии параллельности dynamic, fixed и custom:
# dynamic - вычисляет желаемый параллелизм на основе количества доступных процессоров / ядер, умноженного на коэф-т dynamic.factor. Настраиваемые значения:
# junit.jupiter.execution.parallel.config.dynamic.factor параметр конфигурации (по умолчанию имеет значение 1) - положительное десятичное число
# junit.jupiter.execution.parallel.config.dynamic.max-pool-size-factor параметр конфигурации можно использовать для ограничения максимального количества потоков
# (по умолчанию 256 + значение junit.jupiter.execution.parallel.config.dynamic.factor, умноженное на количество доступных процессоров / ядер) - положительное десятичное число, должно быть больше или равно 1.0
# fixed - устанавливает закрепленное значение параллелизма с помощью коэф-тов:
# junit.jupiter.execution.parallel.config.fixed.parallelism желаемый параллелизм для fixed стратегии (нет значения по умолчанию) - положительное целое число
# junit.jupiter.execution.parallel.config.fixed.max-pool-size желаемый максимальный размер пула (256 + значение junit.jupiter.execution.parallel.config.fixed.parallelism) - положительное целое число,
# должно быть больше или равно junit.jupiter.execution.parallel.config.fixed.parallelism
# custom - пользовательская реализацию с помощью обязательного junit.jupiter.execution.parallel.config.custom.class.
# Пример класса кастомной настройки: https://github.com/sormuras/junit5-1858-fixed-parallelism/commit/1fb2646711c6d59ad68241822e1a609db417c938#diff-d74841653c5af688ce3524c83cc4cf62bad536c64493e888c208ee2a750b6b88
#
# параметр junit.jupiter.execution.parallel.mode.default настраивает параллельность внутри класса (тесты)
# параметр junit.jupiter.execution.parallel.mode.classes.default настраивает параллельность внутри сьюта (IT классы)
# concurrent - паралльный запуск
# same_thread - последовательный запуск

View file

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%-4level] %msg%n</pattern>
</encoder>
</appender>
<logger name="io.github.bonigarcia" level="DEBUG" />
<logger name="io" level="WARN" />
<logger name="org" level="WARN" />
<logger name="com" level="WARN" />
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View file

@ -1,15 +0,0 @@
login = qa_test
password = qa_test
demo_login = demo@example.com
demo_password = demo
qa_admin_login = qa_admin
qa_admin_password = qa_admin
tt_kerberos_url = http://desktop-k0nottv.asd.center.cg:8082/task-tracker
security_ldap_sync_db_url = jdbc:postgresql://185.171.13.99:5432/sec_db_task_tracker_ldap_sync
security_ldap_sync_db_user = sec_user_tt
security_ldap_sync_db_password = sec_user_tt
database_driver = org.postgresql.Driver