Skip to content

Commit

Permalink
Merge pull request #27 from ETS-TAF/feature/selenium
Browse files Browse the repository at this point in the history
Feature/selenium
  • Loading branch information
mouaadbbk authored Nov 13, 2023
2 parents 30eed85 + 45a57d1 commit eb59b2f
Show file tree
Hide file tree
Showing 35 changed files with 1,193 additions and 43 deletions.
1 change: 0 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
/.idea
/k8s
/pulumi
/selenium
/testapi
/tests-ui
/frontend/node_modules
14 changes: 14 additions & 0 deletions backend/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@
<artifactId>backend</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>ca.etsmtl</groupId>
<artifactId>frontend</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
Expand Down Expand Up @@ -76,6 +86,10 @@
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package ca.etsmtl.taf.apiCommunication;

import ca.etsmtl.taf.dto.SeleniumCaseDto;
import ca.etsmtl.taf.entity.SeleniumActionRequest;
import ca.etsmtl.taf.entity.SeleniumCaseResponse;
import ca.etsmtl.taf.entity.SeleniumTestCase;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.util.List;

@Component
public class SeleniumServiceRequester {
private final WebClient webClient;

@Autowired
public SeleniumServiceRequester(WebClient webClient) {
this.webClient = webClient;
}

public Mono<SeleniumCaseResponse> sendTestCase(SeleniumCaseDto testCase) {
return webClient.post()
.uri("/microservice/selenium/test")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.body(Mono.just(testCase), SeleniumCaseDto.class)
.retrieve()
.bodyToMono(SeleniumCaseResponse.class);
}
}
27 changes: 27 additions & 0 deletions backend/src/main/java/ca/etsmtl/taf/config/WebConfigSelenium.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package ca.etsmtl.taf.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;

@Configuration
public class WebConfigSelenium {

@Value("${taf.app.selenium_container_url}")
String SELENIUM_CONTAINER_URL;

@Value("${taf.app.selenium_container_port}")
String SELENIUM_CONTAINER_PORT;

@Bean
public WebClient webClient() {
return WebClient.builder()
.baseUrl(SELENIUM_CONTAINER_URL + ":" + SELENIUM_CONTAINER_PORT)
.defaultCookie("cookie-name", "cookie-value")
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package ca.etsmtl.taf.controller;

import ca.etsmtl.taf.dto.SeleniumCaseDto;
import ca.etsmtl.taf.entity.SeleniumCaseResponse;
import ca.etsmtl.taf.service.SeleniumService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;

@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping("/api")
public class TestSeleniumController {
private final SeleniumService seleniumService;

public TestSeleniumController(SeleniumService seleniumService) {
this.seleniumService = seleniumService;
}

@PostMapping("/testselenium")
public ResponseEntity<List<SeleniumCaseResponse>> runTests(@RequestBody List<SeleniumCaseDto> seleniumCases) throws URISyntaxException, IOException, InterruptedException {
List<SeleniumCaseResponse> response = seleniumService.sendTestCases(seleniumCases);
return ResponseEntity.ok(response);
}
}
13 changes: 13 additions & 0 deletions backend/src/main/java/ca/etsmtl/taf/dto/SeleniumCaseDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ca.etsmtl.taf.dto;

import ca.etsmtl.taf.entity.SeleniumActionRequest;
import lombok.Getter;

import java.util.List;

@Getter
public class SeleniumCaseDto {
int case_id;
String caseName;
List<SeleniumActionRequest> actions;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ca.etsmtl.taf.entity;

import lombok.Getter;

@Getter
public class SeleniumActionRequest {
int action_id;
int action_type_id;
String action_type_name;
String object;
String input;
String target;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package ca.etsmtl.taf.entity;

import lombok.Data;

import java.io.Serializable;
import java.util.List;

@Data
public class SeleniumCaseResponse implements Serializable {
int case_id;
String caseName;
public List<SeleniumActionRequest> seleniumActions;
public boolean success;
public long timestamp;
public long duration;
public String output;
}
10 changes: 10 additions & 0 deletions backend/src/main/java/ca/etsmtl/taf/entity/SeleniumTestCase.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package ca.etsmtl.taf.entity;

import lombok.Getter;

import java.util.List;

@Getter
public class SeleniumTestCase {
List<SeleniumActionRequest> seleniumActionRequestList;
}
31 changes: 31 additions & 0 deletions backend/src/main/java/ca/etsmtl/taf/service/SeleniumService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package ca.etsmtl.taf.service;

import ca.etsmtl.taf.apiCommunication.SeleniumServiceRequester;
import ca.etsmtl.taf.dto.SeleniumCaseDto;
import ca.etsmtl.taf.entity.SeleniumActionRequest;
import ca.etsmtl.taf.entity.SeleniumCaseResponse;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

@Service
public class SeleniumService {
private final SeleniumServiceRequester seleniumServiceRequester;

public SeleniumService(SeleniumServiceRequester seleniumServiceRequester) {
this.seleniumServiceRequester = seleniumServiceRequester;
}

public List<SeleniumCaseResponse> sendTestCases(List<SeleniumCaseDto> seleniumCases) throws URISyntaxException, IOException, InterruptedException {
List<SeleniumCaseResponse> testResults = new ArrayList<>();
for(SeleniumCaseDto seleniumCaseDto : seleniumCases) {

SeleniumCaseResponse testCaseResult = seleniumServiceRequester.sendTestCase(seleniumCaseDto).block();
testResults.add(testCaseResult);
}
return testResults;
}
}
4 changes: 3 additions & 1 deletion backend/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ taf:
jwtSecret: bezKoderSecretKey
jwtExpirationMs: 86400000
testAPI_url: http://localhost
testAPI_port: 8082
testAPI_port: 8082
selenium_container_url: http://selenium
selenium_container_port: 8090
20 changes: 11 additions & 9 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,17 @@
version: "3.9"
services:
testapi:
image: testapi
container_name: testapi
build:
context: ./testapi
ports:
# TEST_API_SERVICE_PORT is defined as env variable in .docker_config.env
- "${TEST_API_SERVICE_PORT}:${TEST_API_SERVICE_PORT}"
backend:
image: back
container_name: back
build:
context: ./
dockerfile: ./backend/Dockerfile
ports:
- "9000:80"
- "8080:8080"
env_file:
# Specifying the env file with necessaries values
- .docker_config.env

frontend:
image: front
container_name: front
Expand All @@ -28,3 +21,12 @@ services:
- "4200:80"
depends_on:
- backend

selenium:
image: selenium
container_name: selenium
build:
context: ./
dockerfile: ./selenium/Dockerfile
ports:
- "8090:8090"
7 changes: 7 additions & 0 deletions frontend/src/app/selenium/test-selenium.component.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.showModelResult{
width: 100%; background-color: rgba(0, 0, 0, 0.4); height: 100vh;position: absolute;left: 0;top: 0; z-index: 9999;
}

.hideIt{
visibility: hidden;
}
53 changes: 52 additions & 1 deletion frontend/src/app/selenium/test-selenium.component.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,53 @@
<br><br>
<!-- model of results -->
<div class="showModelResult hideIt" id="modelResult">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticModalLabel">Cases Result</h5>
</div>
<div class="modal-body">
<div *ngIf="testResult">
<div class="progress">
<div class="progress-bar" role="progressbar" [style.width]="percentage + '%'" aria-valuenow="percentage" aria-valuemin="0" aria-valuemax="100">{{percentage}}%</div>
</div>
<table class="table">
<thead>
<tr>
<th scope="col">Case ID</th>
<th scope="col">Case Name</th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let result of testResult">
<td>{{result.case_id}}</td>
<td>{{result.caseName}}</td>
<td>
<span class="badge bg-success" *ngIf="result.success==true">success</span>
<span class="badge bg-danger" *ngIf="result.success==false">failed</span>
</td>

</tr>
</tbody>
</table>

</div>
<div class="" id="spinner">
<div class="text-center">
<div class="spinner-border text-primary" style="width: 3rem; height: 3rem;" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger"(click)="hideResultModal()">Close</button>
</div>
</div>
</div>
</div>
<!-- model of new action -->
<div class="modal fade" tabindex="-1" id="addAction" aria-labelledby="Add new Action" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
<div class="modal-dialog modal-dialog-centered modal-xl">
<div class="modal-content">
Expand Down Expand Up @@ -32,6 +81,7 @@ <h5 class="modal-title">New Action</h5>
</div>
</div>
</div>
<!-- model of new Case -->
<div class="modal fade" tabindex="-1" id="addCase" aria-labelledby="Add new Case" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
Expand All @@ -51,6 +101,7 @@ <h5 class="modal-title">New Case</h5>
</div>
</div>
</div>
<!-- show the added cases and actions -->
<div class="container">
<div class="btn-group" role="group" aria-label="Basic outlined example">
<button type="button" class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#addCase">
Expand All @@ -59,7 +110,7 @@ <h5 class="modal-title">New Case</h5>
<button type="button" class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#addAction" id="addActionButton" disabled>
Add New Action
</button>
<button type="button" class="btn btn-success" (click)="runMethod(cases)">Run</button>
<button type="button" class="btn btn-success" data-toggle="modal" data-target="#resultModal" (click)="runMethod(cases)">Run</button>
</div><br><br>
<div class="container" *ngFor="let case of cases">

Expand Down
Loading

0 comments on commit eb59b2f

Please sign in to comment.