Équipe 3 – Phase 2: Timeout, Response Time Validation & Gherkin Editor Fixes - #56
Conversation
…tor fixes Backend: - Add configurable testApiTimeout (default 30s) for HttpClient proxy - Forward responseTime and expectedHeaders fields to testapi microservice - Add 3 timeout unit tests (87 total, 0 failures) Testapi: - Add TimeoutConfig: RestAssured connection/socket/connectionManager timeout - Add /slow?delay=N endpoint for timeout testing - Handle SocketTimeoutException with explicit error message - Enable checkResponseTime() validation (was disabled) Frontend: - Fix Gherkin editor cursor misalignment on last line (trailing newline) - Cache highlightedHtml to avoid recompute on every Angular CD cycle - Fix overflow: hidden -> auto on highlight layer for scroll sync - Change Gherkin parser regex .+ to .* to accept empty body - Display actualResponseTime in test results Other: - Optimize .dockerignore (1.2GB -> 50MB image context) - Update README and TEST-REPORT with timeout docs and 87 tests
Replace nested quantifiers ([a-z\d]([a-z\d\-.]*[a-z\d])*) with atomic pattern ([a-z\d]+(?:[\-.][a-z\d]+)*) to eliminate exponential backtracking on malicious input.
There was a problem hiding this comment.
Pull request overview
Implements Équipe 3 Phase 4 milestone across the testapi microservice, backend proxy, and Angular frontend: end-to-end timeout handling, response-time validation, Gherkin editor fixes, OAuth2/refresh-token support, persistence for API test definitions, and Docker/build optimizations.
Changes:
- Added timeout configuration on both backend→testapi proxy and testapi→target API calls, with response-time capture/validation and clearer error reporting.
- Added/updated frontend features: Gherkin editor (cursor/scroll/perf fixes), progressive test execution UI, persisted test definitions via backend CRUD, and Google OAuth2 callback + refresh-token handling.
- Build/test/infra updates:
.dockerignore, Maven/Docker tweaks, expanded test suite + docs.
Reviewed changes
Copilot reviewed 113 out of 115 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| user/src/main/java/ca/etsmtl/taf/user/services/UserService.java | Adjusts update behavior and adds id null validation. |
| user/src/main/java/ca/etsmtl/taf/user/services/JwtService.java | Removes unused imports/field wiring. |
| user/src/main/java/ca/etsmtl/taf/user/repository/UserRepository.java | Adds @NonNull on existsById. |
| user/src/main/java/ca/etsmtl/taf/user/payload/request/PasswordRequest.java | Removes unused import. |
| user/src/main/java/ca/etsmtl/taf/user/jwt/JwtUtil.java | Removes unused token helpers. |
| user/src/main/java/ca/etsmtl/taf/user/jwt/JwtAuthenticationFilter.java | Adds @NonNull annotations to filter parameters. |
| user/src/main/java/ca/etsmtl/taf/user/controller/UserController.java | Removes unused auth-related wiring. |
| user/src/main/java/ca/etsmtl/taf/user/AuthGatewayApplication.java | Removes unused imports. |
| testapi-Service/testapi/src/main/resources/application.yml | Adds timeout configuration properties and fixes YAML formatting. |
| testapi-Service/testapi/src/main/java/org/requests/payload/request/TestApiRequest.java | Migrates validation import to jakarta. |
| testapi-Service/testapi/src/main/java/org/requests/payload/request/Answer.java | Adds actualResponseTime field to responses. |
| testapi-Service/testapi/src/main/java/org/requests/TestManager.java | Expands Spring scan packages to include new config package. |
| testapi-Service/testapi/src/main/java/org/requests/TestApiController.java | Adds /slow endpoint for timeout verification. |
| testapi-Service/testapi/src/main/java/org/requests/RequestController.java | Adds timeout handling, response time capture, header/body null-guards, and re-enables response-time validation. |
| testapi-Service/testapi/src/main/java/org/config/TimeoutConfig.java | New Rest-Assured timeout configuration via Spring @Configuration. |
| testapi-Service/testapi/Dockerfile | Skips tests in Docker build and runs Maven in batch mode. |
| testapi-Service/selenium/src/test/java/ca/etsmtl/selenium/SeleniumApplicationTests.java | Removes unused import. |
| testapi-Service/selenium/src/main/java/ca/etsmtl/selenium/requests/UseSelenium.java | Updates Selenium timeout API usage and attribute retrieval. |
| testapi-Service/selenium/src/main/java/ca/etsmtl/selenium/config/DevCorsConfiguration.java | Adds @NonNull to CORS registry parameter. |
| testapi-Service/run-tests-testapi.ps1 | Adds a one-command backend test runner. |
| testapi-Service/pom.xml | Sets UTF-8 encodings for build/reporting. |
| testapi-Service/frontend/src/environments/environment.ts | Adds oauth2BackendUrl for local dev. |
| testapi-Service/frontend/src/environments/environment.prod.ts | Adds oauth2BackendUrl for prod config. |
| testapi-Service/frontend/src/app/register/register.component.spec.ts | Updates unit test module setup (schemas/imports). |
| testapi-Service/frontend/src/app/project/project.component.spec.ts | Updates unit test module setup (schemas/imports). |
| testapi-Service/frontend/src/app/profile/profile.component.spec.ts | Adds token-storage mock and NO_ERRORS_SCHEMA. |
| testapi-Service/frontend/src/app/performance-test-api/gatling-api/gatling-api.component.spec.ts | Updates unit test module setup (schemas/imports). |
| testapi-Service/frontend/src/app/oauth2-callback/oauth2-callback.component.ts | New OAuth2 callback handler storing tokens and user info. |
| testapi-Service/frontend/src/app/oauth2-callback/oauth2-callback.component.html | New OAuth2 callback UI. |
| testapi-Service/frontend/src/app/oauth2-callback/oauth2-callback.component.css | New OAuth2 callback styling. |
| testapi-Service/frontend/src/app/models/testmodel2.ts | Adds mongo id, actual response time, and pending state support. |
| testapi-Service/frontend/src/app/models/testResponseModel.ts | Adds actualResponseTime to response model. |
| testapi-Service/frontend/src/app/login/login.component.ts | Supports refresh token storage and adds Google login redirect. |
| testapi-Service/frontend/src/app/login/login.component.spec.ts | Updates unit test module setup (schemas/imports). |
| testapi-Service/frontend/src/app/login/login.component.html | Adds Google login button UI. |
| testapi-Service/frontend/src/app/login/login.component.css | Adds Google button styling and tweaks existing styles. |
| testapi-Service/frontend/src/app/interface-test-api/test-api/test-api.component.ts | Adds Gherkin mode, progressive execution, loadDefinitions-on-login. |
| testapi-Service/frontend/src/app/interface-test-api/test-api/test-api.component.spec.ts | Adds unit tests for Gherkin mode, editing, and response time UI. |
| testapi-Service/frontend/src/app/interface-test-api/test-api/test-api.component.html | Adds Gherkin editor toggle, tooltip/spinner UI, and edit action. |
| testapi-Service/frontend/src/app/interface-test-api/test-api/add-test-dialog/add-test-dialog.component.ts | Adds edit mode, input body field, header mapping improvements, update calls. |
| testapi-Service/frontend/src/app/interface-test-api/test-api/add-test-dialog/add-test-dialog.component.html | Adds edit-mode titles/buttons and input textarea. |
| testapi-Service/frontend/src/app/interface-test-api/gherkin-editor/gherkin-editor.component.ts | New Gherkin editor with overlay highlighting + scroll sync. |
| testapi-Service/frontend/src/app/interface-test-api/gherkin-editor/gherkin-editor.component.spec.ts | New unit tests for editor parsing/highlighting and events. |
| testapi-Service/frontend/src/app/interface-test-api/gherkin-editor/gherkin-editor.component.html | New editor template + preview + toolbar/help. |
| testapi-Service/frontend/src/app/interface-test-api/gherkin-editor/gherkin-editor.component.css | New editor styling including overlay highlighting behavior. |
| testapi-Service/frontend/src/app/home/home.component.spec.ts | Updates unit test module setup (schemas/imports). |
| testapi-Service/frontend/src/app/gatling/gatling.component.spec.ts | Updates unit test module setup (schemas/imports). |
| testapi-Service/frontend/src/app/board-user/board-user.component.spec.ts | Updates unit test module setup (schemas/imports). |
| testapi-Service/frontend/src/app/board-admin/board-admin.component.spec.ts | Updates unit test module setup (schemas/imports). |
| testapi-Service/frontend/src/app/app.module.ts | Registers OAuth2 callback + Gherkin editor and Material modules. |
| testapi-Service/frontend/src/app/app.component.ts | Changes logout behavior to redirect to /login. |
| testapi-Service/frontend/src/app/app.component.spec.ts | Adjusts test setup and removes obsolete title assertions. |
| testapi-Service/frontend/src/app/app-routing.module.ts | Adds OAuth2 callback route. |
| testapi-Service/frontend/src/app/_services/user.service.spec.ts | Adds HttpClientTestingModule to service test setup. |
| testapi-Service/frontend/src/app/_services/token-storage.service.ts | Adds refresh token storage helpers. |
| testapi-Service/frontend/src/app/_services/test-api.service.ts | Adds HTTP-backed persistence, progressive execution, pending-state helpers. |
| testapi-Service/frontend/src/app/_services/test-api.service.spec.ts | Adds HttpTestingController coverage for persistence + progressive execution. |
| testapi-Service/frontend/src/app/_services/performance-test-api.service.spec.ts | Adds HttpClientTestingModule to test setup. |
| testapi-Service/frontend/src/app/_services/gherkin-parser.service.ts | New lightweight Gherkin parser + serializer. |
| testapi-Service/frontend/src/app/_services/auth.service.ts | Adds refresh-token call to backend auth API. |
| testapi-Service/frontend/src/app/_services/auth.service.spec.ts | Adds HttpClientTestingModule to test setup. |
| testapi-Service/frontend/src/app/_helpers/auth.interceptor.ts | Switches to Authorization header + implements refresh-token retry logic. |
| testapi-Service/frontend/package.json | Formatting-only change. |
| testapi-Service/frontend/angular.json | Increases bundle/style budget thresholds. |
| testapi-Service/documentation/CONVENTIONS.md | Documents backend testing conventions and commands. |
| testapi-Service/backend/src/test/resources/application.yml | Adds test-only Spring config disabling Mongo/Eureka auto-config. |
| testapi-Service/backend/src/test/java/ca/etsmtl/taf/security/services/UserDetailsServiceImplTest.java | Adds unit tests for user details loading. |
| testapi-Service/backend/src/test/java/ca/etsmtl/taf/security/services/UserDetailsImplTest.java | Adds unit tests for UserDetails wrapper behavior. |
| testapi-Service/backend/src/test/java/ca/etsmtl/taf/security/oauth2/OAuth2LoginSuccessHandlerTest.java | Adds unit tests for Google OAuth2 success flow and edge cases. |
| testapi-Service/backend/src/test/java/ca/etsmtl/taf/security/jwt/JwtUtilsTest.java | Adds extensive JWT/refresh-token unit tests. |
| testapi-Service/backend/src/test/java/ca/etsmtl/taf/security/jwt/AuthTokenFilterTest.java | Adds unit tests for JWT filter behavior. |
| testapi-Service/backend/src/test/java/ca/etsmtl/taf/security/jwt/AuthEntryPointJwtTest.java | Adds unit tests for 401 JSON response shape. |
| testapi-Service/backend/src/test/java/ca/etsmtl/taf/security/WebSecurityConfigTest.java | Adds security integration tests for public/protected routes. |
| testapi-Service/backend/src/test/java/ca/etsmtl/taf/payload/response/MessageResponseTest.java | Adds DTO tests for message response. |
| testapi-Service/backend/src/test/java/ca/etsmtl/taf/payload/response/JwtResponseTest.java | Adds DTO tests including refresh token field. |
| testapi-Service/backend/src/test/java/ca/etsmtl/taf/entity/UserEntityTest.java | Adds entity tests including OAuth2 user constructor. |
| testapi-Service/backend/src/test/java/ca/etsmtl/taf/entity/RoleTest.java | Adds role entity tests. |
| testapi-Service/backend/src/test/java/ca/etsmtl/taf/controller/TestApiControllerTest.java | Adds proxy timeout + DTO forwarding tests. |
| testapi-Service/backend/src/test/java/ca/etsmtl/taf/controller/OAuth2ControllerTest.java | Adds tests for OAuth2 helper endpoint. |
| testapi-Service/backend/src/test/java/ca/etsmtl/taf/controller/AuthControllerTest.java | Adds tests for signin/signup/refresh-token endpoints. |
| testapi-Service/backend/src/test/java/ca/etsmtl/taf/controller/ApiTestDefinitionControllerTest.java | Adds CRUD tests for persisted definitions. |
| testapi-Service/backend/src/test/java/ca/etsmtl/taf/TestAutomationFrameworkApplicationTests.java | Disables full-context test requiring MongoDB. |
| testapi-Service/backend/src/main/resources/application.yml | Adds OAuth2 config, refresh expiry, proxy timeout, redirect URL config. |
| testapi-Service/backend/src/main/java/ca/etsmtl/taf/security/oauth2/OAuth2LoginSuccessHandler.java | New OAuth2 success handler creating/linking users and redirecting with tokens. |
| testapi-Service/backend/src/main/java/ca/etsmtl/taf/security/jwt/JwtUtils.java | Adds refresh token + username-from-expired-token helpers. |
| testapi-Service/backend/src/main/java/ca/etsmtl/taf/security/WebSecurityConfig.java | Adds OAuth2 login support and updates security rules/session policy. |
| testapi-Service/backend/src/main/java/ca/etsmtl/taf/repository/UserRepository.java | Adds finders for email/googleId. |
| testapi-Service/backend/src/main/java/ca/etsmtl/taf/repository/ApiTestDefinitionRepository.java | New repository for persisted API test definitions. |
| testapi-Service/backend/src/main/java/ca/etsmtl/taf/payload/response/JwtResponse.java | Adds refresh token to auth response model. |
| testapi-Service/backend/src/main/java/ca/etsmtl/taf/payload/request/TestApiRequest.java | Adds responseTime + expectedHeaders to proxy DTO. |
| testapi-Service/backend/src/main/java/ca/etsmtl/taf/payload/request/RefreshTokenRequest.java | New request DTO for refresh-token endpoint. |
| testapi-Service/backend/src/main/java/ca/etsmtl/taf/entity/User.java | Adds OAuth2 provider/googleId support and adjusts username size. |
| testapi-Service/backend/src/main/java/ca/etsmtl/taf/entity/ApiTestDefinition.java | New persisted API test definition entity. |
| testapi-Service/backend/src/main/java/ca/etsmtl/taf/controller/TestController.java | Removes obsolete controller. |
| testapi-Service/backend/src/main/java/ca/etsmtl/taf/controller/TestApiController.java | Adds configurable HttpClient timeout for proxy requests. |
| testapi-Service/backend/src/main/java/ca/etsmtl/taf/controller/OAuth2Controller.java | Adds helper endpoint returning OAuth2 login URL metadata. |
| testapi-Service/backend/src/main/java/ca/etsmtl/taf/controller/AuthController.java | Adds refresh-token endpoint and returns refresh token on signin. |
| testapi-Service/backend/src/main/java/ca/etsmtl/taf/controller/ApiTestDefinitionController.java | New CRUD controller for per-user persisted definitions. |
| testapi-Service/backend/src/main/java/ca/etsmtl/taf/config/OpenApiConfig.java | Updates OpenAPI description for JWT + OAuth2 flows. |
| testapi-Service/backend/src/main/java/ca/etsmtl/taf/config/MongoAuditingConfig.java | Moves @EnableMongoAuditing into separate config for test slices. |
| testapi-Service/backend/src/main/java/ca/etsmtl/taf/TestAutomationFrameworkApplication.java | Removes @EnableMongoAuditing annotation from main class. |
| testapi-Service/backend/pom.xml | Adds oauth2-client, JaCoCo, encoding config; moves frontend dep to profile. |
| testapi-Service/backend/pom.docker.xml | Adds oauth2-client dependency for Docker build. |
| testapi-Service/backend/.env | Updates JWT expirations and adds refresh expiry. |
| testapi-Service/TEST-REPORT.md | Adds detailed backend test report and coverage summary. |
| testapi-Service/Dockerfile.local | Adjusts Maven test skipping flag during local Docker build. |
| testapi-Service/CONTRIBUTING.md | Adds explicit backend test-running instructions and expectations. |
| testapi-Service/.dockerignore | Adds ignores to reduce Docker build context size. |
| gateway/src/main/java/ca/etsmtl/taf/gateway/GatewayApplication.java | Removes unused import. |
| docker-compose-local-test.yml | Adds mongo-express config and updates backend env vars for OAuth2/JWT refresh. |
| auth/src/main/java/ca/etsmtl/taf/auth/services/JwtService.java | Removes unused imports. |
| auth/src/main/java/ca/etsmtl/taf/auth/services/CustomUserDetailsService.java | Removes unused import. |
| .gitignore | Adds *.py ignore rule and normalizes node_modules ignore. |
Comments suppressed due to low confidence (1)
testapi-Service/frontend/src/app/interface-test-api/test-api/test-api.component.ts:49
getTestList()creates a new subscription every time it’s called and is invoked repeatedly (e.g., inngOnInit()and during progressive execution). This will leak subscriptions and can cause duplicated updates. Subscribe once (e.g., inngOnInit) and store/unsubscribe on destroy, or bindtests$directly in the template viaasyncpipe.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| User user = userRepository.findByUsername(username).orElseThrow(); | ||
| if(signUpRequest.getFullName().isEmpty()) | ||
| if(!signUpRequest.getFullName().isEmpty()) | ||
| user.setFullName(signUpRequest.getFullName()); | ||
| if(signUpRequest.getEmail().isEmpty()) | ||
| if(!signUpRequest.getEmail().isEmpty()) | ||
| user.setEmail(signUpRequest.getEmail()); | ||
|
|
||
| return userRepository.save(user); | ||
| if (user != null) { | ||
| return userRepository.save(user); | ||
| } | ||
| return user; |
There was a problem hiding this comment.
update() fetches the user via orElseThrow(), so user can never be null here. The if (user != null) branch and return user; are dead code and make the flow harder to read; simplify to a single return userRepository.save(user) after applying updates.
| if (test.input) { | ||
| lines.push(` And the input is '${test.input}'`); | ||
| } | ||
|
|
||
| if (test.expectedOutput) { | ||
| lines.push(` And the expected output is '${test.expectedOutput}'`); | ||
| } |
There was a problem hiding this comment.
toGherkin() uses truthy checks (if (test.input) / if (test.expectedOutput)) which drop empty-string values. Since parsing now supports And the input is '' / And the expected output is '', converting back to Gherkin should preserve empty strings by checking !== undefined (or != null) instead of truthiness.
| if (userInfoBase64) { | ||
| // Decode base64url user info | ||
| const json: string = atob(userInfoBase64.replace(/-/g, '+').replace(/_/g, '/')); | ||
| const userInfo: Record<string, unknown> = JSON.parse(json); | ||
| this.tokenStorage.saveUser(userInfo); |
There was a problem hiding this comment.
Backend encodes userInfo with Base64 URL encoding without padding (Base64.getUrlEncoder().withoutPadding()), but the frontend decodes with atob() without restoring padding. atob() can fail for unpadded base64url strings, causing OAuth2 logins to intermittently error. Add padding restoration before calling atob() (or use a dedicated base64url decode helper).
| return next.handle(authReq).pipe( | ||
| catchError((error: HttpErrorResponse) => { | ||
| // Only attempt refresh on 401 errors and if the request is not itself a refresh/auth request | ||
| if (error.status === 401 && !req.url.includes('/api/auth/')) { | ||
| return this.handle401Error(authReq, next); | ||
| } | ||
| return throwError(() => error); |
There was a problem hiding this comment.
The 401 refresh guard only excludes URLs containing /api/auth/, but the login endpoint used by AuthService is under /auth/api/ (via the gateway). A 401 from the signin call would incorrectly trigger refresh/logout logic. Exclude the gateway auth paths too (e.g., /auth/api/ and /oauth2/) or use a more explicit allow/deny list for refresh handling.
| addTestOnList(newTest: testModel2){ | ||
| newTest.id= this.listTests.length+1; | ||
| this.listTests.push(newTest); | ||
| this.testsSubject.next([...this.listTests]); | ||
|
|
||
| // Persist to backend | ||
| this.http.post<any>(this.DEFINITIONS_API, this.toBackend(newTest)).subscribe({ | ||
| next: saved => { newTest.mongoId = saved.id; }, | ||
| error: err => console.error('Failed to save definition:', err) | ||
| }); |
There was a problem hiding this comment.
addTestOnList() persists asynchronously and sets newTest.mongoId in the POST callback. If the list entry is edited/replaced (updateTest() assigns this.listTests[index] = updatedTest) before the POST returns, the mongoId will be written to the old object reference and lost, breaking subsequent PUT/DELETE persistence. Consider updating the stored list element by index/id inside the POST callback and re-emitting testsSubject once the mongoId is known (or make add return an Observable and await it).
| // Ouvre le dialogue de suppression de test | ||
| deleteTest(id: string) { | ||
| this.isPopupOpened = true; | ||
| const dialogRef = this.dialog.open(DeleteTestDialogComponent, { data: id }); | ||
| dialogRef.afterClosed().subscribe(result => { | ||
| dialogRef.afterClosed().subscribe(() => { | ||
| this.isPopupOpened = false; | ||
| this.ngOnInit(); | ||
| }); | ||
| this.getTestList(); | ||
| } |
There was a problem hiding this comment.
deleteTest is typed as (id: string) but testModel2.id is a number and the template calls deleteTest(row.id). With Angular template type-checking enabled this becomes a compile-time error; change the parameter type to number (or coerce explicitly) to match the model.
| @GetMapping("/slow") | ||
| public ResponseEntity<Map<String, Object>> slow( | ||
| @RequestParam(value = "delay", defaultValue = "15000") int delay) { | ||
| long start = System.currentTimeMillis(); | ||
| try { | ||
| Thread.sleep(delay); | ||
| } catch (InterruptedException e) { | ||
| Thread.currentThread().interrupt(); | ||
| } |
There was a problem hiding this comment.
/slow accepts an unbounded delay and passes it directly to Thread.sleep(delay). Negative values throw IllegalArgumentException (500), and very large values can tie up request threads (easy DoS). Validate/clamp delay (e.g., delay >= 0 and a reasonable max) and return 400 Bad Request for invalid inputs.
| export const environment = { | ||
| production: true, | ||
| apiUrl: '/my-backend' | ||
| apiUrl: '/my-backend', | ||
| oauth2BackendUrl: 'http://localhost:8084' | ||
| }; |
There was a problem hiding this comment.
environment.prod.ts sets oauth2BackendUrl to http://localhost:8084, which will break Google login/refresh-token calls in a real production deployment and may accidentally send users to a local machine. Use a relative URL (same origin) or a production-specific value injected at build/deploy time.
…tException - Reject delay < 0 or delay > 120000 ms with 400 Bad Request - Prevents thread exhaustion from unbounded sleep values - Addresses Copilot code review on PR #56
- UserService: remove dead null-check after orElseThrow() - gherkin-parser: use != null instead of truthy for empty string preservation - oauth2-callback: restore base64url padding before atob() decode - auth.interceptor: also exclude /auth/api/ and /oauth2/ from 401 refresh - test-api.service: fix mongoId race condition in addTestOnList POST callback - test-api.component: fix deleteTest parameter type string -> number
Équipe 3 – Phase 2: Timeout, Response Time Validation & Gherkin Editor Fixes
Summary
This PR delivers the Phase 2 milestone for Équipe 3 – Gestion du Timeout, validation du temps de réponse, corrections de l'éditeur Gherkin et optimisation Docker. The objective was to implement end-to-end timeout handling for API tests, activate response time validation (previously disabled), fix editor display bugs, and optimize the Docker build pipeline.
When we started this work, the testapi microservice had no timeout configuration – Rest-Assured requests to target APIs could hang indefinitely with no error message. The backend proxy silently dropped the
responseTimeandexpectedHeadersfields during JSON deserialization, so response time validation never triggered (testapi always receivedresponseTime=0). The Gherkin editor had a cursor misalignment bug on the last line, and the Docker build context was 1.2 GB due to a missing.dockerignore.After our changes, the system handles timeouts at two levels (backend→estapi proxy: 30s, testapi→arget API: 10s) with explicit error messages instead of crashes, response time validation works end-to-end, the Gherkin editor cursor is fixed, the Docker image context is down to 50 MB, and backend test coverage reaches 98% line coverage (433/438) across 24 team-owned classes with 87 tests, 0 failures.
Problems Found & Changes Made
1. No timeout on testapi microservice – RestAssured hangs indefinitely
Problem: When the target API being tested was slow or unreachable, the testapi microservice's Rest-Assured requests would block indefinitely. There was no connection timeout, socket timeout, or connection manager timeout configured. Users would see an infinite spinner with no feedback.
Changes (Testapi –
TimeoutConfig.java):TimeoutConfig(org.config.TimeoutConfig) – Spring@Configurationclass that configures Rest-Assured timeouts on@PostConstruct:http.connection.timeout= 10 000 ms (default, configurable viatimeout.connection)http.socket.timeout= 10 000 ms (default, configurable viatimeout.socket)http.connection-manager.timeout= 10 000 ms (default, configurable viatimeout.connectionManager)TestManager.java– addedscanBasePackages = {"org.requests", "org.config"}to@SpringBootApplicationso Spring discoversTimeoutConfigat startupChanges (Testapi –
RequestController.java):try/catchforSocketTimeoutException– returns JSON error message"❌Temps de réponse dépassé.."instead of crashingSystem.currentTimeMillis()around the Rest-Assured call and stored inAnswer.actualResponseTime2.
/slowtest endpoint – missing for timeout verificationProblem: There was no way to test timeout behavior without relying on an external slow API. Developers needed a controllable endpoint to verify timeout handling.
Changes (Testapi –
TestApiController.java):GET /microservice/testapi/slow?delay=N– sleeps fordelayms (default 15 000) and returns elapsed time,Thread.currentThread().isInterrupted()status, and timestamp@RequestParamwithdefaultValuefor safe invocation3. Backend proxy drops
responseTimeandexpectedHeaders– response time validation never triggersProblem: The backend proxy's
TestApiRequestDTO was missing theresponseTime(int) andexpectedHeaders(Map<String,String>) fields. When the frontend sent a test request withresponseTime: 1000, Jackson silently dropped the unknown field during deserialization. The testapi microservice receivedresponseTime=0, andcheckResponseTime()returnedtrue(skip check when 0). Users could set any response time threshold and it would always pass.Changes (Backend –
TestApiRequest.java):private int responseTimefield with getter/setterprivate Map<String, String> expectedHeadersfield with getter/setterChanges (Backend –
application.yml):taf.app.testAPI_timeout: 30000– configurable timeout for the HttpClient proxy call to testapiChanges (Backend –
TestApiController.java):@Value("${taf.app.testAPI_timeout:30000}") int testApiTimeoutHttpClientnow usesconnectTimeout(Duration.ofMillis(testApiTimeout))andtimeout(Duration.ofMillis(testApiTimeout))on the request4. Gherkin editor cursor misalignment on last line
Problem: When clicking on the last line of the Gherkin editor, the cursor display became chaotic – text appeared misaligned between the textarea and the highlight overlay. Root cause: the
<pre>element withwhite-space: pre-wrapcollapses trailing newlines, making the highlight layer one line shorter than the textarea. Additionally,overflow: hiddenon the highlight layer prevented scroll synchronization.Changes (Frontend –
gherkin-editor.component.ts):getHighlightedHtml()now appends'\n'to the output, preventing<pre>from collapsing the last line'\n'instead of empty string when text is emptyhighlightedHtml: stringcached field – HTML is recomputed only ononTextChange()instead of every Angular change detection cycleChanges (Frontend –
gherkin-editor.component.html):[innerHTML]="getHighlightedHtml()"to[innerHTML]="highlightedHtml"(performance: avoids method call on every CD cycle)Changes (Frontend –
gherkin-editor.component.css):.highlight-layerfromoverflow: hiddentooverflow: auto– both layers now have matching scroll behavior5. Gherkin parser rejects empty body in
And the input is ''Problem: The Gherkin parser regex for input and expected output used
(.+)which required at least one character. WritingAnd the input is ''(empty body) resulted in an unrecognized step instead of parsing as empty string.Changes (Frontend –
gherkin-parser.service.ts):(.+)to(.*)for both input and expectedOutput patterns''is now correctly parsed as an empty string6. Frontend: display
actualResponseTimeand split TDR columnsProblem: The testapi microservice now returns
actualResponseTimein the response, but the frontend model and display didn't include it.Changes (Frontend):
testResponseModel.ts– addedactualResponseTime: numberfieldtestmodel2.ts– addedresponseTime: numberandexpectedHeaders: Map<string, string>fieldstest-api.component.html– displays actual response time next to test resultsadd-test-dialog.component.ts– includesresponseTimeandexpectedHeadersin the form model7. Docker build context 1.2 GB – missing
.dockerignoreProblem: The Docker build context for
testapi-Servicewas 1.2 GB because there was no.dockerignorefile. Everydocker compose buildsent the entire workspace (includingnode_modules,target/,.git/) to the Docker daemon.Changes (
testapi-Service/.dockerignore):**/target/,**/node_modules/,**/.git/,**/dist/, build output, IDE files8. Frontend persistence: HTTP-backed test definitions
Problem: The frontend
TestApiServicestored test definitions only in memory (BehaviorSubject). The MongoDB persistence layer was added in feature/MongoDB, but the service needed updated methods for the new persistence fields.Changes (Frontend –
test-api.service.ts):loadDefinitions(),addDefinition(),updateDefinition(),deleteDefinition()to call backend REST APIHttpTestingController-based tests for all HTTP operationsChanges (Frontend –
test-api.service.spec.ts):HttpTestingControllerTesting & Validation
Backend Test Results
Frontend Test Results
JaCoCo Coverage Summary (Team Classes)
AuthControllerTestApiControllerApiTestDefinitionControllerOAuth2ControllerWebSecurityConfigJwtUtilsAuthTokenFilterAuthEntryPointJwtOAuth2LoginSuccessHandlerUserDetailsImplUserDetailsServiceImplMvcConfigurationUserRoleERole(enum)ApiTestDefinitionJwtResponseMessageResponseSignupRequestLoginRequestRefreshTokenRequestTestApiRequestTestAutomationFrameworkApplicationMvcConfiguration (inner PathResourceResolver)Timeout Validation (Docker Integration)
GET https://jsonplaceholder.typicode.com/posts/1/slowendpointGET /slow?delay=1000Gherkin Editor Validation
And the input is ''highlightedHtml)Pre-push Hook
System Health
Files Modified
New Files
testapi/src/main/java/org/config/TimeoutConfig.javaModified Files (Backend)
backend/src/main/java/.../controller/TestApiController.javatestApiTimeout@value, HttpClient connectTimeout + request timeoutbackend/src/main/java/.../payload/request/TestApiRequest.javaresponseTime(int) andexpectedHeaders(Map) fieldsbackend/src/main/resources/application.ymltaf.app.testAPI_timeout: 30000backend/src/test/.../controller/TestApiControllerTest.javaModified Files (Testapi Microservice)
testapi/src/main/java/org/requests/TestApiController.java/slow?delay=Nendpoint with delay validation (0–2000 ms, 400 on invalid)testapi/src/main/java/org/requests/RequestController.javatestapi/src/main/java/org/requests/TestManager.javascanBasePackages = {"org.requests", "org.config"}testapi/src/main/java/org/requests/payload/request/Answer.javaactualResponseTimefieldtestapi/src/main/resources/application.ymlModified Files (Frontend – Feature)
frontend/src/app/_services/gherkin-parser.service.ts.+–.*for empty body supportfrontend/src/app/_services/test-api.service.tsfrontend/src/app/_services/test-api.service.spec.tsfrontend/src/app/app.module.tsfrontend/src/app/interface-test-api/gherkin-editor/gherkin-editor.component.tshighlightedHtml, trailing\nfixfrontend/src/app/interface-test-api/gherkin-editor/gherkin-editor.component.html[innerHTML]bound to cached fieldfrontend/src/app/interface-test-api/gherkin-editor/gherkin-editor.component.cssoverflow: hidden–overflow: autofrontend/src/app/interface-test-api/gherkin-editor/gherkin-editor.component.spec.tsfrontend/src/app/interface-test-api/test-api/test-api.component.tsfrontend/src/app/interface-test-api/test-api/test-api.component.htmlactualResponseTimein resultsfrontend/src/app/interface-test-api/test-api/test-api.component.spec.tsfrontend/src/app/interface-test-api/test-api/add-test-dialog/add-test-dialog.component.tsfrontend/src/app/models/testResponseModel.tsactualResponseTimefieldfrontend/src/app/models/testmodel2.tsresponseTime,expectedHeadersfieldsModified Files (Infrastructure)
.dockerignoreModified Files (Code Review Fixes –commits 3–)
frontend/src/app/interface-test-api/test-api/add-test-dialog/add-test-dialog.component.tsuser/src/main/java/.../services/UserService.javaorElseThrow()frontend/src/app/_services/gherkin-parser.service.tstoGherkin(): use!= nullinstead of truthy to preserve empty stringsfrontend/src/app/oauth2-callback/oauth2-callback.component.tsatob()decodefrontend/src/app/_helpers/auth.interceptor.ts/auth/api/and/oauth2/paths from 401 refresh guardfrontend/src/app/_services/test-api.service.tsaddTestOnList()POST callbackfrontend/src/app/interface-test-api/test-api/test-api.component.tsdeleteTestparameter typestring→numberModified Files (TDR Column Split – commit 6)
frontend/.../test-api.component.htmlfrontend/.../test-api.component.tsactualResponseTimetodisplayedColumnsfrontend/.../add-test-dialog.component.htmlREADME.mdModified Files (Documentation)
README.mdTEST-REPORT.mdCommit History
91dc856feat: add timeout handling, response time validation, and Gherkin editor fixes– 27 filesbe5163etest: cover TestApiRequest responseTime/expectedHeaders getters (98% line coverage)–3 files20b2bb3fix: prevent ReDoS in URL validation regex (CodeQL high severity)–1 file8c4c2abfix: validate /slow delay parameter to prevent DoS and IllegalArgumentException–1 filed394a12fix: address 6 Copilot code review findings on PR #56–6 files15642a4feat: split TDR column into expected/actual and rename form label–4 filesArchitecture Notes
Timeout Flow
Configuration Hierarchy