From c6a90c3acdf4ed10caa2a970b0457a79c9e7df72 Mon Sep 17 00:00:00 2001 From: Roman Iuvshyn Date: Fri, 15 Dec 2017 14:43:46 +0200 Subject: [PATCH 01/30] RELEASE: Update CHANGELOG (#7896) --- CHANGELOG.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a20100f02a35..93bd30946a9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,53 @@ # Change Log +## [6.0.0-M3](https://github.com/eclipse/che/tree/6.0.0-M3) (2017-12-14) +[Full Changelog](https://github.com/eclipse/che/compare/5.22.0...6.0.0-M3) + +**Merged pull requests:** + +- Selenium: apply changes for selenium tests from Che6 branch to master [\#7870](https://github.com/eclipse/che/pull/7870) ([SkorikSergey](https://github.com/SkorikSergey)) +- CHE-7407: Remove redundant file watcher initialization [\#7867](https://github.com/eclipse/che/pull/7867) ([vinokurig](https://github.com/vinokurig)) + +## [5.22.0](https://github.com/eclipse/che/tree/5.22.0) (2017-12-13) +[Full Changelog](https://github.com/eclipse/che/compare/5.21.1...5.22.0) + +**Merged pull requests:** + +- RELEASE: Set next development version [\#7848](https://github.com/eclipse/che/pull/7848) ([riuvshin](https://github.com/riuvshin)) +- Adapt webdriver.sh to Multiuser Che; add ability to set rerun attempts [\#7847](https://github.com/eclipse/che/pull/7847) ([dmytro-ndp](https://github.com/dmytro-ndp)) +- Revert "Selenium: apply changes for selenium tests from Che6 branch to master" [\#7843](https://github.com/eclipse/che/pull/7843) ([SkorikSergey](https://github.com/SkorikSergey)) +- Selenium: apply changes for selenium tests from Che6 branch to master [\#7830](https://github.com/eclipse/che/pull/7830) ([SkorikSergey](https://github.com/SkorikSergey)) +- Fix the OpenshiftClient connection leaks [\#7793](https://github.com/eclipse/che/pull/7793) ([davidfestal](https://github.com/davidfestal)) +- Introduce wsagent ping success threshold [\#7766](https://github.com/eclipse/che/pull/7766) ([l0rd](https://github.com/l0rd)) +- Give focus for widget when activate this one [\#7760](https://github.com/eclipse/che/pull/7760) ([RomanNikitenko](https://github.com/RomanNikitenko)) +- Rework selenium page objects for Dashboard [\#7757](https://github.com/eclipse/che/pull/7757) ([SkorikSergey](https://github.com/SkorikSergey)) +- Remove separation of selenium tests on stable/unstable/failed [\#7749](https://github.com/eclipse/che/pull/7749) ([dmytro-ndp](https://github.com/dmytro-ndp)) +- Move clean up to the end of selenium test execution [\#7731](https://github.com/eclipse/che/pull/7731) ([dmytro-ndp](https://github.com/dmytro-ndp)) +- Set screen size in the selenium chrome node to 1920x1080 [\#7717](https://github.com/eclipse/che/pull/7717) ([dmytro-ndp](https://github.com/dmytro-ndp)) +- Test commands starting from the Processes area [\#7690](https://github.com/eclipse/che/pull/7690) ([SkorikSergey](https://github.com/SkorikSergey)) +- Fixed location of centos blank stack which was previously invalid [\#7666](https://github.com/eclipse/che/pull/7666) ([JPinkney](https://github.com/JPinkney)) +- Add ability to wait until selenium web element animation is ended [\#7659](https://github.com/eclipse/che/pull/7659) ([dmytro-ndp](https://github.com/dmytro-ndp)) +- Fix for part of redhat-developer/rh-che\#431 [\#7639](https://github.com/eclipse/che/pull/7639) ([JPinkney](https://github.com/JPinkney)) +- Selenium: Add changes to the 'RenamePackageTest' [\#7628](https://github.com/eclipse/che/pull/7628) ([artaleks9](https://github.com/artaleks9)) +- CHE-7407: Rework Git file change event detection to be depend on open… [\#7613](https://github.com/eclipse/che/pull/7613) ([vinokurig](https://github.com/vinokurig)) +- Fix small UI bugs [\#7608](https://github.com/eclipse/che/pull/7608) ([olexii4](https://github.com/olexii4)) +- RELEASE: Update CHANGELOG [\#7570](https://github.com/eclipse/che/pull/7570) ([riuvshin](https://github.com/riuvshin)) +- Change testing of the Find Text feature presentation [\#7568](https://github.com/eclipse/che/pull/7568) ([SkorikSergey](https://github.com/SkorikSergey)) +- Port from che6 Added missing lib to be able to configure LogstashEncoder on wsagent [\#7566](https://github.com/eclipse/che/pull/7566) ([skabashnyuk](https://github.com/skabashnyuk)) +- Add machine token for 'Upload SSH key' request [\#7540](https://github.com/eclipse/che/pull/7540) ([RomanNikitenko](https://github.com/RomanNikitenko)) +- RELEASE: Set next development version [\#7503](https://github.com/eclipse/che/pull/7503) ([riuvshin](https://github.com/riuvshin)) +- Add the ability to configure logback \(MDC\) to show `identity\_id` and `X-Request-ID` in logs files when available. [\#7461](https://github.com/eclipse/che/pull/7461) ([sunix](https://github.com/sunix)) +- Prevent NPE after applying the refactoring session [\#7458](https://github.com/eclipse/che/pull/7458) ([vzhukovskii](https://github.com/vzhukovskii)) +- Include Organization tests into acceptance tests execution on the Multiuser Che [\#7447](https://github.com/eclipse/che/pull/7447) ([dmytro-ndp](https://github.com/dmytro-ndp)) +- Do not index files from File Index excludes [\#7096](https://github.com/eclipse/che/pull/7096) ([RomanNikitenko](https://github.com/RomanNikitenko)) + +## [5.21.1](https://github.com/eclipse/che/tree/5.21.1) (2017-12-07) +[Full Changelog](https://github.com/eclipse/che/compare/6.0.0-M2...5.21.1) + +## [6.0.0-M2](https://github.com/eclipse/che/tree/6.0.0-M2) (2017-11-23) +[Full Changelog](https://github.com/eclipse/che/compare/5.21.0...6.0.0-M2) + + ## [6.0.0-M2](https://github.com/eclipse/che/tree/6.0.0-M2) (2017-11-23) [Full Changelog](https://github.com/eclipse/che/compare/5.21.0...6.0.0-M2) From 9c52742f71faf246a83cfa229b60f8c8c993b03e Mon Sep 17 00:00:00 2001 From: Ilya Buziuk Date: Fri, 15 Dec 2017 10:54:44 +0100 Subject: [PATCH 02/30] Support of headers to 'HttpJsonRequest'. Adding 'Connection: close' header while pinging workspace agent Signed-off-by: Ilya Buziuk --- .../api/core/rest/DefaultHttpJsonRequest.java | 26 ++++++++++++++-- .../che/api/core/rest/HttpJsonRequest.java | 22 +++++++++++++ .../core/rest/DefaultHttpJsonRequestTest.java | 31 ++++++++++++++++--- .../server/WsAgentPingRequestFactory.java | 6 +++- .../server/WsAgentPingRequestFactoryTest.java | 7 +++++ 5 files changed, 83 insertions(+), 9 deletions(-) diff --git a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequest.java b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequest.java index 6a633699668b..0ace844a8b64 100644 --- a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequest.java +++ b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequest.java @@ -68,6 +68,7 @@ public class DefaultHttpJsonRequest implements HttpJsonRequest { private String method; private Object body; private List> queryParams; + private List> headers; private String authorizationHeaderValue; protected DefaultHttpJsonRequest(String url, String method) { @@ -118,6 +119,16 @@ public HttpJsonRequest addQueryParam(@NotNull String name, @NotNull Object value return this; } + public HttpJsonRequest addHeader(@NotNull String name, @NotNull String value) { + requireNonNull(name, "Required non-null header name"); + requireNonNull(value, "Required non-null header value"); + if (headers == null) { + headers = new ArrayList<>(); + } + headers.add(Pair.of(name, value)); + return this; + } + @Override public HttpJsonRequest setAuthorizationHeader(@NotNull String value) { requireNonNull(value, "Required non-null header value"); @@ -149,7 +160,7 @@ public HttpJsonResponse request() if (method == null) { throw new IllegalStateException("Could not perform request, request method wasn't set"); } - return doRequest(timeout, url, method, body, queryParams, authorizationHeaderValue); + return doRequest(timeout, url, method, body, queryParams, authorizationHeaderValue, headers); } /** @@ -182,7 +193,8 @@ protected DefaultHttpJsonResponse doRequest( String method, Object body, List> parameters, - String authorizationHeaderValue) + String authorizationHeaderValue, + List> headers) throws IOException, ServerException, ForbiddenException, NotFoundException, UnauthorizedException, ConflictException, BadRequestException { final String authToken = EnvironmentContext.getCurrent().getSubject().getToken(); @@ -202,6 +214,15 @@ protected DefaultHttpJsonResponse doRequest( final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); conn.setConnectTimeout(timeout > 0 ? timeout : 60000); conn.setReadTimeout(timeout > 0 ? timeout : 60000); + + final boolean hasHeaders = headers != null && !headers.isEmpty(); + + if (hasHeaders) { + for (Pair header : headers) { + conn.setRequestProperty(header.first, header.second); + } + } + try { conn.setRequestMethod(method); // drop a hint for server side that we want to receive application/json @@ -225,7 +246,6 @@ protected DefaultHttpJsonResponse doRequest( output.write(DtoFactory.getInstance().toJson(body).getBytes()); } } - final int responseCode = conn.getResponseCode(); if ((responseCode / 100) != 2) { InputStream in = conn.getErrorStream(); diff --git a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/HttpJsonRequest.java b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/HttpJsonRequest.java index 34af8b266287..ec8d3194d596 100644 --- a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/HttpJsonRequest.java +++ b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/HttpJsonRequest.java @@ -110,6 +110,16 @@ public interface HttpJsonRequest { */ HttpJsonRequest addQueryParam(@NotNull String name, @NotNull Object value); + /** + * Adds header to the request. + * + * @param name header name + * @param value header value + * @return this request instance + * @throws NullPointerException when either header name or value is null + */ + HttpJsonRequest addHeader(@NotNull String name, @NotNull String value); + /** * Adds authorization header to the request. * @@ -206,4 +216,16 @@ default HttpJsonRequest addQueryParams(@NotNull Map params) { params.forEach(this::addQueryParam); return this; } + + /** + * Adds set of headers to this request. + * + * @param headers map with headers + * @return this request instance + */ + default HttpJsonRequest addHeaders(@NotNull Map headers) { + Objects.requireNonNull(headers, "Required non-null headers"); + headers.forEach(this::addHeader); + return this; + } } diff --git a/core/che-core-api-core/src/test/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequestTest.java b/core/che-core-api-core/src/test/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequestTest.java index ca877bfd54f4..cac0f46ac318 100644 --- a/core/che-core-api-core/src/test/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequestTest.java +++ b/core/che-core-api-core/src/test/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequestTest.java @@ -103,10 +103,11 @@ public void shouldUseUrlAndMethodFromTheLinks() throws Exception { anyString(), nullable(Object.class), nullable(List.class), - nullable(String.class)); + nullable(String.class), + nullable(List.class)); request.request(); - verify(request).doRequest(0, DEFAULT_URL, "POST", null, null, null); + verify(request).doRequest(0, DEFAULT_URL, "POST", null, null, null, null); } @Test @@ -119,6 +120,7 @@ public void shouldBeAbleToMakeRequest() throws Exception { .setTimeout(10_000_000) .addQueryParam("name", "value") .addQueryParam("name2", "value2") + .addHeader("Connection", "close") .request(); verify(request) @@ -128,7 +130,8 @@ public void shouldBeAbleToMakeRequest() throws Exception { "PUT", body, asList(Pair.of("name", "value"), Pair.of("name2", "value2")), - null); + null, + asList(Pair.of("Connection", "close"))); } @Test @@ -146,6 +149,7 @@ public void shouldBeAbleToUseStringMapAsRequestBody() throws Exception { eq("POST"), mapCaptor.capture(), eq(null), + eq(null), eq(null)); assertTrue(mapCaptor.getValue() instanceof JsonStringMap); assertEquals(mapCaptor.getValue(), body); @@ -164,6 +168,7 @@ public void shouldBeAbleToUseListOfJsonSerializableElementsAsRequestBody() throw eq("POST"), listCaptor.capture(), eq(null), + eq(null), eq(null)); assertTrue(listCaptor.getValue() instanceof JsonArray); assertEquals(listCaptor.getValue(), body); @@ -172,7 +177,7 @@ public void shouldBeAbleToUseListOfJsonSerializableElementsAsRequestBody() throw @Test public void defaultMethodIsGet() throws Exception { request.request(); - verify(request).doRequest(0, DEFAULT_URL, HttpMethod.GET, null, null, null); + verify(request).doRequest(0, DEFAULT_URL, HttpMethod.GET, null, null, null, null); } @Test(expectedExceptions = NullPointerException.class) @@ -216,6 +221,21 @@ public void shouldThrowNullPointerExceptionWhenQueryParamsAreNull() throws Excep new DefaultHttpJsonRequest("http://localhost:8080").addQueryParams(null); } + @Test(expectedExceptions = NullPointerException.class) + public void shouldThrowNullPointerExceptionWhenHeaderNameIsNull() throws Exception { + new DefaultHttpJsonRequest("http://localhost:8080").addHeader(null, "close"); + } + + @Test(expectedExceptions = NullPointerException.class) + public void shouldThrowNullPointerExceptionWhenHeaderValueIsNull() throws Exception { + new DefaultHttpJsonRequest("http://localhost:8080").addHeader("Connection", null); + } + + @Test(expectedExceptions = NullPointerException.class) + public void shouldThrowNullPointerExceptionWhenHeadersAreNull() throws Exception { + new DefaultHttpJsonRequest("http://localhost:8080").addHeaders(null); + } + @Test(expectedExceptions = NullPointerException.class) public void shouldThrowNullPointerExceptionWhenLinkHrefIsNull() throws Exception { new DefaultHttpJsonRequest(createLink("GET", null, null)); @@ -375,6 +395,7 @@ private void prepareResponse(String response) throws Exception { anyString(), nullable(Object.class), nullable(List.class), - nullable(String.class)); + nullable(String.class), + nullable(List.class)); } } diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/agent/server/WsAgentPingRequestFactory.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/agent/server/WsAgentPingRequestFactory.java index 6032f1a66fbe..afdec7e0f022 100644 --- a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/agent/server/WsAgentPingRequestFactory.java +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/agent/server/WsAgentPingRequestFactory.java @@ -39,6 +39,8 @@ public class WsAgentPingRequestFactory { "Workspace agent server not found in dev machine."; private static final String WS_AGENT_URL_IS_NULL_OR_EMPTY_ERROR = "URL of Workspace Agent is null or empty."; + private static final String CONNECTION_HEADER = "Connection"; + private static final String CONNECTION_CLOSE = "close"; private final HttpJsonRequestFactory httpJsonRequestFactory; private final int wsAgentPingConnectionTimeoutMs; @@ -80,9 +82,11 @@ public HttpJsonRequest createRequest(Machine machine) throws ServerException { if (!wsAgentPingUrl.endsWith("/")) { wsAgentPingUrl = wsAgentPingUrl.concat("/"); } + return httpJsonRequestFactory .fromUrl(wsAgentPingUrl) .setMethod(HttpMethod.GET) - .setTimeout(wsAgentPingConnectionTimeoutMs); + .setTimeout(wsAgentPingConnectionTimeoutMs) + .addHeader(CONNECTION_HEADER, CONNECTION_CLOSE); } } diff --git a/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/agent/server/WsAgentPingRequestFactoryTest.java b/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/agent/server/WsAgentPingRequestFactoryTest.java index 61ec61e3bb10..df403da4f0a7 100644 --- a/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/agent/server/WsAgentPingRequestFactoryTest.java +++ b/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/agent/server/WsAgentPingRequestFactoryTest.java @@ -40,6 +40,8 @@ public class WsAgentPingRequestFactoryTest { private static final String WS_AGENT_SERVER_NOT_FOUND_ERROR = "Workspace agent server not found in dev machine."; private static final String WS_AGENT_SERVER_URL = "ws_agent"; + private static final String CONNECTION_HEADER = "Connection"; + private static final String CONNECTION_CLOSE = "close"; @Mock private HttpJsonRequestFactory httpJsonRequestFactory; @Mock private HttpJsonRequest httpJsonRequest; @@ -62,6 +64,10 @@ public void setUp() throws Exception { when(httpJsonRequestFactory.fromUrl(anyString())).thenReturn(httpJsonRequest); when(httpJsonRequest.setMethod(HttpMethod.GET)).thenReturn(httpJsonRequest); + when(httpJsonRequest.setTimeout(WS_AGENT_PING_CONNECTION_TIMEOUT_MS)) + .thenReturn(httpJsonRequest); + when(httpJsonRequest.addHeader(CONNECTION_HEADER, CONNECTION_CLOSE)) + .thenReturn(httpJsonRequest); when(server.getProperties()).thenReturn(serverProperties); when(serverProperties.getInternalUrl()).thenReturn(WS_AGENT_SERVER_URL); when(devMachine.getRuntime()).thenReturn(machineRuntimeInfo); @@ -105,5 +111,6 @@ public void pingRequestShouldBeCreated() throws Exception { verify(httpJsonRequestFactory).fromUrl(WS_AGENT_SERVER_URL + '/'); verify(httpJsonRequest).setMethod(javax.ws.rs.HttpMethod.GET); verify(httpJsonRequest).setTimeout(WS_AGENT_PING_CONNECTION_TIMEOUT_MS); + verify(httpJsonRequest).addHeader(CONNECTION_HEADER, CONNECTION_CLOSE); } } From e5f92ca9cfea1476d267fe1ac41acb0e8f1f145d Mon Sep 17 00:00:00 2001 From: Aleksandr Shmaraiev Date: Mon, 18 Dec 2017 18:20:20 +0200 Subject: [PATCH 03/30] Change expected text in the 'AutocompleteProposalJavaDocTest' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Изменить ожидаемый текст контекстного меню JavaDoc в «AutocompleteProposalJavaDocTest», связанный с запуском теста на che6-ocp --- .../editor/autocomplete/AutocompleteProposalJavaDocTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/editor/autocomplete/AutocompleteProposalJavaDocTest.java b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/editor/autocomplete/AutocompleteProposalJavaDocTest.java index 5e7d3cc99176..c3f65f8c7151 100644 --- a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/editor/autocomplete/AutocompleteProposalJavaDocTest.java +++ b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/editor/autocomplete/AutocompleteProposalJavaDocTest.java @@ -169,7 +169,7 @@ public void shouldDisplayJavaDocOfJreClass() throws IOException { editor.waitContextMenuJavaDocText( ".*Returns a hash code value for the object. " + "This method is supported for the benefit of hash tables such as those provided by " - + "java.util.HashMap.*"); + + "java.util.HashMap.*"); } @Test From ecd7c89ec07826764eb97598a1f735d2f2ca6d72 Mon Sep 17 00:00:00 2001 From: Artem Zatsarynnyi Date: Tue, 19 Dec 2017 08:48:32 +0200 Subject: [PATCH 04/30] Remove Testing API (server artifact) from the Basic IDE (#7936) Signed-off-by: Artem Zatsarynnyi --- ide/che-ide-core/pom.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ide/che-ide-core/pom.xml b/ide/che-ide-core/pom.xml index afd6667fe1c8..03b0b216fd66 100644 --- a/ide/che-ide-core/pom.xml +++ b/ide/che-ide-core/pom.xml @@ -60,10 +60,6 @@ javax.inject javax.inject - - org.eclipse.che.core - che-core-api-testing - org.eclipse.che.core che-core-commons-gwt From 10d70ca9cc53f776cc622380514ccfa6ed28b7cb Mon Sep 17 00:00:00 2001 From: Oleksandr Garagatyi Date: Mon, 18 Dec 2017 12:07:25 +0200 Subject: [PATCH 05/30] CHE-7834: add field 'status' into runtime machine object Signed-off-by: Oleksandr Garagatyi --- .../core/model/workspace/runtime/Machine.java | 2 + .../workspace/runtime/MachineStatus.java | 2 +- .../ide/api/workspace/model/MachineImpl.java | 45 +++++++++++++++---- .../ide/api/workspace/model/RuntimeImpl.java | 6 +-- .../docker/DockerInternalRuntime.java | 2 + .../infrastructure/docker/DockerMachine.java | 13 ++++++ .../openshift/OpenShiftInternalRuntime.java | 3 +- .../openshift/OpenShiftMachine.java | 15 ++++++- .../GdbConfigurationPagePresenter.java | 1 + .../api/workspace/shared/dto/MachineDto.java | 6 +++ .../api/workspace/server/DtoConverter.java | 5 ++- .../server/model/impl/MachineImpl.java | 35 ++++++++++++--- .../workspace/server/spi/InternalRuntime.java | 3 +- .../server/WorkspaceManagerTest.java | 3 +- .../server/WorkspaceServiceTest.java | 16 ++++--- .../server/spi/InternalRuntimeTest.java | 15 ++++--- 16 files changed, 135 insertions(+), 37 deletions(-) diff --git a/core/che-core-api-model/src/main/java/org/eclipse/che/api/core/model/workspace/runtime/Machine.java b/core/che-core-api-model/src/main/java/org/eclipse/che/api/core/model/workspace/runtime/Machine.java index 5f85a66b4afd..c0e884d3ac21 100644 --- a/core/che-core-api-model/src/main/java/org/eclipse/che/api/core/model/workspace/runtime/Machine.java +++ b/core/che-core-api-model/src/main/java/org/eclipse/che/api/core/model/workspace/runtime/Machine.java @@ -37,4 +37,6 @@ public interface Machine { * */ Map getServers(); + + MachineStatus getStatus(); } diff --git a/core/che-core-api-model/src/main/java/org/eclipse/che/api/core/model/workspace/runtime/MachineStatus.java b/core/che-core-api-model/src/main/java/org/eclipse/che/api/core/model/workspace/runtime/MachineStatus.java index a67f30d1b3ed..6d4174a14ce8 100644 --- a/core/che-core-api-model/src/main/java/org/eclipse/che/api/core/model/workspace/runtime/MachineStatus.java +++ b/core/che-core-api-model/src/main/java/org/eclipse/che/api/core/model/workspace/runtime/MachineStatus.java @@ -26,5 +26,5 @@ public enum MachineStatus { STOPPED, /** Machine failed */ - FAILED; + FAILED } diff --git a/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/workspace/model/MachineImpl.java b/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/workspace/model/MachineImpl.java index 8bd0bc03754d..2f98f38e5d3b 100644 --- a/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/workspace/model/MachineImpl.java +++ b/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/workspace/model/MachineImpl.java @@ -15,6 +15,7 @@ import java.util.Objects; import java.util.Optional; import org.eclipse.che.api.core.model.workspace.runtime.Machine; +import org.eclipse.che.api.core.model.workspace.runtime.MachineStatus; import org.eclipse.che.api.core.model.workspace.runtime.Server; /** Data object for {@link Machine}. */ @@ -23,11 +24,16 @@ public class MachineImpl implements Machine { private String name; private Map attributes; private Map servers; + private MachineStatus status; public MachineImpl( - String name, Map attributes, Map servers) { + String name, + Map attributes, + Map servers, + MachineStatus status) { this.name = name; this.attributes = new HashMap<>(attributes); + this.status = status; if (servers != null) { this.servers = servers @@ -42,7 +48,7 @@ public MachineImpl( } public MachineImpl(String name, Machine machine) { - this(name, machine.getAttributes(), machine.getServers()); + this(name, machine.getAttributes(), machine.getServers(), machine.getStatus()); } public String getName() { @@ -65,26 +71,47 @@ public Map getServers() { return servers; } + @Override + public MachineStatus getStatus() { + return status; + } + public Optional getServerByName(String name) { return Optional.ofNullable(getServers().get(name)); } @Override public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof MachineImpl)) return false; - MachineImpl that = (MachineImpl) o; - return Objects.equals(getAttributes(), that.getAttributes()) - && Objects.equals(getServers(), that.getServers()); + if (this == o) { + return true; + } + if (!(o instanceof MachineImpl)) { + return false; + } + MachineImpl machine = (MachineImpl) o; + return Objects.equals(getName(), machine.getName()) + && Objects.equals(getAttributes(), machine.getAttributes()) + && Objects.equals(getServers(), machine.getServers()) + && getStatus() == machine.getStatus(); } @Override public int hashCode() { - return Objects.hash(getAttributes(), getServers()); + return Objects.hash(getName(), getAttributes(), getServers(), getStatus()); } @Override public String toString() { - return "MachineImpl{" + "attributes=" + attributes + ", servers=" + servers + '}'; + return "MachineImpl{" + + "name='" + + name + + '\'' + + ", attributes=" + + attributes + + ", servers=" + + servers + + ", status=" + + status + + '}'; } } diff --git a/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/workspace/model/RuntimeImpl.java b/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/workspace/model/RuntimeImpl.java index 56676e28e533..165d69062b67 100644 --- a/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/workspace/model/RuntimeImpl.java +++ b/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/workspace/model/RuntimeImpl.java @@ -47,11 +47,7 @@ public RuntimeImpl( .collect( toMap( Map.Entry::getKey, - entry -> - new MachineImpl( - entry.getKey(), - entry.getValue().getAttributes(), - entry.getValue().getServers()))); + entry -> new MachineImpl(entry.getKey(), entry.getValue()))); } this.owner = owner; this.machineToken = machineToken; diff --git a/infrastructures/docker/infrastructure/src/main/java/org/eclipse/che/workspace/infrastructure/docker/DockerInternalRuntime.java b/infrastructures/docker/infrastructure/src/main/java/org/eclipse/che/workspace/infrastructure/docker/DockerInternalRuntime.java index 14f606ba1ea1..827a0b55df4a 100644 --- a/infrastructures/docker/infrastructure/src/main/java/org/eclipse/che/workspace/infrastructure/docker/DockerInternalRuntime.java +++ b/infrastructures/docker/infrastructure/src/main/java/org/eclipse/che/workspace/infrastructure/docker/DockerInternalRuntime.java @@ -277,6 +277,8 @@ private void startMachine(String name, DockerContainerConfig containerConfig) serverCheckerFactory.create(getContext().getIdentity(), name, machine.getServers()); readinessChecker.startAsync(new ServerReadinessHandler(name)); readinessChecker.await(); + + machine.setStatus(MachineStatus.RUNNING); } private void checkInterruption() throws InterruptedException { diff --git a/infrastructures/docker/infrastructure/src/main/java/org/eclipse/che/workspace/infrastructure/docker/DockerMachine.java b/infrastructures/docker/infrastructure/src/main/java/org/eclipse/che/workspace/infrastructure/docker/DockerMachine.java index 2d5dd2b1ce05..26a05bc11a42 100644 --- a/infrastructures/docker/infrastructure/src/main/java/org/eclipse/che/workspace/infrastructure/docker/DockerMachine.java +++ b/infrastructures/docker/infrastructure/src/main/java/org/eclipse/che/workspace/infrastructure/docker/DockerMachine.java @@ -17,6 +17,7 @@ import java.util.Collections; import java.util.Map; import org.eclipse.che.api.core.model.workspace.runtime.Machine; +import org.eclipse.che.api.core.model.workspace.runtime.MachineStatus; import org.eclipse.che.api.core.model.workspace.runtime.ServerStatus; import org.eclipse.che.api.workspace.server.model.impl.ServerImpl; import org.eclipse.che.api.workspace.server.spi.InfrastructureException; @@ -54,6 +55,8 @@ public class DockerMachine implements Machine { private final String registry; private final Map servers; + private MachineStatus status; + public DockerMachine( String containerId, String image, @@ -67,6 +70,7 @@ public DockerMachine( this.registry = registry; this.dockerMachineStopDetector = dockerMachineStopDetector; this.servers = servers; + this.status = MachineStatus.STARTING; } @Override @@ -79,6 +83,15 @@ public Map getServers() { return servers; } + @Override + public MachineStatus getStatus() { + return status; + } + + public void setStatus(MachineStatus status) { + this.status = status; + } + void setServerStatus(String serverRef, ServerStatus status) { if (servers == null) { throw new IllegalStateException("Servers are not initialized yet"); diff --git a/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInternalRuntime.java b/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInternalRuntime.java index cb1fbc165115..954bfbc3ba46 100644 --- a/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInternalRuntime.java +++ b/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInternalRuntime.java @@ -126,6 +126,7 @@ protected void internalStart(Map startOptions) throws Infrastruc machine.waitRunning(machineStartTimeoutMin); bootstrapMachine(machine); checkMachineServers(machine); + machine.setStatus(MachineStatus.RUNNING); sendRunningEvent(machine.getName()); } catch (InfrastructureException rethrow) { sendFailedEvent(machine.getName(), rethrow.getMessage()); @@ -245,7 +246,7 @@ public void accept(String serverRef) { return; } - machine.setStatus(serverRef, ServerStatus.RUNNING); + machine.setServerStatus(serverRef, ServerStatus.RUNNING); eventService.publish( DtoFactory.newDto(ServerStatusEvent.class) diff --git a/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftMachine.java b/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftMachine.java index 1b349c8f9f61..355a0b48b339 100644 --- a/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftMachine.java +++ b/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftMachine.java @@ -15,6 +15,7 @@ import java.util.HashMap; import java.util.Map; import org.eclipse.che.api.core.model.workspace.runtime.Machine; +import org.eclipse.che.api.core.model.workspace.runtime.MachineStatus; import org.eclipse.che.api.core.model.workspace.runtime.Server; import org.eclipse.che.api.core.model.workspace.runtime.ServerStatus; import org.eclipse.che.api.workspace.server.model.impl.ServerImpl; @@ -33,6 +34,8 @@ public class OpenShiftMachine implements Machine { private final Map ref2Server; private final OpenShiftProject project; + private MachineStatus status; + public OpenShiftMachine( String machineName, String podName, @@ -47,6 +50,7 @@ public OpenShiftMachine( this.ref2Server.putAll(ref2Server); } this.project = project; + this.status = MachineStatus.STARTING; } public String getName() { @@ -71,7 +75,16 @@ public Map getAttributes() { return ref2Server; } - void setStatus(String serverRef, ServerStatus status) { + @Override + public MachineStatus getStatus() { + return status; + } + + public void setStatus(MachineStatus status) { + this.status = status; + } + + void setServerStatus(String serverRef, ServerStatus status) { ServerImpl server = ref2Server.get(serverRef); if (server == null) { throw new IllegalArgumentException( diff --git a/plugins/plugin-gdb/che-plugin-gdb-ide/src/main/java/org/eclipse/che/plugin/gdb/ide/configuration/GdbConfigurationPagePresenter.java b/plugins/plugin-gdb/che-plugin-gdb-ide/src/main/java/org/eclipse/che/plugin/gdb/ide/configuration/GdbConfigurationPagePresenter.java index d8ee249ced90..cdc83b56b529 100644 --- a/plugins/plugin-gdb/che-plugin-gdb-ide/src/main/java/org/eclipse/che/plugin/gdb/ide/configuration/GdbConfigurationPagePresenter.java +++ b/plugins/plugin-gdb/che-plugin-gdb-ide/src/main/java/org/eclipse/che/plugin/gdb/ide/configuration/GdbConfigurationPagePresenter.java @@ -109,6 +109,7 @@ public void go(AcceptsOneWidget container) { private void setHosts(List machines) { Map hosts = new HashMap<>(); for (MachineImpl machine : machines) { + // TODO this attribute is not provided anymore String host = machine.getAttributes().get("network.ipAddress"); if (host == null) { continue; diff --git a/wsmaster/che-core-api-workspace-shared/src/main/java/org/eclipse/che/api/workspace/shared/dto/MachineDto.java b/wsmaster/che-core-api-workspace-shared/src/main/java/org/eclipse/che/api/workspace/shared/dto/MachineDto.java index f3449744d95d..b55a45ea317b 100644 --- a/wsmaster/che-core-api-workspace-shared/src/main/java/org/eclipse/che/api/workspace/shared/dto/MachineDto.java +++ b/wsmaster/che-core-api-workspace-shared/src/main/java/org/eclipse/che/api/workspace/shared/dto/MachineDto.java @@ -12,6 +12,7 @@ import java.util.Map; import org.eclipse.che.api.core.model.workspace.runtime.Machine; +import org.eclipse.che.api.core.model.workspace.runtime.MachineStatus; import org.eclipse.che.dto.shared.DTO; /** @author Alexander Garagatyi */ @@ -27,4 +28,9 @@ public interface MachineDto extends Machine { Map getServers(); MachineDto withServers(Map servers); + + @Override + MachineStatus getStatus(); + + MachineDto withStatus(MachineStatus status); } diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/DtoConverter.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/DtoConverter.java index 3eaf84d2efeb..7a71cf33f5a3 100644 --- a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/DtoConverter.java +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/DtoConverter.java @@ -279,7 +279,10 @@ public static ServerDto asDto(Server server) { /** Converts {@link Machine} to {@link MachineDto}. */ public static MachineDto asDto(Machine machine) { - MachineDto machineDto = newDto(MachineDto.class).withAttributes(machine.getAttributes()); + MachineDto machineDto = + newDto(MachineDto.class) + .withAttributes(machine.getAttributes()) + .withStatus(machine.getStatus()); if (machine.getServers() != null) { machineDto.withServers( machine diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/model/impl/MachineImpl.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/model/impl/MachineImpl.java index 2da7161b9656..355d6fad2532 100644 --- a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/model/impl/MachineImpl.java +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/model/impl/MachineImpl.java @@ -14,6 +14,7 @@ import java.util.Map; import java.util.Objects; import org.eclipse.che.api.core.model.workspace.runtime.Machine; +import org.eclipse.che.api.core.model.workspace.runtime.MachineStatus; import org.eclipse.che.api.core.model.workspace.runtime.Server; /** @@ -25,14 +26,17 @@ public class MachineImpl implements Machine { private Map attributes; private Map servers; + private MachineStatus status; public MachineImpl(Machine machineRuntime) { - this(machineRuntime.getAttributes(), machineRuntime.getServers()); + this(machineRuntime.getAttributes(), machineRuntime.getServers(), machineRuntime.getStatus()); } - public MachineImpl(Map attributes, Map servers) { + public MachineImpl( + Map attributes, Map servers, MachineStatus status) { this(servers); this.attributes = new HashMap<>(attributes); + this.status = status; } public MachineImpl(Map servers) { @@ -64,22 +68,39 @@ public Map getServers() { return servers; } + @Override + public MachineStatus getStatus() { + return status; + } + @Override public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof MachineImpl)) return false; + if (this == o) { + return true; + } + if (!(o instanceof MachineImpl)) { + return false; + } MachineImpl machine = (MachineImpl) o; return Objects.equals(getAttributes(), machine.getAttributes()) - && Objects.equals(getServers(), machine.getServers()); + && Objects.equals(getServers(), machine.getServers()) + && getStatus() == machine.getStatus(); } @Override public int hashCode() { - return Objects.hash(getAttributes(), getServers()); + return Objects.hash(getAttributes(), getServers(), getStatus()); } @Override public String toString() { - return "MachineImpl{" + "attributes=" + attributes + ", servers=" + servers + '}'; + return "MachineImpl{" + + "attributes=" + + attributes + + ", servers=" + + servers + + ", status=" + + status + + '}'; } } diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/InternalRuntime.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/InternalRuntime.java index a00354592499..ab2847dad991 100644 --- a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/InternalRuntime.java +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/spi/InternalRuntime.java @@ -79,7 +79,8 @@ public List getWarnings() { e -> new MachineImpl( e.getValue().getAttributes(), - rewriteExternalServers(e.getValue().getServers())))); + rewriteExternalServers(e.getValue().getServers()), + e.getValue().getStatus()))); } /** diff --git a/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/WorkspaceManagerTest.java b/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/WorkspaceManagerTest.java index 91098b6d8f58..f593b6701faa 100644 --- a/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/WorkspaceManagerTest.java +++ b/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/WorkspaceManagerTest.java @@ -52,6 +52,7 @@ import org.eclipse.che.api.core.model.workspace.WorkspaceConfig; import org.eclipse.che.api.core.model.workspace.WorkspaceStatus; import org.eclipse.che.api.core.model.workspace.runtime.Machine; +import org.eclipse.che.api.core.model.workspace.runtime.MachineStatus; import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity; import org.eclipse.che.api.core.notification.EventService; import org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl; @@ -571,7 +572,7 @@ private static WorkspaceConfigImpl createConfig() { } private MachineImpl createMachine() { - return new MachineImpl(emptyMap(), emptyMap()); + return new MachineImpl(emptyMap(), emptyMap(), MachineStatus.RUNNING); } private RuntimeContext mockContext(RuntimeIdentity identity) throws Exception { diff --git a/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/WorkspaceServiceTest.java b/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/WorkspaceServiceTest.java index 5f69bbd9bd97..21cf447f3333 100644 --- a/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/WorkspaceServiceTest.java +++ b/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/WorkspaceServiceTest.java @@ -19,6 +19,7 @@ import static java.util.stream.Collectors.toList; import static org.eclipse.che.api.core.model.workspace.WorkspaceStatus.STARTING; import static org.eclipse.che.api.core.model.workspace.config.MachineConfig.MEMORY_LIMIT_ATTRIBUTE; +import static org.eclipse.che.api.core.model.workspace.runtime.MachineStatus.RUNNING; import static org.eclipse.che.dto.server.DtoFactory.newDto; import static org.everrest.assured.JettyHttpServer.ADMIN_USER_NAME; import static org.everrest.assured.JettyHttpServer.ADMIN_USER_PASSWORD; @@ -329,7 +330,7 @@ public void shouldGetWorkspaceWithExternalServersByDefault() throws Exception { Map servers = ImmutableMap.of("server1", createInternalServer(), externalServerKey, externalServer); Map machines = - singletonMap("machine1", new MachineImpl(singletonMap("key", "value"), servers)); + singletonMap("machine1", new MachineImpl(singletonMap("key", "value"), servers, RUNNING)); workspace.setRuntime(new RuntimeImpl("activeEnv", machines, "user123")); when(wsManager.getWorkspace(workspace.getId())).thenReturn(workspace); Map expected = @@ -337,6 +338,7 @@ public void shouldGetWorkspaceWithExternalServersByDefault() throws Exception { "machine1", newDto(MachineDto.class) .withAttributes(singletonMap("key", "value")) + .withStatus(RUNNING) .withServers( singletonMap( externalServerKey, @@ -372,7 +374,7 @@ public void shouldTreatServerWithInternalServerAttributeNotEqualToTrueExternal() Map servers = ImmutableMap.of("server1", createInternalServer(), externalServerKey, externalServer); Map machines = - singletonMap("machine1", new MachineImpl(singletonMap("key", "value"), servers)); + singletonMap("machine1", new MachineImpl(singletonMap("key", "value"), servers, RUNNING)); workspace.setRuntime(new RuntimeImpl("activeEnv", machines, "user123")); when(wsManager.getWorkspace(workspace.getId())).thenReturn(workspace); Map expected = @@ -380,6 +382,7 @@ public void shouldTreatServerWithInternalServerAttributeNotEqualToTrueExternal() "machine1", newDto(MachineDto.class) .withAttributes(singletonMap("key", "value")) + .withStatus(RUNNING) .withServers( singletonMap( externalServerKey, @@ -415,7 +418,7 @@ public void shouldGetWorkspaceWithInternalServers() throws Exception { ImmutableMap.of( internalServerKey, createInternalServer(), externalServerKey, externalServer); Map machines = - singletonMap("machine1", new MachineImpl(singletonMap("key", "value"), servers)); + singletonMap("machine1", new MachineImpl(singletonMap("key", "value"), servers, RUNNING)); workspace.setRuntime(new RuntimeImpl("activeEnv", machines, "user123")); when(wsManager.getWorkspace(workspace.getId())).thenReturn(workspace); @@ -424,6 +427,7 @@ public void shouldGetWorkspaceWithInternalServers() throws Exception { "machine1", newDto(MachineDto.class) .withAttributes(singletonMap("key", "value")) + .withStatus(RUNNING) .withServers( ImmutableMap.of( externalServerKey, @@ -466,7 +470,7 @@ public void shouldGetWorkspaceWithInternalServersIfCorrespondingQueryParamHasEmp ImmutableMap.of( internalServerKey, createInternalServer(), externalServerKey, externalServer); Map machines = - singletonMap("machine1", new MachineImpl(singletonMap("key", "value"), servers)); + singletonMap("machine1", new MachineImpl(singletonMap("key", "value"), servers, RUNNING)); workspace.setRuntime(new RuntimeImpl("activeEnv", machines, "user123")); when(wsManager.getWorkspace(workspace.getId())).thenReturn(workspace); @@ -475,6 +479,7 @@ public void shouldGetWorkspaceWithInternalServersIfCorrespondingQueryParamHasEmp "machine1", newDto(MachineDto.class) .withAttributes(singletonMap("key", "value")) + .withStatus(RUNNING) .withServers( ImmutableMap.of( externalServerKey, @@ -517,7 +522,7 @@ public void shouldGetWorkspaceWithInternalServersIfCorrespondingQueryParamHasNoV ImmutableMap.of( internalServerKey, createInternalServer(), externalServerKey, externalServer); Map machines = - singletonMap("machine1", new MachineImpl(singletonMap("key", "value"), servers)); + singletonMap("machine1", new MachineImpl(singletonMap("key", "value"), servers, RUNNING)); workspace.setRuntime(new RuntimeImpl("activeEnv", machines, "user123")); when(wsManager.getWorkspace(workspace.getId())).thenReturn(workspace); @@ -526,6 +531,7 @@ public void shouldGetWorkspaceWithInternalServersIfCorrespondingQueryParamHasNoV "machine1", newDto(MachineDto.class) .withAttributes(singletonMap("key", "value")) + .withStatus(RUNNING) .withServers( ImmutableMap.of( externalServerKey, diff --git a/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/spi/InternalRuntimeTest.java b/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/spi/InternalRuntimeTest.java index 059a3c92fff5..bacc7805b8b6 100644 --- a/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/spi/InternalRuntimeTest.java +++ b/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/spi/InternalRuntimeTest.java @@ -41,6 +41,7 @@ import org.eclipse.che.api.core.model.workspace.Warning; import org.eclipse.che.api.core.model.workspace.config.ServerConfig; import org.eclipse.che.api.core.model.workspace.runtime.Machine; +import org.eclipse.che.api.core.model.workspace.runtime.MachineStatus; import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity; import org.eclipse.che.api.core.model.workspace.runtime.ServerStatus; import org.eclipse.che.api.workspace.server.URLRewriter; @@ -325,7 +326,8 @@ public void shouldNotRewriteURLsOfInternalServers() throws Exception { MachineImpl machineWithInternalServer = new MachineImpl( createAttributes(), - ImmutableMap.of("server1", regularServer, "server2", internalServer)); + ImmutableMap.of("server1", regularServer, "server2", internalServer), + MachineStatus.RUNNING); ImmutableMap internalMachines = ImmutableMap.of("m1", createMachine(), "m2", machineWithInternalServer); ImmutableMap expected = @@ -335,7 +337,8 @@ public void shouldNotRewriteURLsOfInternalServers() throws Exception { "m2", new MachineImpl( createAttributes(), - ImmutableMap.of("server1", rewriteURL(regularServer), "server2", internalServer))); + ImmutableMap.of("server1", rewriteURL(regularServer), "server2", internalServer), + MachineStatus.RUNNING)); setRunningRuntime(); doReturn(internalMachines).when(internalRuntime).getInternalMachines(); @@ -410,7 +413,8 @@ private HashMap createMachines( expectedProps, singletonMap( expectedServerName, - new ServerImpl().withUrl(expectedServerUrl).withStatus(expectedServerStatus))); + new ServerImpl().withUrl(expectedServerUrl).withStatus(expectedServerStatus)), + MachineStatus.RUNNING); HashMap result = new HashMap<>(); result.put("m1", createMachine()); result.put("m2", createMachine()); @@ -476,7 +480,8 @@ public void shouldAddAWarningInsteadOfAServerIfURLRewritingFailed() throws Excep machine1.getServers().put(badServerName, failingRewritingServer); internalMachines.put("m1", machine1); internalMachines.put("m2", machine2); - expectedMachines.put("m1", new MachineImpl(machine1.getAttributes(), expectedServers)); + expectedMachines.put( + "m1", new MachineImpl(machine1.getAttributes(), expectedServers, machine1.getStatus())); expectedMachines.put("m2", machine2); List expectedWarnings = new ArrayList<>(); expectedWarnings.add( @@ -497,7 +502,7 @@ public void shouldAddAWarningInsteadOfAServerIfURLRewritingFailed() throws Excep } private static MachineImpl createMachine() throws Exception { - return new MachineImpl(createAttributes(), createServers()); + return new MachineImpl(createAttributes(), createServers(), MachineStatus.RUNNING); } private static Map createAttributes() { From 6e6bb04a6f0078769491a98ca9d53003e64a8695 Mon Sep 17 00:00:00 2001 From: Artem Zatsarynnyi Date: Tue, 19 Dec 2017 09:46:13 +0200 Subject: [PATCH 06/30] Add IDE actions for working with GWT SDM instead of bookmarklets (#7515) --- ide/che-core-ide-app/pom.xml | 4 + .../che/ide/CoreLocalizationConstant.java | 15 ++ .../core/StandardComponentInitializer.java | 12 ++ .../che/ide/devmode/BookmarkletParams.java | 49 +++++ .../che/ide/devmode/DevModeOffAction.java | 35 ++++ .../ide/devmode/DevModeScriptInjector.java | 57 ++++++ .../che/ide/devmode/DevModeSetUpAction.java | 35 ++++ .../eclipse/che/ide/devmode/GWTDevMode.java | 174 ++++++++++++++++++ .../ide/CoreLocalizationConstant.properties | 7 + .../che/ide/devmode/DevModeOffActionTest.java | 39 ++++ .../ide/devmode/DevModeSetUpActionTest.java | 39 ++++ .../che/ide/devmode/GWTDevModeTest.java | 108 +++++++++++ 12 files changed, 574 insertions(+) create mode 100644 ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/devmode/BookmarkletParams.java create mode 100644 ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/devmode/DevModeOffAction.java create mode 100644 ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/devmode/DevModeScriptInjector.java create mode 100644 ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/devmode/DevModeSetUpAction.java create mode 100644 ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/devmode/GWTDevMode.java create mode 100644 ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/devmode/DevModeOffActionTest.java create mode 100644 ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/devmode/DevModeSetUpActionTest.java create mode 100644 ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/devmode/GWTDevModeTest.java diff --git a/ide/che-core-ide-app/pom.xml b/ide/che-core-ide-app/pom.xml index d451368f03db..753714124dd6 100644 --- a/ide/che-core-ide-app/pom.xml +++ b/ide/che-core-ide-app/pom.xml @@ -48,6 +48,10 @@ com.google.inject.extensions guice-assistedinject + + com.google.jsinterop + jsinterop-annotations + javax.inject javax.inject diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/CoreLocalizationConstant.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/CoreLocalizationConstant.java index 4efc98705fb6..3b60a1d1227c 100644 --- a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/CoreLocalizationConstant.java +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/CoreLocalizationConstant.java @@ -1279,4 +1279,19 @@ String sshConnectInfo( @Key("menu.loader.pullingImage") String menuLoaderPullingImage(String image); + + @Key("gwt_recompile.action.setup.title") + String gwtDevModeSetUpActionTitle(); + + @Key("gwt_recompile.action.off.title") + String gwtDevModeOffActionTitle(); + + @Key("gwt_recompile.dialog.title") + String gwtRecompileDialogTitle(); + + @Key("gwt_recompile.dialog.message.recompiling") + String gwtRecompileDialogRecompilingMessage(String host); + + @Key("gwt_recompile.dialog.message.no_server") + String gwtRecompileDialogNoServerMessage(); } diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/core/StandardComponentInitializer.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/core/StandardComponentInitializer.java index c8329281c6a0..fe59ff0ce903 100644 --- a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/core/StandardComponentInitializer.java +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/core/StandardComponentInitializer.java @@ -118,6 +118,8 @@ import org.eclipse.che.ide.api.parts.PerspectiveManager; import org.eclipse.che.ide.command.editor.CommandEditorProvider; import org.eclipse.che.ide.command.palette.ShowCommandsPaletteAction; +import org.eclipse.che.ide.devmode.DevModeOffAction; +import org.eclipse.che.ide.devmode.DevModeSetUpAction; import org.eclipse.che.ide.imageviewer.ImageViewerProvider; import org.eclipse.che.ide.imageviewer.PreviewImageAction; import org.eclipse.che.ide.machine.MachineResources; @@ -359,6 +361,10 @@ public interface ParserResource extends ClientBundle { @Inject private RemoveFromFileWatcherExcludesAction removeFromFileWatcherExcludesAction; + @Inject private DevModeSetUpAction devModeSetUpAction; + + @Inject private DevModeOffAction devModeOffAction; + @Inject private CollapseAllAction collapseAllAction; @Inject private PerspectiveManager perspectiveManager; @@ -654,6 +660,12 @@ public void initialize() { actionManager.registerAction(NAVIGATE_TO_FILE, navigateToFileAction); assistantGroup.add(navigateToFileAction); + assistantGroup.addSeparator(); + actionManager.registerAction("devModeSetUpAction", devModeSetUpAction); + actionManager.registerAction("devModeOffAction", devModeOffAction); + assistantGroup.add(devModeSetUpAction); + assistantGroup.add(devModeOffAction); + // Compose Profile menu DefaultActionGroup profileGroup = (DefaultActionGroup) actionManager.getAction(GROUP_PROFILE); actionManager.registerAction("showPreferences", showPreferencesAction); diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/devmode/BookmarkletParams.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/devmode/BookmarkletParams.java new file mode 100644 index 000000000000..cdbe051f94f3 --- /dev/null +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/devmode/BookmarkletParams.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.ide.devmode; + +import static jsinterop.annotations.JsPackage.GLOBAL; + +import javax.inject.Singleton; +import jsinterop.annotations.JsPackage; +import jsinterop.annotations.JsProperty; +import jsinterop.annotations.JsType; + +/** Helps to set-up the parameters for GWT Super DevMode. */ +@Singleton +class BookmarkletParams { + + /** Sets-up URL of the Code Server and GWT module name to recompile. */ + void setParams(String codeServerURL, String moduleName) { + Params params = new Params(); + params.setServerURL(codeServerURL); + params.setModuleName(moduleName); + + Window.setParams(params); + } + + @JsType(isNative = true, name = "window", namespace = JsPackage.GLOBAL) + private static class Window { + + @JsProperty(name = "__gwt_bookmarklet_params") + static native void setParams(Object message); + } + + @JsType(isNative = true, name = "Object", namespace = GLOBAL) + private static class Params { + + @JsProperty(name = "server_url") + native void setServerURL(String serverURL); + + @JsProperty(name = "module_name") + native void setModuleName(String moduleName); + } +} diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/devmode/DevModeOffAction.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/devmode/DevModeOffAction.java new file mode 100644 index 000000000000..4742d1051f47 --- /dev/null +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/devmode/DevModeOffAction.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.ide.devmode; + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import org.eclipse.che.ide.CoreLocalizationConstant; +import org.eclipse.che.ide.api.action.ActionEvent; +import org.eclipse.che.ide.api.action.BaseAction; + +@Singleton +public class DevModeOffAction extends BaseAction { + + private final GWTDevMode gwtDevMode; + + @Inject + public DevModeOffAction(CoreLocalizationConstant messages, GWTDevMode gwtDevMode) { + super(messages.gwtDevModeOffActionTitle()); + + this.gwtDevMode = gwtDevMode; + } + + @Override + public void actionPerformed(ActionEvent event) { + gwtDevMode.off(); + } +} diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/devmode/DevModeScriptInjector.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/devmode/DevModeScriptInjector.java new file mode 100644 index 000000000000..d394743e25be --- /dev/null +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/devmode/DevModeScriptInjector.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.ide.devmode; + +import com.google.gwt.core.client.Callback; +import com.google.gwt.core.client.ScriptInjector; +import elemental.js.JsBrowser; +import javax.inject.Singleton; +import org.eclipse.che.api.promises.client.Promise; +import org.eclipse.che.api.promises.client.callback.CallbackPromiseHelper; + +/** Allows to inject JavaScript for enabling Super DevMode on a host page. */ +@Singleton +class DevModeScriptInjector { + + private static final String DEV_MODE_SCRIPT_NAME = "dev_mode_on.js"; + + private static Callback getScriptInjectionCallback( + Callback promiseCallback) { + + return new Callback() { + @Override + public void onSuccess(Void result) { + promiseCallback.onSuccess(result); + } + + @Override + public void onFailure(Exception reason) { + promiseCallback.onFailure(reason); + } + }; + } + + /** + * Injects the JS script, that communicates with a Code Server, into a host page. + * + * @param url host URL where script is located. Usually should be a Code Server URL + * @return promise that may be resolved if script has been injected successfully or rejected in + * case of any error while script injection + */ + Promise inject(String url) { + return CallbackPromiseHelper.createFromCallback( + promiseCallback -> + ScriptInjector.fromUrl(url + DEV_MODE_SCRIPT_NAME) + .setWindow(JsBrowser.getWindow()) + .setCallback(getScriptInjectionCallback(promiseCallback)) + .inject()); + } +} diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/devmode/DevModeSetUpAction.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/devmode/DevModeSetUpAction.java new file mode 100644 index 000000000000..e6885093d57d --- /dev/null +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/devmode/DevModeSetUpAction.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.ide.devmode; + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import org.eclipse.che.ide.CoreLocalizationConstant; +import org.eclipse.che.ide.api.action.ActionEvent; +import org.eclipse.che.ide.api.action.BaseAction; + +@Singleton +public class DevModeSetUpAction extends BaseAction { + + private final GWTDevMode gwtDevMode; + + @Inject + public DevModeSetUpAction(CoreLocalizationConstant messages, GWTDevMode gwtDevMode) { + super(messages.gwtDevModeSetUpActionTitle()); + + this.gwtDevMode = gwtDevMode; + } + + @Override + public void actionPerformed(ActionEvent event) { + gwtDevMode.setUp(); + } +} diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/devmode/GWTDevMode.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/devmode/GWTDevMode.java new file mode 100644 index 000000000000..4b9f1feb8d0e --- /dev/null +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/devmode/GWTDevMode.java @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.ide.devmode; + +import static com.google.common.base.Strings.isNullOrEmpty; + +import elemental.client.Browser; +import elemental.html.Storage; +import elemental.html.Window; +import java.util.Optional; +import javax.inject.Inject; +import javax.inject.Singleton; +import org.eclipse.che.api.promises.client.Operation; +import org.eclipse.che.api.promises.client.Promise; +import org.eclipse.che.api.promises.client.PromiseError; +import org.eclipse.che.ide.CoreLocalizationConstant; +import org.eclipse.che.ide.api.workspace.WsAgentServerUtil; +import org.eclipse.che.ide.api.workspace.model.MachineImpl; +import org.eclipse.che.ide.api.workspace.model.ServerImpl; +import org.eclipse.che.ide.ui.dialogs.DialogFactory; +import org.eclipse.che.ide.ui.dialogs.message.MessageDialog; + +/** + * Helps to set-up Super DevMode for the current IDE GWT app. + * + *

It does not communicate with a GWT CodeServer directly in any way but relies on the {@code + * dev_mode_on.js} script functionality from the {@code gwt-dev} library. + */ +@Singleton +class GWTDevMode { + + public static final String LOCAL_CODE_SERVER_ADDRESS = "http://127.0.0.1:9876/"; + public static final String INT_CODE_SERVER_REF = "GWT-CodeServer"; + public static final String IDE_GWT_APP_SHORT_NAME = "_app"; + + private final WsAgentServerUtil wsAgentServerUtil; + private final DevModeScriptInjector devModeScriptInjector; + private final BookmarkletParams bookmarkletParams; + private final DialogFactory dialogFactory; + private final CoreLocalizationConstant messages; + + @Inject + GWTDevMode( + WsAgentServerUtil wsAgentServerUtil, + DevModeScriptInjector devModeScriptInjector, + BookmarkletParams bookmarkletParams, + DialogFactory dialogFactory, + CoreLocalizationConstant messages) { + this.wsAgentServerUtil = wsAgentServerUtil; + this.devModeScriptInjector = devModeScriptInjector; + this.bookmarkletParams = bookmarkletParams; + this.dialogFactory = dialogFactory; + this.messages = messages; + } + + /** + * Sets-up Super DevMode for the current IDE GWT app. Tries to use Code Server launched in a + * dev-machine or at a localhost depending on which one is launched. + */ + void setUp() { + String codeServerURL = getInternalCodeServerURL().orElse(LOCAL_CODE_SERVER_ADDRESS); + + setUpSuperDevModeWithUI(codeServerURL); + } + + /** Turn off Super DevMode for the current IDE GWT app. */ + void off() { + Window window = Browser.getWindow(); + Storage sessionStorage = window.getSessionStorage(); + + for (int i = 0; i < sessionStorage.getLength(); i++) { + String key = sessionStorage.key(i); + + if (key.equals("__gwtDevModeHook:" + IDE_GWT_APP_SHORT_NAME)) { + sessionStorage.removeItem(key); + break; + } + } + + window.getLocation().reload(); + } + + /** + * Returns a top-level URL of the GWT Code Server which is declared in the machine that contains + * the "wsagent" server. + * + * @return {@code Optional} with a top-level URL of the GWT Code Server or an empty {@code + * Optional} if none + */ + private Optional getInternalCodeServerURL() { + Optional wsAgentServerMachineOpt = wsAgentServerUtil.getWsAgentServerMachine(); + + if (wsAgentServerMachineOpt.isPresent()) { + MachineImpl wsAgentServerMachine = wsAgentServerMachineOpt.get(); + Optional codeServerOpt = + wsAgentServerMachine.getServerByName(INT_CODE_SERVER_REF); + + if (codeServerOpt.isPresent()) { + ServerImpl codeServer = codeServerOpt.get(); + String codeServerUrl = codeServer.getUrl(); + + if (!isNullOrEmpty(codeServerUrl)) { + return codeServerUrl.endsWith("/") + ? Optional.of(codeServerUrl) + : Optional.of(codeServerUrl + '/'); + } + } + } + + return Optional.empty(); + } + + /** + * Tries to set-up Super DevMode for the current IDE GWT app and shows an appropriate message to + * the user. + */ + private void setUpSuperDevModeWithUI(String codeServerURL) { + setUpSuperDevMode(codeServerURL) + .then(showSuccessMessage(codeServerURL)) + .catchError(handleStartRecompilationError(codeServerURL)); + } + + /** + * Tries to set-up Super DevMode for the current IDE GWT app. + * + * @param codeServerURL URL of the Code Server URL to use + * @return promise that may be resolved if Super DevMode has been set up successfully or rejected + * in case of any error while setting up Super DevMode + */ + private Promise setUpSuperDevMode(String codeServerURL) { + bookmarkletParams.setParams(codeServerURL, IDE_GWT_APP_SHORT_NAME); + + return devModeScriptInjector.inject(codeServerURL); + } + + private Operation showSuccessMessage(String codeServerURL) { + boolean isLocalhost = codeServerURL.equals(LOCAL_CODE_SERVER_ADDRESS); + + String message = + isLocalhost + ? messages.gwtRecompileDialogRecompilingMessage("localhost") + : messages.gwtRecompileDialogRecompilingMessage("dev-machine"); + + MessageDialog dialog = + dialogFactory.createMessageDialog(messages.gwtRecompileDialogTitle(), message, null); + + return aVoid -> dialog.show(); + } + + private Operation handleStartRecompilationError(String codeServerURL) { + boolean isLocalhost = codeServerURL.equals(LOCAL_CODE_SERVER_ADDRESS); + + return err -> { + if (!isLocalhost) { + setUpSuperDevModeWithUI(LOCAL_CODE_SERVER_ADDRESS); + } else { + dialogFactory + .createMessageDialog( + messages.gwtRecompileDialogTitle(), + messages.gwtRecompileDialogNoServerMessage(), + null) + .show(); + } + }; + } +} diff --git a/ide/che-core-ide-app/src/main/resources/org/eclipse/che/ide/CoreLocalizationConstant.properties b/ide/che-core-ide-app/src/main/resources/org/eclipse/che/ide/CoreLocalizationConstant.properties index 2b3c2bf5dd82..dd0c8c4f3d78 100644 --- a/ide/che-core-ide-app/src/main/resources/org/eclipse/che/ide/CoreLocalizationConstant.properties +++ b/ide/che-core-ide-app/src/main/resources/org/eclipse/che/ide/CoreLocalizationConstant.properties @@ -572,3 +572,10 @@ menu.loader.machineRunning = Machine {0} is menu.loader.workspaceStarted = Workspace successfully started menu.loader.waitingWorkspace = Waiting workspace machines to be booted... menu.loader.pullingImage = Pulling image {0} ... + +##### GWT SDM ##### +gwt_recompile.action.setup.title = GWT Super DevMode: recompile +gwt_recompile.action.off.title = GWT Super DevMode: turn off +gwt_recompile.dialog.title = GWT Super DevMode +gwt_recompile.dialog.message.recompiling = Recompiling at {0}... +gwt_recompile.dialog.message.no_server = No running Code Server in a dev-machine or localhost found diff --git a/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/devmode/DevModeOffActionTest.java b/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/devmode/DevModeOffActionTest.java new file mode 100644 index 000000000000..abc81f5ac14e --- /dev/null +++ b/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/devmode/DevModeOffActionTest.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.ide.devmode; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import org.eclipse.che.ide.CoreLocalizationConstant; +import org.eclipse.che.ide.api.action.ActionEvent; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +/** Tests for the {@link DevModeOffAction}. */ +@RunWith(MockitoJUnitRunner.class) +public class DevModeOffActionTest { + + @Mock CoreLocalizationConstant messages; + @Mock GWTDevMode gwtDevMode; + + @InjectMocks DevModeOffAction action; + + @Test + public void shouldTurnOffDevModeOnPerformingAction() throws Exception { + action.actionPerformed(mock(ActionEvent.class)); + + verify(gwtDevMode).off(); + } +} diff --git a/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/devmode/DevModeSetUpActionTest.java b/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/devmode/DevModeSetUpActionTest.java new file mode 100644 index 000000000000..f56c5953c0d8 --- /dev/null +++ b/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/devmode/DevModeSetUpActionTest.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.ide.devmode; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import org.eclipse.che.ide.CoreLocalizationConstant; +import org.eclipse.che.ide.api.action.ActionEvent; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +/** Tests for the {@link DevModeSetUpAction}. */ +@RunWith(MockitoJUnitRunner.class) +public class DevModeSetUpActionTest { + + @Mock CoreLocalizationConstant messages; + @Mock GWTDevMode gwtDevMode; + + @InjectMocks DevModeSetUpAction action; + + @Test + public void shouldSetUpDevModeOnPerformingAction() throws Exception { + action.actionPerformed(mock(ActionEvent.class)); + + verify(gwtDevMode).setUp(); + } +} diff --git a/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/devmode/GWTDevModeTest.java b/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/devmode/GWTDevModeTest.java new file mode 100644 index 000000000000..342cbef3ae16 --- /dev/null +++ b/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/devmode/GWTDevModeTest.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.ide.devmode; + +import static org.eclipse.che.ide.devmode.GWTDevMode.IDE_GWT_APP_SHORT_NAME; +import static org.eclipse.che.ide.devmode.GWTDevMode.INT_CODE_SERVER_REF; +import static org.eclipse.che.ide.devmode.GWTDevMode.LOCAL_CODE_SERVER_ADDRESS; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.Optional; +import org.eclipse.che.api.promises.client.Operation; +import org.eclipse.che.api.promises.client.Promise; +import org.eclipse.che.api.promises.client.PromiseError; +import org.eclipse.che.ide.CoreLocalizationConstant; +import org.eclipse.che.ide.api.workspace.WsAgentServerUtil; +import org.eclipse.che.ide.api.workspace.model.MachineImpl; +import org.eclipse.che.ide.api.workspace.model.ServerImpl; +import org.eclipse.che.ide.ui.dialogs.DialogFactory; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +/** Tests for the {@link GWTDevMode}. */ +@RunWith(MockitoJUnitRunner.class) +public class GWTDevModeTest { + + static final String INT_CODE_SERVER_URL = "http://172.19.20.28:12345/"; + + @Mock WsAgentServerUtil wsAgentServerUtil; + @Mock DevModeScriptInjector devModeScriptInjector; + @Mock BookmarkletParams bookmarkletParams; + @Mock DialogFactory dialogFactory; + @Mock CoreLocalizationConstant messages; + + @Mock Promise voidPromise; + @Mock PromiseError promiseError; + @Captor ArgumentCaptor> promiseErrorOperationCapture; + + @Mock MachineImpl wsAgentMachine; + @Mock ServerImpl codeServer; + + @InjectMocks GWTDevMode devMode; + + @Test + public void shouldSetUpDevModeForInternalCodeServer() throws Exception { + mockInternalCodeServer(); + + when(devModeScriptInjector.inject(anyString())).thenReturn(voidPromise); + when(voidPromise.then(any(Operation.class))).thenReturn(voidPromise); + + devMode.setUp(); + + verify(bookmarkletParams).setParams(INT_CODE_SERVER_URL, IDE_GWT_APP_SHORT_NAME); + verify(devModeScriptInjector).inject(INT_CODE_SERVER_URL); + } + + @Test + public void shouldSetUpDevModeForLocalCodeServerIfNoInternalOne() throws Exception { + when(devModeScriptInjector.inject(anyString())).thenReturn(voidPromise); + when(voidPromise.then(any(Operation.class))).thenReturn(voidPromise); + + devMode.setUp(); + + verify(bookmarkletParams).setParams(LOCAL_CODE_SERVER_ADDRESS, IDE_GWT_APP_SHORT_NAME); + verify(devModeScriptInjector).inject(LOCAL_CODE_SERVER_ADDRESS); + } + + @Test + public void shouldSetUpDevModeForLocalCodeServerIfFailedForInternalOne() throws Exception { + mockInternalCodeServer(); + + when(devModeScriptInjector.inject(anyString())).thenReturn(voidPromise); + when(voidPromise.then(any(Operation.class))).thenReturn(voidPromise); + + devMode.setUp(); + + verify(bookmarkletParams, never()).setParams(LOCAL_CODE_SERVER_ADDRESS, IDE_GWT_APP_SHORT_NAME); + verify(devModeScriptInjector, never()).inject(LOCAL_CODE_SERVER_ADDRESS); + + verify(voidPromise).catchError(promiseErrorOperationCapture.capture()); + promiseErrorOperationCapture.getValue().apply(promiseError); + + verify(bookmarkletParams).setParams(INT_CODE_SERVER_URL, IDE_GWT_APP_SHORT_NAME); + verify(devModeScriptInjector).inject(INT_CODE_SERVER_URL); + } + + private void mockInternalCodeServer() { + when(codeServer.getUrl()).thenReturn(INT_CODE_SERVER_URL); + when(wsAgentMachine.getServerByName(INT_CODE_SERVER_REF)).thenReturn(Optional.of(codeServer)); + when(wsAgentServerUtil.getWsAgentServerMachine()).thenReturn(Optional.of(wsAgentMachine)); + } +} From 3919c892f936d2de5cdbd2f5af7722c49a0afb83 Mon Sep 17 00:00:00 2001 From: Lee Fenlan Date: Mon, 18 Dec 2017 10:46:57 +0800 Subject: [PATCH 07/30] sed apps.openshift.io/ out of the version as its invalid closes #7803 Signed-off-by: Lee Fenlan --- dockerfiles/init/modules/openshift/files/scripts/deploy_che.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dockerfiles/init/modules/openshift/files/scripts/deploy_che.sh b/dockerfiles/init/modules/openshift/files/scripts/deploy_che.sh index 940f43009b1f..38c8716983be 100755 --- a/dockerfiles/init/modules/openshift/files/scripts/deploy_che.sh +++ b/dockerfiles/init/modules/openshift/files/scripts/deploy_che.sh @@ -424,6 +424,7 @@ if [ "${OPENSHIFT_FLAVOR}" == "minishift" ]; then echo "[CHE] Deploying Che on minishift (image ${CHE_IMAGE})" curl -sSL http://central.maven.org/maven2/io/fabric8/tenant/apps/che/"${OSIO_VERSION}"/che-"${OSIO_VERSION}"-openshift.yml | \ if [ ! -z "${OPENSHIFT_NAMESPACE_URL+x}" ]; then sed "s/ hostname-http:.*/ hostname-http: ${OPENSHIFT_NAMESPACE_URL}/" ; else cat -; fi | \ + sed "s/apps.openshift.io\///" | \ sed "s/ image:.*/ image: \"${CHE_IMAGE_SANITIZED}\"/" | \ sed "s/ imagePullPolicy:.*/ imagePullPolicy: \"${IMAGE_PULL_POLICY}\"/" | \ sed "s/ workspaces-memory-limit: 2300Mi/ workspaces-memory-limit: 1300Mi/" | \ From 52599d66a8ce1799e01ce147bd6bd54a6dce8293 Mon Sep 17 00:00:00 2001 From: Igor Vinokur Date: Tue, 19 Dec 2017 08:33:28 +0000 Subject: [PATCH 08/30] CHE-7661: Clear active debugger on connection error (#7932) --- .../eclipse/che/plugin/debugger/ide/debug/AbstractDebugger.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/plugin-debugger/che-plugin-debugger-ide/src/main/java/org/eclipse/che/plugin/debugger/ide/debug/AbstractDebugger.java b/plugins/plugin-debugger/che-plugin-debugger-ide/src/main/java/org/eclipse/che/plugin/debugger/ide/debug/AbstractDebugger.java index deec22dfce70..8c04082835f5 100644 --- a/plugins/plugin-debugger/che-plugin-debugger-ide/src/main/java/org/eclipse/che/plugin/debugger/ide/debug/AbstractDebugger.java +++ b/plugins/plugin-debugger/che-plugin-debugger-ide/src/main/java/org/eclipse/che/plugin/debugger/ide/debug/AbstractDebugger.java @@ -494,6 +494,7 @@ public Promise connect(Map connectionProperties) { }) .catchError( error -> { + debuggerManager.setActiveDebugger(null); notification.setTitle( constant.failedToConnectToRemoteDebuggerDescription( debuggerDescriptor.getAddress(), error.getMessage())); From 2e3cb47a6bf8042a13492e7f885e587bfbb5cda2 Mon Sep 17 00:00:00 2001 From: Maxim Musienko Date: Tue, 19 Dec 2017 10:51:09 +0200 Subject: [PATCH 09/30] Complement unstable parts of the selenium tests with info about known issues (#7934) * add Asserts to tests with depended issues --- .../che/selenium/debugger/NodeJsDebugTest.java | 9 ++++++++- .../factory/DirectUrlFactoryWithRootFolder.java | 7 ++++++- .../DirectUrlFactoryWithSpecificBranch.java | 9 ++++++++- .../testrunner/JavaTestPluginTestNgTest.java | 15 +++++++++++---- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/debugger/NodeJsDebugTest.java b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/debugger/NodeJsDebugTest.java index 66b21df42de4..d05b9e4c8723 100644 --- a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/debugger/NodeJsDebugTest.java +++ b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/debugger/NodeJsDebugTest.java @@ -12,6 +12,7 @@ import static org.eclipse.che.selenium.core.constant.TestTimeoutsConstants.REDRAW_UI_ELEMENTS_TIMEOUT_SEC; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.fail; import com.google.inject.Inject; import java.net.URL; @@ -33,6 +34,7 @@ import org.eclipse.che.selenium.pageobject.debug.DebugPanel; import org.eclipse.che.selenium.pageobject.debug.NodeJsDebugConfig; import org.openqa.selenium.By; +import org.openqa.selenium.TimeoutException; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import org.testng.Assert; @@ -127,7 +129,12 @@ private void checkEvaluationFeatures() { debugPanel.clickOnButton(DebugPanel.DebuggerActionButtons.EVALUATE_EXPRESSIONS); debugPanel.typeEvaluateExpression("c.length"); debugPanel.clickEvaluateBtn(); - debugPanel.waitExpectedResultInEvaluateExpression("19"); + try { + debugPanel.waitExpectedResultInEvaluateExpression("19"); + } catch (TimeoutException ex) { + // remove try-catch block after issue has been resolved + fail("Known issue https://github.com/eclipse/che/issues/4720", ex); + } debugPanel.clickCloseEvaluateBtn(); } } diff --git a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/factory/DirectUrlFactoryWithRootFolder.java b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/factory/DirectUrlFactoryWithRootFolder.java index 8b3538a03953..e9852307d13e 100644 --- a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/factory/DirectUrlFactoryWithRootFolder.java +++ b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/factory/DirectUrlFactoryWithRootFolder.java @@ -84,7 +84,12 @@ public void factoryWithDirectUrlWithRootFolder() throws Exception { "tslint.json", "typings.json", "wallaby.js"); - testFactoryWithRootFolder.authenticateAndOpen(); + try { + testFactoryWithRootFolder.authenticateAndOpen(); + } catch (TimeoutException ex) { + // remove try-catch block after issue has been resolved + fail("Known issue https://github.com/eclipse/che/issues/7555", ex); + } projectExplorer.waitProjectExplorer(); projectExplorer.waitItem(EXPECTED_PROJECT); notificationsPopupPanel.waitProgressPopupPanelClose(); diff --git a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/factory/DirectUrlFactoryWithSpecificBranch.java b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/factory/DirectUrlFactoryWithSpecificBranch.java index 6b3910855512..ccd02f7069a8 100644 --- a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/factory/DirectUrlFactoryWithSpecificBranch.java +++ b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/factory/DirectUrlFactoryWithSpecificBranch.java @@ -12,6 +12,7 @@ import static org.eclipse.che.selenium.core.constant.TestTimeoutsConstants.UPDATING_PROJECT_TIMEOUT_SEC; import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; import com.google.common.collect.ImmutableList; import com.google.inject.Inject; @@ -27,6 +28,7 @@ import org.eclipse.che.selenium.pageobject.Ide; import org.eclipse.che.selenium.pageobject.NotificationsPopupPanel; import org.eclipse.che.selenium.pageobject.ProjectExplorer; +import org.openqa.selenium.TimeoutException; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -64,7 +66,12 @@ public void tearDown() throws Exception { @Test public void factoryWithDirectUrlWithSpecificBranch() throws Exception { - testFactoryWithSpecificBranch.authenticateAndOpen(); + try { + testFactoryWithSpecificBranch.authenticateAndOpen(); + } catch (TimeoutException ex) { + // remove try-catch block after issue has been resolved + fail("Known issue https://github.com/eclipse/che/issues/7555", ex); + } projectExplorer.waitProjectExplorer(); notificationsPopupPanel.waitProgressPopupPanelClose(); events.clickEventLogBtn(); diff --git a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/testrunner/JavaTestPluginTestNgTest.java b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/testrunner/JavaTestPluginTestNgTest.java index 8b85c5de50a8..2592c0fd2e73 100644 --- a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/testrunner/JavaTestPluginTestNgTest.java +++ b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/testrunner/JavaTestPluginTestNgTest.java @@ -16,6 +16,7 @@ import static org.eclipse.che.selenium.pageobject.plugins.JavaTestRunnerPluginConsole.JunitMethodsState.FAILED; import static org.eclipse.che.selenium.pageobject.plugins.JavaTestRunnerPluginConsole.JunitMethodsState.PASSED; import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; import com.google.inject.Inject; import java.net.URL; @@ -38,6 +39,7 @@ import org.eclipse.che.selenium.pageobject.ProjectExplorer; import org.eclipse.che.selenium.pageobject.intelligent.CommandsPalette; import org.eclipse.che.selenium.pageobject.plugins.JavaTestRunnerPluginConsole; +import org.openqa.selenium.TimeoutException; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -105,7 +107,7 @@ public void prepareTestProject() throws Exception { } @Test - public void shouldExecuteTestClassSuccessfully() throws InterruptedException { + public void shouldExecuteTestClassSuccessfully() { // given projectExplorer.quickRevealToItemWithJavaScript(PATH_TO_ANOTHER_TEST_CLASS); projectExplorer.openItemByPath(PATH_TO_TEST_CLASS); @@ -127,7 +129,7 @@ public void shouldExecuteTestClassSuccessfully() throws InterruptedException { } @Test(priority = 1) - public void shouldExecuteTestMethodsSuccessfully() throws InterruptedException { + public void shouldExecuteTestMethodsSuccessfully() { // given projectExplorer.openItemByPath(PATH_TO_ANOTHER_TEST_CLASS); @@ -140,7 +142,12 @@ public void shouldExecuteTestMethodsSuccessfully() throws InterruptedException { assertTrue(pluginConsole.getAllNamesOfMethodsMarkedDefinedStatus(PASSED).size() == 1); editor.goToCursorPositionVisible(30, 17); menu.runCommand(RUN_MENU, TEST, TEST_NG_TEST_DROP_DAWN_ITEM); - pluginConsole.waitMethodMarkedAsFailed("shouldFailOfAppAnother"); + try { + pluginConsole.waitMethodMarkedAsFailed("shouldFailOfAppAnother"); + } catch (TimeoutException ex) { + // remove try-catch block after issue has been resolved + fail("Known issue https://github.com/eclipse/che/issues/7338", ex); + } assertTrue(pluginConsole.getAllNamesOfMethodsMarkedDefinedStatus(FAILED).size() == 1); String testErrorMessage = pluginConsole.getTestErrorMessage(); assertTrue( @@ -151,7 +158,7 @@ public void shouldExecuteTestMethodsSuccessfully() throws InterruptedException { } @Test(priority = 2) - public void shouldExecuteAlltests() throws InterruptedException { + public void shouldExecuteAlltests() { // given projectExplorer.openItemByPath(PATH_TO_ANOTHER_TEST_CLASS); From ec91a226437e29d67d8ef0a16d4636db1039e2d1 Mon Sep 17 00:00:00 2001 From: Roman Iuvshyn Date: Tue, 19 Dec 2017 15:13:30 +0200 Subject: [PATCH 10/30] Wait keycloak is booted after deploy to ocp (#7954) * Wait keycloak is booted after deploy to ocp --- .../modules/openshift/files/scripts/ocp.sh | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/dockerfiles/init/modules/openshift/files/scripts/ocp.sh b/dockerfiles/init/modules/openshift/files/scripts/ocp.sh index 74a66d0cd16d..0d94f1add2c7 100755 --- a/dockerfiles/init/modules/openshift/files/scripts/ocp.sh +++ b/dockerfiles/init/modules/openshift/files/scripts/ocp.sh @@ -157,6 +157,9 @@ deploy_che_to_ocp() { cd "${CONFIG_DIR}/instance/config/openshift/scripts/" bash deploy_che.sh ${DEPLOY_SCRIPT_ARGS} wait_until_server_is_booted + if [ $CHE_MULTIUSER == true ]; then + wait_until_kc_is_booted + fi } server_is_booted() { @@ -179,6 +182,32 @@ wait_until_server_is_booted() { done } +wait_until_kc_is_booted() { + echo "[CHE] wait Keycloak pod booting..." + available=$($OC_BINARY get dc keycloak -o json | jq ".status.conditions[] | select(.type == \"Available\") | .status") + progressing=$($OC_BINARY get dc keycloak -o json | jq ".status.conditions[] | select(.type == \"Progressing\") | .status") + + DEPLOYMENT_TIMEOUT_SEC=1200 + POLLING_INTERVAL_SEC=5 + end=$((SECONDS+DEPLOYMENT_TIMEOUT_SEC)) + while [[ "${available}" != "\"True\"" || "${progressing}" != "\"True\"" ]] && [ ${SECONDS} -lt ${end} ]; do + available=$($OC_BINARY get dc keycloak -o json | jq ".status.conditions[] | select(.type == \"Available\") | .status") + progressing=$($OC_BINARY get dc keycloak -o json | jq ".status.conditions[] | select(.type == \"Progressing\") | .status") + timeout_in=$((end-SECONDS)) + echo "[CHE] Deployment is in progress...(Available.status=${available}, Progressing.status=${progressing}, Timeout in ${timeout_in}s)" + sleep ${POLLING_INTERVAL_SEC} + done + + if [ "${progressing}" == "\"True\"" ]; then + echo "[CHE] Keycloak deployed successfully" + elif [ "${progressing}" == "False" ]; then + echo "[CHE] [ERROR] Keycloak deployment failed. Aborting. Run command 'oc rollout status keycloak' to get more details." + elif [ ${SECONDS} -ge ${end} ]; then + echo "[CHE] [ERROR] Deployment timeout. Aborting." + exit 1 + fi +} + destroy_ocp() { $OC_BINARY login -u system:admin $OC_BINARY delete pvc --all From a17ccfb86002f46eb762fd38afcd5b4f4217bb18 Mon Sep 17 00:00:00 2001 From: Oleksii Orel Date: Tue, 19 Dec 2017 12:56:26 +0200 Subject: [PATCH 11/30] CHE-7600 improve start workspace widget Signed-off-by: Oleksii Orel --- .../list-workspaces/list-workspaces.html | 5 +- .../list-workspaces/list-workspaces.styl | 5 +- .../workspace-item.directive.ts | 53 ++---- .../workspace-item/workspace-item.html | 5 +- .../workspace-status-button.directive.spec.ts | 167 ++++++++++++++++++ .../workspace-status.controller.ts | 96 +++++----- .../workspace-status.directive.ts | 43 ++--- .../workspace-status.html | 17 +- .../workspace-status.styl | 6 +- .../api/workspace/che-workspace.factory.ts | 44 ++++- 10 files changed, 291 insertions(+), 150 deletions(-) create mode 100644 dashboard/src/app/workspaces/list-workspaces/workspace-status-action/workspace-status-button.directive.spec.ts diff --git a/dashboard/src/app/workspaces/list-workspaces/list-workspaces.html b/dashboard/src/app/workspaces/list-workspaces/list-workspaces.html index 9e61a4f4872d..4f43933395b2 100644 --- a/dashboard/src/app/workspaces/list-workspaces/list-workspaces.html +++ b/dashboard/src/app/workspaces/list-workspaces/list-workspaces.html @@ -13,8 +13,8 @@ A workspace is where your projects live and run. Create workspaces from stacks that define projects, runtimes, and commands. - + Actions - - + diff --git a/dashboard/src/app/workspaces/list-workspaces/workspace-status-action/workspace-status-button.directive.spec.ts b/dashboard/src/app/workspaces/list-workspaces/workspace-status-action/workspace-status-button.directive.spec.ts new file mode 100644 index 000000000000..69500e35669c --- /dev/null +++ b/dashboard/src/app/workspaces/list-workspaces/workspace-status-action/workspace-status-button.directive.spec.ts @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2015-2017 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +import {CheHttpBackend} from '../../../../components/api/test/che-http-backend'; +import {CheWorkspace, WorkspaceStatus} from '../../../../components/api/workspace/che-workspace.factory'; +import {CheAPIBuilder} from '../../../../components/api/builder/che-api-builder.factory'; + +interface ITestScope extends ng.IRootScopeService { + model: { + workspaceId: string; + }; +} + +/** + * Test of the workspace status widget directive. + * @author Oleksii Orel + */ +describe('WorkspaceStatus >', () => { + + let $rootScope: ITestScope, + $timeout: ng.ITimeoutService, + $compile: ng.ICompileService, + httpBackend: ng.IHttpBackendService; + + /** + * Workspace Factory for the test + */ + let workspaceFactory; + /** + * API builder + */ + let apiBuilder: CheAPIBuilder; + /** + * Che backend + */ + let cheBackend: CheHttpBackend; + + /** + * setup module + */ + beforeEach(angular.mock.module('userDashboard')); + + + beforeEach(inject((_$compile_: ng.ICompileService, _$timeout_: ng.ITimeoutService, _$rootScope_: ng.IRootScopeService, cheWorkspace: CheWorkspace, cheAPIBuilder: CheAPIBuilder, cheHttpBackend: CheHttpBackend) => { + $rootScope = _$rootScope_.$new(); + $compile = _$compile_; + $timeout = _$timeout_; + + workspaceFactory = cheWorkspace; + apiBuilder = cheAPIBuilder; + cheBackend = cheHttpBackend; + httpBackend = cheHttpBackend.getHttpBackend(); + httpBackend.when('OPTIONS', '/api/').respond({}); + + $rootScope.model = { + workspaceId: 'testWorkspaceId' + }; + })); + + afterEach(() => { + $timeout.verifyNoPendingTasks(); + }); + + function getCompiledElement(status: WorkspaceStatus): ng.IAugmentedJQuery { + const defaultEnvironment = 'default'; + const environments = { + [defaultEnvironment]: { + 'machines': { + 'dev-machine': { + 'installers': ['org.eclipse.che.ws-agent'] + } + }, + 'recipe': { + 'type': 'compose', + 'content': 'services:\n dev-machine:\n image: eclipse/ubuntu_jdk8\n', + 'contentType': 'application/x-yaml' + } + } + }; + const workspace = apiBuilder.getWorkspaceBuilder().withId($rootScope.model.workspaceId).withEnvironments(environments).withDefaultEnvironment('default').withStatus(WorkspaceStatus[status]).build(); + // add workspaces on Http backend + cheBackend.addWorkspaces([workspace]); + // setup backend + cheBackend.setup(); + // fetch workspaces + workspaceFactory.fetchWorkspaces(); + // flush command + httpBackend.flush(); + + const element = $compile(angular.element( + `` + ))($rootScope); + $rootScope.$digest(); + + return element; + } + + describe('initially RUN button >', () => { + let jqElement: ng.IAugmentedJQuery; + + beforeEach(() => { + jqElement = getCompiledElement(WorkspaceStatus.STOPPED); + }); + + it('should be enabled', () => { + // timeout should be flashed + $timeout.flush(); + + expect(jqElement.get(0)).toBeTruthy(); + expect(jqElement.attr('disabled')).toBeFalsy(); + expect(jqElement.find('.fa-play')).toBeTruthy(); + }); + + it('should call the run workspace callback on click', () => { + // timeout should be flashed + $timeout.flush(); + + // expecting POSTs + httpBackend.expectPOST('/api/workspace/' + $rootScope.model.workspaceId + '/runtime?environment=default').respond(200, {}); + + jqElement.find('.workspace-status').click(); + + expect(jqElement.get(0)).toBeTruthy(); + expect(jqElement.attr('disabled')).toBeFalsy(); + expect(jqElement.find('.fa-play')).toBeTruthy(); + }); + }); + + describe('initially STOP button >', () => { + let jqElement: ng.IAugmentedJQuery; + + beforeEach(() => { + jqElement = getCompiledElement(WorkspaceStatus.RUNNING); + }); + + it('should be enabled', () => { + // timeout should be flashed + $timeout.flush(); + + expect(jqElement.get(0)).toBeTruthy(); + expect(jqElement.attr('disabled')).toBeFalsy(); + expect(jqElement.find('.fa-stop')).toBeTruthy(); + }); + + it('should call the stop workspace callback on click', () => { + // timeout should be flashed + $timeout.flush(); + + // expecting DELETEs + httpBackend.expectDELETE('/api/workspace/' + $rootScope.model.workspaceId + '/runtime').respond(200); + + jqElement.find('.workspace-status').click(); + + expect(jqElement.get(0)).toBeTruthy(); + expect(jqElement.attr('disabled')).toBeFalsy(); + expect(jqElement.find('.fa-stop')).toBeTruthy(); + }); + }); + +}); diff --git a/dashboard/src/app/workspaces/list-workspaces/workspace-status-action/workspace-status.controller.ts b/dashboard/src/app/workspaces/list-workspaces/workspace-status-action/workspace-status.controller.ts index 736e2152dbef..66e4e377fa1e 100644 --- a/dashboard/src/app/workspaces/list-workspaces/workspace-status-action/workspace-status.controller.ts +++ b/dashboard/src/app/workspaces/list-workspaces/workspace-status-action/workspace-status.controller.ts @@ -10,7 +10,7 @@ */ 'use strict'; import {CheNotification} from '../../../../components/notification/che-notification.factory'; -import {CheWorkspace} from '../../../../components/api/workspace/che-workspace.factory'; +import {CheWorkspace, WorkspaceStatus} from '../../../../components/api/workspace/che-workspace.factory'; /** * @ngdoc controller @@ -26,86 +26,78 @@ export class WorkspaceStatusController { private cheNotification: CheNotification; private cheWorkspace: CheWorkspace; - private isLoading: boolean; - private workspace: che.IWorkspace; + private isRequestPending: boolean; + private workspaceId: string; /** * Default constructor that is using resource * @ngInject for Dependency injection */ - constructor($rootScope: ng.IRootScopeService, - cheNotification: CheNotification, - cheWorkspace: CheWorkspace) { + constructor($rootScope: ng.IRootScopeService, cheWorkspace: CheWorkspace, cheNotification: CheNotification) { this.$rootScope = $rootScope; - this.cheNotification = cheNotification; this.cheWorkspace = cheWorkspace; - - this.isLoading = false; + this.cheNotification = cheNotification; } - startWorkspace(): void { - let status = this.getWorkspaceStatus(); - if (this.isLoading || !this.workspace || !this.workspace.config || !(status === 'STOPPED' || status === 'ERROR')) { + /** + * Change workspace status. + */ + changeWorkspaceStatus(): void { + if (this.isRequestPending || !this.workspaceId) { return; } - - this.updateRecentWorkspace(this.workspace.id); - - this.isLoading = true; - let promise = this.cheWorkspace.startWorkspace(this.workspace.id, this.workspace.config.defaultEnv); - - promise.then(() => { - this.isLoading = false; - }, (error: any) => { - this.isLoading = false; - this.cheNotification.showError('Run workspace error.', error); - }); - } - - stopWorkspace(): void { - let status = this.getWorkspaceStatus(); - if (this.isLoading || !this.workspace || (status !== 'RUNNING' && status !== 'STARTING')) { + const workspace = this.cheWorkspace.getWorkspaceById(this.workspaceId); + if (!workspace || !workspace.config) { return; } - this.isLoading = true; - let promise = this.cheWorkspace.stopWorkspace(this.workspace.id); + const status = this.getWorkspaceStatus(); + const isRunButton = status !== WorkspaceStatus.RUNNING && status !== WorkspaceStatus.STOPPING && status !== WorkspaceStatus.STARTING; + const environment = workspace.config.defaultEnv; - promise.then(() => { - this.isLoading = false; - }, (error: any) => { - this.isLoading = false; - this.cheNotification.showError('Stop workspace error.', error); + if (isRunButton) { + this.updateRecentWorkspace(this.workspaceId); + } + this.isRequestPending = true; + const promise = isRunButton ? this.cheWorkspace.startWorkspace(this.workspaceId, environment) : this.cheWorkspace.stopWorkspace(this.workspaceId); + promise.catch((error: any) => { + this.cheNotification.showError(`${isRunButton ? 'Run' : 'Stop'} workspace error.`, error); + }).finally(() => { + this.isRequestPending = false; }); } /** - * Returns current status of workspace - * @returns {String} + * Returns status of button. + * + * @returns {boolean} true if button disabled */ - getWorkspaceStatus(): string { - let workspace = this.cheWorkspace.getWorkspaceById(this.workspace.id); - return workspace ? workspace.status : 'unknown'; + isButtonDisabled(): boolean { + const status = this.getWorkspaceStatus(); + return this.isRequestPending || status === WorkspaceStatus.STOPPING; } /** - * Is show run button. - * - * @returns {boolean} + * Returns current status of workspace + * @returns {number} */ - isShowRun(): boolean { - let status = this.getWorkspaceStatus(); - return status !== 'RUNNING' && status !== 'STOPPING' && status !== 'STARTING'; + getWorkspaceStatus(): number { + const workspace = this.cheWorkspace.getWorkspaceById(this.workspaceId); + if (!workspace || !workspace.status) { + return -1; + } + + return WorkspaceStatus[workspace.status]; } /** - * Is stop button disabled. + * Is show run button. * * @returns {boolean} */ - isStopDisabled(): boolean { - let status = this.getWorkspaceStatus(); - return status === 'STOPPING'; + isShowRun(): boolean { + const status = this.getWorkspaceStatus(); + return status !== WorkspaceStatus.RUNNING && status !== WorkspaceStatus.STOPPING && status !== WorkspaceStatus.STARTING; } /** @@ -114,7 +106,7 @@ export class WorkspaceStatusController { * * @param {string} workspaceId */ - updateRecentWorkspace(workspaceId: string): any { + updateRecentWorkspace(workspaceId: string): void { this.$rootScope.$broadcast('recent-workspace:set', workspaceId); } diff --git a/dashboard/src/app/workspaces/list-workspaces/workspace-status-action/workspace-status.directive.ts b/dashboard/src/app/workspaces/list-workspaces/workspace-status-action/workspace-status.directive.ts index 02fd7504ce3e..7b1a461c9981 100644 --- a/dashboard/src/app/workspaces/list-workspaces/workspace-status-action/workspace-status.directive.ts +++ b/dashboard/src/app/workspaces/list-workspaces/workspace-status-action/workspace-status.directive.ts @@ -17,43 +17,22 @@ * @element * * @description - * + * `` defines workspace status component for start/stop workspace. * * @usage - * + * * * @author Oleksii Orel */ -export class CheWorkspaceStatus { - restrict: string; - replace: boolean; - - scope: { - [propName: string]: string +export class CheWorkspaceStatus implements ng.IDirective { + restrict = 'E'; + templateUrl = 'app/workspaces/list-workspaces/workspace-status-action/workspace-status.html'; + bindToController = true; + controller = 'WorkspaceStatusController'; + controllerAs = 'workspaceStatusController'; + scope = { + workspaceId: '=workspaceId', + isRequestPending: '=?' }; - templateUrl: string; - controller: string; - controllerAs: string; - bindToController: boolean; - - /** - * Default constructor. - */ - constructor() { - this.restrict = 'E'; - this.replace = false; - - // scope values - this.scope = { - workspace: '=cheWorkspaceItem' - }; - - this.templateUrl = 'app/workspaces/list-workspaces/workspace-status-action/workspace-status.html'; - - this.controller = 'WorkspaceStatusController'; - this.controllerAs = 'workspaceStatusController'; - this.bindToController = true; - } - } diff --git a/dashboard/src/app/workspaces/list-workspaces/workspace-status-action/workspace-status.html b/dashboard/src/app/workspaces/list-workspaces/workspace-status-action/workspace-status.html index 622e1fbe26d4..0360fbd0a3e8 100644 --- a/dashboard/src/app/workspaces/list-workspaces/workspace-status-action/workspace-status.html +++ b/dashboard/src/app/workspaces/list-workspaces/workspace-status-action/workspace-status.html @@ -10,15 +10,10 @@ Red Hat, Inc. - initial API and implementation --> -

- - +
+
diff --git a/dashboard/src/app/workspaces/list-workspaces/workspace-status-action/workspace-status.styl b/dashboard/src/app/workspaces/list-workspaces/workspace-status-action/workspace-status.styl index abef39016c2c..dcf41f698d0d 100644 --- a/dashboard/src/app/workspaces/list-workspaces/workspace-status-action/workspace-status.styl +++ b/dashboard/src/app/workspaces/list-workspaces/workspace-status-action/workspace-status.styl @@ -1,8 +1,8 @@ -.workspaces-status +.workspace-status vertical-align middle + height inherit color inherit outline none - height inherit - span.disabled + &.disabled span color $disabled-color diff --git a/dashboard/src/components/api/workspace/che-workspace.factory.ts b/dashboard/src/components/api/workspace/che-workspace.factory.ts index de8294eb5f78..4652a04a9b51 100644 --- a/dashboard/src/components/api/workspace/che-workspace.factory.ts +++ b/dashboard/src/components/api/workspace/che-workspace.factory.ts @@ -78,7 +78,7 @@ export class CheWorkspace { /** * Map with promises. */ - private workspaceDetailsByKeyPromise: Map> = new Map(); + private workspacePromises: Map> = new Map(); /** @@ -86,7 +86,7 @@ export class CheWorkspace { * @ngInject for Dependency injection */ constructor($resource: ng.resource.IResourceService, $http: ng.IHttpService, $q: ng.IQService, cheJsonRpcApi: CheJsonRpcApi, - $websocket: any, $location: ng.ILocationService, proxySettings : string, userDashboardConfig: any, + $websocket: any, $location: ng.ILocationService, proxySettings: string, userDashboardConfig: any, lodash: any, cheEnvironmentRegistry: CheEnvironmentRegistry, $log: ng.ILogService, cheBranding: CheBranding, keycloakAuth: any) { this.workspaceStatuses = ['RUNNING', 'STOPPED', 'PAUSED', 'STARTING', 'STOPPING', 'ERROR']; // keep resource @@ -208,7 +208,11 @@ export class CheWorkspace { } }); - let workspaceAgentData = {path: wsAgentLink.url, websocket: wsAgentWebocketLink.url, clientId: this.cheJsonRpcMasterApi.getClientId()}; + let workspaceAgentData = { + path: wsAgentLink.url, + websocket: wsAgentWebocketLink.url, + clientId: this.cheJsonRpcMasterApi.getClientId() + }; let wsagent: CheWorkspaceAgent = new CheWorkspaceAgent(this.$resource, this.$q, this.$websocket, workspaceAgentData); this.workspaceAgents.set(workspaceId, wsagent); return wsagent; @@ -343,12 +347,13 @@ export class CheWorkspace { * @returns {ng.IPromise} */ fetchWorkspaceDetails(workspaceKey: string): ng.IPromise { - if (this.workspaceDetailsByKeyPromise.has(workspaceKey)) { - return this.workspaceDetailsByKeyPromise.get(workspaceKey); + const workspacePromisesKey = 'fetchWorkspaceDetails' + workspaceKey; + if (this.workspacePromises.has(workspacePromisesKey)) { + return this.workspacePromises.get(workspacePromisesKey); } const defer = this.$q.defer(); const promise: ng.IHttpPromise = this.$http.get('/api/workspace/' + workspaceKey); - this.workspaceDetailsByKeyPromise.set(workspaceKey, promise); + this.workspacePromises.set(workspacePromisesKey, promise); promise.then((response: ng.IHttpPromiseCallbackArg) => { const workspace = response.data; @@ -362,7 +367,7 @@ export class CheWorkspace { } defer.reject(error); }).finally(() => { - this.workspaceDetailsByKeyPromise.delete(workspaceKey); + this.workspacePromises.delete(workspacePromisesKey); }); return defer.promise; @@ -511,7 +516,18 @@ export class CheWorkspace { * @returns {ng.IPromise} promise */ startWorkspace(workspaceId: string, envName: string): ng.IPromise { - return this.remoteWorkspaceAPI.startWorkspace({workspaceId: workspaceId, envName: envName}, {}).$promise; + const workspacePromisesKey = 'startWorkspace' + workspaceId; + if (this.workspacePromises.has(workspacePromisesKey)) { + return this.workspacePromises.get(workspacePromisesKey); + } + + const promise = this.remoteWorkspaceAPI.startWorkspace({workspaceId: workspaceId, envName: envName}, {}).$promise; + this.workspacePromises.set(workspacePromisesKey, promise); + promise.finally(() => { + this.workspacePromises.delete(workspacePromisesKey); + }); + + return promise; } /** @@ -529,9 +545,19 @@ export class CheWorkspace { * @returns {ng.IPromise} promise */ stopWorkspace(workspaceId: string): ng.IPromise { - return this.remoteWorkspaceAPI.stopWorkspace({ + const workspacePromisesKey = 'stopWorkspace' + workspaceId; + if (this.workspacePromises.has(workspacePromisesKey)) { + return this.workspacePromises.get(workspacePromisesKey); + } + const promise = this.remoteWorkspaceAPI.stopWorkspace({ workspaceId: workspaceId }, {}).$promise; + this.workspacePromises.set(workspacePromisesKey, promise); + promise.finally(() => { + this.workspacePromises.delete(workspacePromisesKey); + }); + + return promise; } /** From 86dfcd6c3d15372b787e700b700b410c518e491b Mon Sep 17 00:00:00 2001 From: Aleksandr Shmaraiev Date: Tue, 19 Dec 2017 13:57:14 +0200 Subject: [PATCH 12/30] Change content of field in the 'WorkingWithTerminalTest' according to che6-ocp Change the content of 'VIEW_BIN_FOLDER' field in the selenium test 'WorkingWithTerminalTest' according to che-6 ocp platform Add the 'waitTerminalConsole()' to the test method to increase staility --- .../che/selenium/miscellaneous/WorkingWithTerminalTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/miscellaneous/WorkingWithTerminalTest.java b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/miscellaneous/WorkingWithTerminalTest.java index 1ebf3f21da24..cab4427d9a19 100644 --- a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/miscellaneous/WorkingWithTerminalTest.java +++ b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/miscellaneous/WorkingWithTerminalTest.java @@ -59,7 +59,7 @@ public class WorkingWithTerminalTest { private static final String MC_HELP_DIALOG = "This is the main help screen for GNU Midnight Commander."; private static final String MC_USER_MENU_DIALOG = "User menu"; - private static final String[] VIEW_BIN_FOLDER = {"bash", "bunzip2", "bzcat"}; + private static final String[] VIEW_BIN_FOLDER = {"bash", "chmod", "date"}; @Inject private TestWorkspace workspace; @Inject private Ide ide; @@ -342,6 +342,7 @@ public void shouldViewFolderIntoMC() { @Test(priority = 12) public void closeTerminalByExitCommand() { + terminal.waitTerminalConsole(); terminal.typeIntoTerminal("exit" + Keys.ENTER); terminal.waitTerminalIsNotPresent(1); } From c48a525021913447eed148d8fe86d2aa436711ab Mon Sep 17 00:00:00 2001 From: Sergey Skorik Date: Tue, 19 Dec 2017 16:34:47 +0200 Subject: [PATCH 13/30] Selenium: update the ConvertToProjectWithPomFileTest selenium test (#7945) * added method for testing the Editor tab after changing artifactId * added checking in checkEditorTabNameAfterChangingArtifactID() method that after refreshine web page the Editor tab name is not changed --- .../ConvertToProjectWithPomFileTest.java | 60 +++++++++++++------ 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/miscellaneous/ConvertToProjectWithPomFileTest.java b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/miscellaneous/ConvertToProjectWithPomFileTest.java index b732f98ff7ec..67b7f28951d5 100644 --- a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/miscellaneous/ConvertToProjectWithPomFileTest.java +++ b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/miscellaneous/ConvertToProjectWithPomFileTest.java @@ -10,6 +10,11 @@ */ package org.eclipse.che.selenium.miscellaneous; +import static org.eclipse.che.selenium.core.constant.TestProjectExplorerContextMenuConstants.CONVERT_TO_PROJECT; +import static org.eclipse.che.selenium.core.constant.TestProjectExplorerContextMenuConstants.NEW; +import static org.eclipse.che.selenium.core.constant.TestProjectExplorerContextMenuConstants.SubMenuNew.XML_FILE; +import static org.eclipse.che.selenium.core.project.ProjectTemplates.MAVEN_SPRING; + import com.google.inject.Inject; import java.net.URL; import java.nio.file.Paths; @@ -18,8 +23,7 @@ import org.eclipse.che.selenium.core.action.ActionsFactory; import org.eclipse.che.selenium.core.client.TestProjectServiceClient; import org.eclipse.che.selenium.core.constant.TestMenuCommandsConstants; -import org.eclipse.che.selenium.core.constant.TestProjectExplorerContextMenuConstants; -import org.eclipse.che.selenium.core.project.ProjectTemplates; +import org.eclipse.che.selenium.core.utils.WaitUtils; import org.eclipse.che.selenium.core.workspace.TestWorkspace; import org.eclipse.che.selenium.pageobject.AskForValueDialog; import org.eclipse.che.selenium.pageobject.CodenvyEditor; @@ -34,7 +38,7 @@ /** @author Aleksandr Shmaraev */ public class ConvertToProjectWithPomFileTest { - private static final String PROJECT_NAME = NameGenerator.generate("web-spring", 4); + private static final String PROJECT_NAME = NameGenerator.generate("project", 4); private static final String NEW_FOLDER_NAME = "new-folder"; private static final String NEW_MODULE_NAME = "new-module"; private static final String PATH_TO_POM_FILE = PROJECT_NAME + "/" + NEW_MODULE_NAME; @@ -67,24 +71,22 @@ public class ConvertToProjectWithPomFileTest { public void setUp() throws Exception { URL resource = getClass().getResource("/projects/guess-project"); testProjectServiceClient.importProject( - workspace.getId(), - Paths.get(resource.toURI()), - PROJECT_NAME, - ProjectTemplates.MAVEN_SPRING); + workspace.getId(), Paths.get(resource.toURI()), PROJECT_NAME, MAVEN_SPRING); ide.open(workspace); + projectExplorer.waitProjectExplorer(); + projectExplorer.waitItem(PROJECT_NAME); + projectExplorer.selectItem(PROJECT_NAME); + projectExplorer.quickExpandWithJavaScript(); } @Test public void checkConvertToProjectWithPomFile() throws Exception { - projectExplorer.waitProjectExplorer(); - projectExplorer.openItemByPath(PROJECT_NAME); // create a folder and check message if the path is wrong createNewFolder(PROJECT_NAME, NEW_FOLDER_NAME); projectExplorer.selectVisibleItem(NEW_FOLDER_NAME); projectExplorer.openContextMenuByPathSelectedItem(PROJECT_NAME + "/" + NEW_FOLDER_NAME); - projectExplorer.clickOnItemInContextMenu( - TestProjectExplorerContextMenuConstants.CONVERT_TO_PROJECT); + projectExplorer.clickOnItemInContextMenu(CONVERT_TO_PROJECT); wizard.waitOpenProjectConfigForm(); wizard.waitTextParentDirectoryName("/" + PROJECT_NAME); wizard.waitTextProjectNameInput(NEW_FOLDER_NAME); @@ -97,21 +99,43 @@ public void checkConvertToProjectWithPomFile() throws Exception { // create a folder with pom file createNewFolder(PROJECT_NAME, NEW_MODULE_NAME); - createNewFile( - "pom", PATH_TO_POM_FILE, TestProjectExplorerContextMenuConstants.SubMenuNew.XML_FILE); - projectExplorer.waitItemInVisibleArea("pom.xml"); - projectExplorer.openItemByPath(PATH_TO_POM_FILE + "/pom.xml"); + createNewFile("pom", PATH_TO_POM_FILE, XML_FILE); editor.waitActive(); - loader.waitOnClosed(); + editor.waitTabIsPresent("pom.xml"); editor.deleteAllContent(); actionsFactory.createAction(seleniumWebDriver).sendKeys(EXPECTED_TEXT).perform(); editor.waitTextIntoEditor(EXPECTED_TEXT); + + // this timeout is needed for waiting that the Editor tab name of 'pom.xml' file is changed + WaitUtils.sleepQuietly(5); + editor.waitTabIsPresent("pom.xml"); + projectExplorer.waitFolderDefinedTypeOfFolderByPath(PATH_TO_POM_FILE, "simpleFolder"); + editor.closeAllTabs(); seleniumWebDriver.navigate().refresh(); projectExplorer.waitProjectExplorer(); projectExplorer.waitFolderDefinedTypeOfFolderByPath(PATH_TO_POM_FILE, "simpleFolder"); } + @Test + public void checkEditorTabNameAfterChangingArtifactID() { + projectExplorer.openItemByPath(PROJECT_NAME + "/pom.xml"); + editor.waitActive(); + editor.waitTabIsPresent("qa-spring-sample"); + editor.goToCursorPositionVisible(18, 17); + editor.typeTextIntoEditor("new-"); + + // this timeout is needed for waiting that the Editor tab name of 'pom.xml' file is changed + WaitUtils.sleepQuietly(5); + editor.waitTabIsPresent("new-qa-spring-sample"); + + seleniumWebDriver.navigate().refresh(); + projectExplorer.waitItem(PROJECT_NAME + "/pom.xml"); + editor.waitTabIsPresent("new-qa-spring-sample"); + + editor.closeAllTabsByContextMenu(); + } + private void createNewFolder(String path, String folderName) { projectExplorer.selectItem(path); menu.runCommand( @@ -126,10 +150,10 @@ private void createNewFolder(String path, String folderName) { loader.waitOnClosed(); } - private void createNewFile(String name, String pathToFile, String type) throws Exception { + private void createNewFile(String name, String pathToFile, String type) { projectExplorer.selectItem(pathToFile); projectExplorer.openContextMenuByPathSelectedItem(pathToFile); - projectExplorer.clickOnItemInContextMenu(TestProjectExplorerContextMenuConstants.NEW); + projectExplorer.clickOnItemInContextMenu(NEW); projectExplorer.clickOnItemInContextMenu(type); askForValueDialog.waitFormToOpen(); askForValueDialog.typeAndWaitText(name); From da18cd1867210f87a6071ed65930fb47fb8bb775 Mon Sep 17 00:00:00 2001 From: Florent BENOIT Date: Tue, 19 Dec 2017 10:49:28 +0100 Subject: [PATCH 14/30] Allow to use JSInterop on export Change-Id: I37664554064cbe87ec68a8e062e78f34b45d745f Signed-off-by: Florent BENOIT --- ide/che-ide-gwt-app/pom.xml | 3 +++ pom.xml | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/ide/che-ide-gwt-app/pom.xml b/ide/che-ide-gwt-app/pom.xml index 6945115564ea..d946851fd23f 100644 --- a/ide/che-ide-gwt-app/pom.xml +++ b/ide/che-ide-gwt-app/pom.xml @@ -50,6 +50,9 @@ ${gwt.compiler.jvmArgs.Xss} ${gwt.compiler.jvmArgs.Xmx} + + -generateJsInteropExports + diff --git a/pom.xml b/pom.xml index 54c5dd51b911..ae8ab40c656c 100644 --- a/pom.xml +++ b/pom.xml @@ -1877,7 +1877,11 @@ -noprecompile -noincremental + -generateJsInteropExports + + -generateJsInteropExports + ${gwt.compiler.jvmArgs.Xss} ${gwt.compiler.jvmArgs.Xmx} From b4ba12302afcff6d362f7e213d6caf969220d01c Mon Sep 17 00:00:00 2001 From: Ilya Buziuk Date: Fri, 15 Dec 2017 10:54:44 +0100 Subject: [PATCH 15/30] Support of headers to 'HttpJsonRequest'. Adding 'Connection: close' header while checking server availability in 'HttpConnectionServerChecker' Signed-off-by: Ilya Buziuk --- .../api/core/rest/DefaultHttpJsonRequest.java | 26 ++++++++++++++-- .../che/api/core/rest/HttpJsonRequest.java | 22 +++++++++++++ .../core/rest/DefaultHttpJsonRequestTest.java | 31 ++++++++++++++++--- .../hc/HttpConnectionServerChecker.java | 3 ++ 4 files changed, 74 insertions(+), 8 deletions(-) diff --git a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequest.java b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequest.java index 218131de7bf5..612165ce0fa3 100644 --- a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequest.java +++ b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequest.java @@ -68,6 +68,7 @@ public class DefaultHttpJsonRequest implements HttpJsonRequest { private String method; private Object body; private List> queryParams; + private List> headers; private String authorizationHeaderValue; protected DefaultHttpJsonRequest(String url, String method) { @@ -118,6 +119,16 @@ public HttpJsonRequest addQueryParam(@NotNull String name, @NotNull Object value return this; } + public HttpJsonRequest addHeader(@NotNull String name, @NotNull String value) { + requireNonNull(name, "Required non-null header name"); + requireNonNull(value, "Required non-null header value"); + if (headers == null) { + headers = new ArrayList<>(); + } + headers.add(Pair.of(name, value)); + return this; + } + @Override public HttpJsonRequest setAuthorizationHeader(@NotNull String value) { requireNonNull(value, "Required non-null header value"); @@ -149,7 +160,7 @@ public HttpJsonResponse request() if (method == null) { throw new IllegalStateException("Could not perform request, request method wasn't set"); } - return doRequest(timeout, url, method, body, queryParams, authorizationHeaderValue); + return doRequest(timeout, url, method, body, queryParams, authorizationHeaderValue, headers); } /** @@ -182,7 +193,8 @@ protected DefaultHttpJsonResponse doRequest( String method, Object body, List> parameters, - String authorizationHeaderValue) + String authorizationHeaderValue, + List> headers) throws IOException, ServerException, ForbiddenException, NotFoundException, UnauthorizedException, ConflictException, BadRequestException { final String authToken = EnvironmentContext.getCurrent().getSubject().getToken(); @@ -202,6 +214,15 @@ protected DefaultHttpJsonResponse doRequest( final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); conn.setConnectTimeout(timeout > 0 ? timeout : 60000); conn.setReadTimeout(timeout > 0 ? timeout : 60000); + + final boolean hasHeaders = headers != null && !headers.isEmpty(); + + if (hasHeaders) { + for (Pair header : headers) { + conn.setRequestProperty(header.first, header.second); + } + } + try { conn.setRequestMethod(method); // drop a hint for server side that we want to receive application/json @@ -225,7 +246,6 @@ protected DefaultHttpJsonResponse doRequest( output.write(DtoFactory.getInstance().toJson(body).getBytes()); } } - final int responseCode = conn.getResponseCode(); if ((responseCode / 100) != 2) { InputStream in = conn.getErrorStream(); diff --git a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/HttpJsonRequest.java b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/HttpJsonRequest.java index 08f4f36b362a..71be73755ba4 100644 --- a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/HttpJsonRequest.java +++ b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/HttpJsonRequest.java @@ -110,6 +110,16 @@ public interface HttpJsonRequest { */ HttpJsonRequest addQueryParam(@NotNull String name, @NotNull Object value); + /** + * Adds header to the request. + * + * @param name header name + * @param value header value + * @return this request instance + * @throws NullPointerException when either header name or value is null + */ + HttpJsonRequest addHeader(@NotNull String name, @NotNull String value); + /** * Adds authorization header to the request. * @@ -206,4 +216,16 @@ default HttpJsonRequest addQueryParams(@NotNull Map params) { params.forEach(this::addQueryParam); return this; } + + /** + * Adds set of headers to this request. + * + * @param headers map with headers + * @return this request instance + */ + default HttpJsonRequest addHeaders(@NotNull Map headers) { + Objects.requireNonNull(headers, "Required non-null headers"); + headers.forEach(this::addHeader); + return this; + } } diff --git a/core/che-core-api-core/src/test/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequestTest.java b/core/che-core-api-core/src/test/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequestTest.java index ca877bfd54f4..cac0f46ac318 100644 --- a/core/che-core-api-core/src/test/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequestTest.java +++ b/core/che-core-api-core/src/test/java/org/eclipse/che/api/core/rest/DefaultHttpJsonRequestTest.java @@ -103,10 +103,11 @@ public void shouldUseUrlAndMethodFromTheLinks() throws Exception { anyString(), nullable(Object.class), nullable(List.class), - nullable(String.class)); + nullable(String.class), + nullable(List.class)); request.request(); - verify(request).doRequest(0, DEFAULT_URL, "POST", null, null, null); + verify(request).doRequest(0, DEFAULT_URL, "POST", null, null, null, null); } @Test @@ -119,6 +120,7 @@ public void shouldBeAbleToMakeRequest() throws Exception { .setTimeout(10_000_000) .addQueryParam("name", "value") .addQueryParam("name2", "value2") + .addHeader("Connection", "close") .request(); verify(request) @@ -128,7 +130,8 @@ public void shouldBeAbleToMakeRequest() throws Exception { "PUT", body, asList(Pair.of("name", "value"), Pair.of("name2", "value2")), - null); + null, + asList(Pair.of("Connection", "close"))); } @Test @@ -146,6 +149,7 @@ public void shouldBeAbleToUseStringMapAsRequestBody() throws Exception { eq("POST"), mapCaptor.capture(), eq(null), + eq(null), eq(null)); assertTrue(mapCaptor.getValue() instanceof JsonStringMap); assertEquals(mapCaptor.getValue(), body); @@ -164,6 +168,7 @@ public void shouldBeAbleToUseListOfJsonSerializableElementsAsRequestBody() throw eq("POST"), listCaptor.capture(), eq(null), + eq(null), eq(null)); assertTrue(listCaptor.getValue() instanceof JsonArray); assertEquals(listCaptor.getValue(), body); @@ -172,7 +177,7 @@ public void shouldBeAbleToUseListOfJsonSerializableElementsAsRequestBody() throw @Test public void defaultMethodIsGet() throws Exception { request.request(); - verify(request).doRequest(0, DEFAULT_URL, HttpMethod.GET, null, null, null); + verify(request).doRequest(0, DEFAULT_URL, HttpMethod.GET, null, null, null, null); } @Test(expectedExceptions = NullPointerException.class) @@ -216,6 +221,21 @@ public void shouldThrowNullPointerExceptionWhenQueryParamsAreNull() throws Excep new DefaultHttpJsonRequest("http://localhost:8080").addQueryParams(null); } + @Test(expectedExceptions = NullPointerException.class) + public void shouldThrowNullPointerExceptionWhenHeaderNameIsNull() throws Exception { + new DefaultHttpJsonRequest("http://localhost:8080").addHeader(null, "close"); + } + + @Test(expectedExceptions = NullPointerException.class) + public void shouldThrowNullPointerExceptionWhenHeaderValueIsNull() throws Exception { + new DefaultHttpJsonRequest("http://localhost:8080").addHeader("Connection", null); + } + + @Test(expectedExceptions = NullPointerException.class) + public void shouldThrowNullPointerExceptionWhenHeadersAreNull() throws Exception { + new DefaultHttpJsonRequest("http://localhost:8080").addHeaders(null); + } + @Test(expectedExceptions = NullPointerException.class) public void shouldThrowNullPointerExceptionWhenLinkHrefIsNull() throws Exception { new DefaultHttpJsonRequest(createLink("GET", null, null)); @@ -375,6 +395,7 @@ private void prepareResponse(String response) throws Exception { anyString(), nullable(Object.class), nullable(List.class), - nullable(String.class)); + nullable(String.class), + nullable(List.class)); } } diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/hc/HttpConnectionServerChecker.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/hc/HttpConnectionServerChecker.java index 9fa2913f1647..4b2346cb7ff9 100644 --- a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/hc/HttpConnectionServerChecker.java +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/hc/HttpConnectionServerChecker.java @@ -24,6 +24,8 @@ * @author Alexander Garagatyi */ public class HttpConnectionServerChecker extends ServerChecker { + private static final String CONNECTION_HEADER = "Connection"; + private static final String CONNECTION_CLOSE = "close"; private final URL url; public HttpConnectionServerChecker( @@ -46,6 +48,7 @@ public boolean isAvailable() { // TODO consider how much time we should use as a limit httpURLConnection.setConnectTimeout((int) TimeUnit.SECONDS.toMillis(3)); httpURLConnection.setReadTimeout((int) TimeUnit.SECONDS.toMillis(3)); + httpURLConnection.setRequestProperty(CONNECTION_HEADER, CONNECTION_CLOSE); return isConnectionSuccessful(httpURLConnection); } catch (IOException e) { return false; From 434e3f033d57e1123f5476b7befc8a8568f54d82 Mon Sep 17 00:00:00 2001 From: Igor Ohrimenko Date: Tue, 19 Dec 2017 17:18:03 +0200 Subject: [PATCH 16/30] rework selectItemInFileStructure and selectItemInFileStructureByDoubleClick methods in the FileStructure page-object (#7961) --- .../selenium/pageobject/FileStructure.java | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/FileStructure.java b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/FileStructure.java index a7ff044fff6a..baf17ad661b8 100644 --- a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/FileStructure.java +++ b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/FileStructure.java @@ -112,12 +112,8 @@ public void waitExpectedTextInFileStructure(String expText) { loader.waitOnClosed(); new WebDriverWait(seleniumWebDriver, REDRAW_UI_ELEMENTS_TIMEOUT_SEC) .until( - new ExpectedCondition() { - @Override - public Boolean apply(WebDriver driver) { - return getTextFromFileStructurePanel().contains(expText); - } - }); + (ExpectedCondition) + driver -> getTextFromFileStructurePanel().contains(expText)); } /** @@ -165,12 +161,12 @@ public void clickOnIconNodeInFileStructure(String nameNode) { * @param item is the name of the item */ public void selectItemInFileStructureByDoubleClick(String item) { - WebElement fileStructureItem = - new WebDriverWait(seleniumWebDriver, REDRAW_UI_ELEMENTS_TIMEOUT_SEC) - .until( - visibilityOfElementLocated(By.xpath(format(Locators.FILE_STRUCTURE_ITEM, item)))); - fileStructureItem.click(); - actionsFactory.createAction(seleniumWebDriver).doubleClick(fileStructureItem).perform(); + selectItemInFileStructure(item); + actionsFactory + .createAction(seleniumWebDriver) + .moveToElement(getFileStructureItem(item)) + .doubleClick() + .perform(); } /** @@ -189,9 +185,16 @@ public void selectItemInFileStructureByEnter(String item) { * @param item is the name of the item */ public void selectItemInFileStructure(String item) { - new WebDriverWait(seleniumWebDriver, REDRAW_UI_ELEMENTS_TIMEOUT_SEC) - .until(visibilityOfElementLocated(By.xpath(format(Locators.FILE_STRUCTURE_ITEM, item)))) - .click(); + actionsFactory + .createAction(seleniumWebDriver) + .moveToElement(getFileStructureItem(item)) + .click() + .perform(); + } + + private WebElement getFileStructureItem(String item) { + return new WebDriverWait(seleniumWebDriver, REDRAW_UI_ELEMENTS_TIMEOUT_SEC) + .until(visibilityOfElementLocated(By.xpath(format(Locators.FILE_STRUCTURE_ITEM, item)))); } /** From d31151219d7a57c6a7f66f58afa6c8ad77f409c3 Mon Sep 17 00:00:00 2001 From: Vladyslav Zhukovskyi Date: Mon, 18 Dec 2017 15:44:24 +0200 Subject: [PATCH 17/30] Remove redundant event firing Signed-off-by: Vladyslav Zhukovskyi --- .../java/org/eclipse/che/ide/context/AppContextImpl.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/context/AppContextImpl.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/context/AppContextImpl.java index 4b299db46e83..c99d8ee520ec 100644 --- a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/context/AppContextImpl.java +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/context/AppContextImpl.java @@ -58,7 +58,6 @@ import org.eclipse.che.ide.api.workspace.model.WorkspaceImpl; import org.eclipse.che.ide.project.node.SyntheticNode; import org.eclipse.che.ide.resource.Path; -import org.eclipse.che.ide.resources.impl.ResourceDeltaImpl; import org.eclipse.che.ide.resources.impl.ResourceManager; import org.eclipse.che.ide.statepersistance.AppStateManager; import org.eclipse.che.ide.ui.smartTree.data.HasDataObject; @@ -414,10 +413,6 @@ public String getMasterApiEndpoint() { private void clearProjects() { if (!rootProjects.isEmpty()) { - rootProjects.forEach( - project -> - eventBus.fireEvent( - new ResourceChangedEvent(new ResourceDeltaImpl(project, REMOVED)))); rootProjects.clear(); } } From 33feb47ac7aeb1eb3ba9b3d2dac2c258f7ab680b Mon Sep 17 00:00:00 2001 From: Sergey Skorik Date: Tue, 19 Dec 2017 17:41:29 +0200 Subject: [PATCH 18/30] Selenium: add selenium test to check the workspace details of workspace with single machine (#7946) * WorkspaceDetailsTest selenium test splitted to WorkspaceDetailsComposeTest and WorkspaceDetailsSingleMachineTest * created tests added to CheSuite.xml test suite --- .../che/selenium/pageobject/Consoles.java | 17 ++ .../workspaces/WorkspaceOverview.java | 5 + .../workspaces/WorkspaceProjects.java | 28 +- ....java => WorkspaceDetailsComposeTest.java} | 185 +++--------- .../WorkspaceDetailsSingleMachineTest.java | 265 ++++++++++++++++++ .../src/test/resources/suites/CheSuite.xml | 3 +- 6 files changed, 344 insertions(+), 159 deletions(-) rename selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/dashboard/{WorkspaceDetailsTest.java => WorkspaceDetailsComposeTest.java} (55%) create mode 100644 selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/dashboard/WorkspaceDetailsSingleMachineTest.java diff --git a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/Consoles.java b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/Consoles.java index 3e8e1f8223f2..6c1b3217961c 100644 --- a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/Consoles.java +++ b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/Consoles.java @@ -20,10 +20,12 @@ import static org.openqa.selenium.support.ui.ExpectedConditions.textToBePresentInElement; import static org.openqa.selenium.support.ui.ExpectedConditions.textToBePresentInElementLocated; import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOf; +import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfAllElementsLocatedBy; import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated; import com.google.inject.Inject; import com.google.inject.Singleton; +import java.util.List; import org.eclipse.che.selenium.core.SeleniumWebDriver; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; @@ -177,6 +179,21 @@ public void waitReferenceIsNotPresent(String referenceId) { redrawDriverWait.until(invisibilityOfElementLocated(By.id(referenceId))); } + public boolean checkThatServerExists(String serverName) { + List webElements = + loadPageDriverWait.until( + visibilityOfAllElementsLocatedBy( + By.xpath("//div[contains(@id, 'runtime-info-reference-')]"))); + + for (WebElement we : webElements) { + if (we.getText().equals(serverName)) { + return true; + } + } + + return false; + } + public void waitExpectedTextIntoPreviewUrl(String expectedText) { redrawDriverWait.until(textToBePresentInElement(previewUrl, expectedText)); } diff --git a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/dashboard/workspaces/WorkspaceOverview.java b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/dashboard/workspaces/WorkspaceOverview.java index 487defb41b46..4b536c0f5cef 100644 --- a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/dashboard/workspaces/WorkspaceOverview.java +++ b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/dashboard/workspaces/WorkspaceOverview.java @@ -111,6 +111,11 @@ public void clickOnDeleteWorkspace() { .click(); } + public void isDeleteWorkspaceButtonExists() { + new WebDriverWait(seleniumWebDriver, REDRAW_UI_ELEMENTS_TIMEOUT_SEC) + .until(visibilityOf(deleteWorkspaceBtn)); + } + public void waitDownloadWorkspaceJsonFileBtn() { new WebDriverWait(seleniumWebDriver, REDRAW_UI_ELEMENTS_TIMEOUT_SEC) .until(elementToBeClickable(downloadWsJsonBtn)); diff --git a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/dashboard/workspaces/WorkspaceProjects.java b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/dashboard/workspaces/WorkspaceProjects.java index ed4c4e406722..0e0a18f89bb1 100644 --- a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/dashboard/workspaces/WorkspaceProjects.java +++ b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/dashboard/workspaces/WorkspaceProjects.java @@ -17,10 +17,8 @@ import com.google.inject.Inject; import com.google.inject.Singleton; import org.eclipse.che.selenium.core.SeleniumWebDriver; -import org.eclipse.che.selenium.core.utils.WaitUtils; import org.openqa.selenium.By; import org.openqa.selenium.support.PageFactory; -import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; /** @author Musienko Maxim */ @@ -38,8 +36,10 @@ public WorkspaceProjects(SeleniumWebDriver seleniumWebDriver) { private interface Locators { String PROJECT_BY_NAME = "//div[contains(@ng-click, 'projectItem')]/span[text()='%s']"; String DELETE_PROJECT = "//button/span[text()='Delete']"; - String DELETE_IT_PROJECT = "//che-button-primary[@che-button-title='Delete']/button"; + String DELETE_SELECTED_PROJECTS = "//che-button-primary[@che-button-title='Delete']/button"; + String DELETE_IT_PROJECT = "//md-dialog//che-button-primary[@che-button-title='Delete']/button"; String ADD_NEW_PROJECT_BUTTON = "//che-button-primary[@che-button-title='Add Project']/button"; + String PROJECT_CHECKBOX = "//md-checkbox[contains(@aria-label, 'Project %s')]"; } /** @@ -74,7 +74,7 @@ public void waitProjectIsNotPresent(String projectName) { public void openSettingsForProjectByName(String projectName) { new WebDriverWait(seleniumWebDriver, REDRAW_UI_ELEMENTS_TIMEOUT_SEC) .until( - ExpectedConditions.visibilityOfElementLocated( + visibilityOfElementLocated( By.xpath(String.format(Locators.PROJECT_BY_NAME, projectName)))) .click(); } @@ -82,15 +82,20 @@ public void openSettingsForProjectByName(String projectName) { /** click on 'DELETE' button in settings of project */ public void clickOnDeleteProject() { new WebDriverWait(seleniumWebDriver, REDRAW_UI_ELEMENTS_TIMEOUT_SEC) - .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(Locators.DELETE_PROJECT))) + .until(visibilityOfElementLocated(By.xpath(Locators.DELETE_PROJECT))) .click(); } /** click on 'DELETE IT!' button in the confirming window */ public void clickOnDeleteItInDialogWindow() { - WaitUtils.sleepQuietly(1); new WebDriverWait(seleniumWebDriver, REDRAW_UI_ELEMENTS_TIMEOUT_SEC) - .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(Locators.DELETE_IT_PROJECT))) + .until(visibilityOfElementLocated(By.xpath(Locators.DELETE_IT_PROJECT))) + .click(); + } + + public void clickOnDeleteProjectButton() { + new WebDriverWait(seleniumWebDriver, REDRAW_UI_ELEMENTS_TIMEOUT_SEC) + .until(visibilityOfElementLocated(By.xpath(Locators.DELETE_SELECTED_PROJECTS))) .click(); } @@ -100,4 +105,13 @@ public void clickOnAddNewProjectButton() { .until(visibilityOfElementLocated(By.xpath(Locators.ADD_NEW_PROJECT_BUTTON))) .click(); } + + /** click on the Add Project button */ + public void selectProject(String projectName) { + new WebDriverWait(seleniumWebDriver, REDRAW_UI_ELEMENTS_TIMEOUT_SEC) + .until( + visibilityOfElementLocated( + By.xpath(String.format(Locators.PROJECT_CHECKBOX, projectName)))) + .click(); + } } diff --git a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/dashboard/WorkspaceDetailsTest.java b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/dashboard/WorkspaceDetailsComposeTest.java similarity index 55% rename from selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/dashboard/WorkspaceDetailsTest.java rename to selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/dashboard/WorkspaceDetailsComposeTest.java index 3ec6ee75db5c..8782e28a6ec9 100644 --- a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/dashboard/WorkspaceDetailsTest.java +++ b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/dashboard/WorkspaceDetailsComposeTest.java @@ -12,21 +12,15 @@ import static org.eclipse.che.selenium.core.constant.TestStacksConstants.JAVA_MYSQL; import static org.eclipse.che.selenium.core.constant.TestTimeoutsConstants.LOADER_TIMEOUT_SEC; -import static org.eclipse.che.selenium.pageobject.ProjectExplorer.FolderTypes.PROJECT_FOLDER; -import static org.eclipse.che.selenium.pageobject.dashboard.ProjectSourcePage.Template.WEB_JAVA_PETCLINIC; import static org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails.StateWorkspace.RUNNING; import static org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails.StateWorkspace.STOPPED; import static org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails.TabNames.ENV_VARIABLES; -import static org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails.TabNames.INSTALLERS; import static org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails.TabNames.MACHINES; import static org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails.TabNames.OVERVIEW; -import static org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails.TabNames.PROJECTS; -import static org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails.TabNames.SERVERS; -import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; +import com.google.common.collect.ImmutableMap; import com.google.inject.Inject; -import java.util.HashMap; import java.util.Map; import org.eclipse.che.commons.lang.NameGenerator; import org.eclipse.che.selenium.core.SeleniumWebDriver; @@ -35,56 +29,44 @@ import org.eclipse.che.selenium.core.utils.WaitUtils; import org.eclipse.che.selenium.pageobject.Consoles; import org.eclipse.che.selenium.pageobject.Loader; -import org.eclipse.che.selenium.pageobject.NotificationsPopupPanel; import org.eclipse.che.selenium.pageobject.ProjectExplorer; import org.eclipse.che.selenium.pageobject.dashboard.CreateWorkspace; import org.eclipse.che.selenium.pageobject.dashboard.Dashboard; -import org.eclipse.che.selenium.pageobject.dashboard.NavigationBar; -import org.eclipse.che.selenium.pageobject.dashboard.ProjectSourcePage; import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails; import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceEnvVariables; -import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceInstallers; import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceMachines; -import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceProjects; -import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceServers; import org.eclipse.che.selenium.pageobject.dashboard.workspaces.Workspaces; import org.eclipse.che.selenium.pageobject.machineperspective.MachineTerminal; -import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; /** @author Skoryk Serhii */ -public class WorkspaceDetailsTest { +public class WorkspaceDetailsComposeTest { private static final String WORKSPACE = NameGenerator.generate("java-mysql", 4); - private static final String PROJECT_NAME = "web-java-petclinic"; - - private Map installers = new HashMap<>(); - private Map variables = new HashMap<>(); + private static final Map EXPECTED_VARIABLES = + ImmutableMap.of( + "MYSQL_DATABASE", "petclinic", + "MYSQL_PASSWORD", "password", + "MYSQL_ROOT_PASSWORD", "password", + "MYSQL_USER", "petclinic"); @Inject private TestUser testUser; @Inject private ProjectExplorer projectExplorer; @Inject private Loader loader; - @Inject private NavigationBar navigationBar; @Inject private CreateWorkspace createWorkspace; @Inject private Dashboard dashboard; @Inject private WorkspaceDetails workspaceDetails; @Inject private SeleniumWebDriver seleniumWebDriver; @Inject private TestWorkspaceServiceClient workspaceServiceClient; - @Inject private NotificationsPopupPanel notificationsPopupPanel; - @Inject private WorkspaceProjects workspaceProjects; @Inject private Consoles consoles; @Inject private Workspaces workspaces; - @Inject private ProjectSourcePage projectSourcePage; @Inject private WorkspaceMachines workspaceMachines; - @Inject private WorkspaceServers workspaceServers; - @Inject private WorkspaceInstallers workspaceInstallers; @Inject private WorkspaceEnvVariables workspaceEnvVariables; @Inject private MachineTerminal terminal; @BeforeClass public void setUp() throws Exception { - createMaps(); createWsFromJavaMySqlStack(); } @@ -99,10 +81,7 @@ public void workingWithEnvVariables() { // create a new variable, save changes and check it exists workspaceMachines.selectMachine("Environment variables", "dev-machine"); - workspaceEnvVariables.clickOnAddEnvVariableButton(); - workspaceEnvVariables.checkAddNewEnvVarialbleDialogIsOpen(); - workspaceEnvVariables.addNewEnvironmentVariable("logi", "admin"); - workspaceDetails.clickOnAddButtonInDialogWindow(); + createVariable("logi", "admin"); clickOnSaveButton(); assertTrue(workspaceEnvVariables.checkEnvVariableExists("logi")); @@ -112,108 +91,32 @@ public void workingWithEnvVariables() { workspaceEnvVariables.enterEnvVariableName("login"); workspaceDetails.clickOnUpdateButtonInDialogWindow(); clickOnSaveButton(); + assertTrue(workspaceEnvVariables.checkEnvVariableExists("login")); assertTrue(workspaceEnvVariables.checkValueExists("login", "admin")); // delete the variable, save changes and check it is not exists - workspaceEnvVariables.clickOnEnvVariableCheckbox("login"); - workspaceEnvVariables.clickOnDeleteEnvVariableButton("login"); - workspaceDetails.clickOnDeleteButtonInDialogWindow(); + deleteVariable("login", "admin"); clickOnSaveButton(); workspaceEnvVariables.checkValueIsNotExists("login", "admin"); workspaceMachines.selectMachine("Environment variables", "db"); // add variables to 'db' machine, check they exist and save changes - variables.forEach( + EXPECTED_VARIABLES.forEach( (name, value) -> { - loader.waitOnClosed(); - workspaceEnvVariables.clickOnAddEnvVariableButton(); - workspaceEnvVariables.checkAddNewEnvVarialbleDialogIsOpen(); - workspaceEnvVariables.addNewEnvironmentVariable(name, value); - workspaceDetails.clickOnAddButtonInDialogWindow(); + WaitUtils.sleepQuietly(1); + createVariable(name, value); assertTrue(workspaceEnvVariables.checkEnvVariableExists(name)); assertTrue(workspaceEnvVariables.checkValueExists(name, value)); }); clickOnSaveButton(); // delete all variables from the 'db' machine, check they don't exist and save changes - variables.forEach( - (name, value) -> { - workspaceEnvVariables.clickOnDeleteEnvVariableButton(name); - workspaceDetails.clickOnDeleteButtonInDialogWindow(); - workspaceEnvVariables.checkValueIsNotExists(name, value); - }); - - clickOnSaveButton(); - } - - @Test - public void workingWithInstallers() { - workspaceDetails.selectTabInWorkspaceMenu(INSTALLERS); - - // check both versions of the 'Workspace API' installer - assertTrue(workspaceInstallers.isInstallerStateTurnedOn("Workspace API", "1.0.1")); - assertFalse(workspaceInstallers.isInstallerStateTurnedOn("Workspace API", "1.0.0")); - assertTrue(workspaceInstallers.isInstallerStateNotChangeable("Workspace API", "1.0.1")); - assertTrue(workspaceInstallers.isInstallerStateNotChangeable("Workspace API", "1.0.0")); - - // check all needed installers in dev-machine exist - workspaceMachines.selectMachine("Workspace Installers", "dev-machine"); - installers.forEach( - (name, value) -> { - workspaceInstallers.checkInstallerExists(name); - }); - - // switch all installers and save changes - installers.forEach( - (name, value) -> { - Assert.assertEquals(workspaceInstallers.isInstallerStateTurnedOn(name), value); - workspaceInstallers.switchInstallerState(name); - WaitUtils.sleepQuietly(1); - }); - clickOnSaveButton(); - - // switch all installers, save changes and check its states are as previous(by default for the - // Java-MySql stack) - installers.forEach( + EXPECTED_VARIABLES.forEach( (name, value) -> { - workspaceInstallers.switchInstallerState(name); - loader.waitOnClosed(); + deleteVariable(name, value); }); - clickOnSaveButton(); - installers.forEach( - (name, value) -> { - Assert.assertEquals(workspaceInstallers.isInstallerStateTurnedOn(name), value); - }); - } - - @Test - public void workingWithServers() { - workspaceDetails.selectTabInWorkspaceMenu(SERVERS); - - // add a new server to db machine, save changes and check it exists - workspaceMachines.selectMachine("Servers", "db"); - workspaceServers.clickOnAddServerButton(); - workspaceServers.waitAddServerDialogIsOpen(); - workspaceServers.enterReference("agen"); - workspaceServers.enterPort("8080"); - workspaceServers.enterProtocol("https"); - workspaceDetails.clickOnAddButtonInDialogWindow(); - clickOnSaveButton(); - workspaceServers.checkServerExists("agen", "8080"); - // edit the server and check it exists - workspaceServers.clickOnEditServerButton("agen"); - workspaceServers.enterReference("agent"); - workspaceServers.enterPort("80"); - workspaceServers.enterProtocol("http"); - workspaceDetails.clickOnUpdateButtonInDialogWindow(); - workspaceServers.checkServerExists("agent", "80"); - - // delete the server and check it is not exist - workspaceServers.clickOnDeleteServerButton("agent"); - workspaceDetails.clickOnDeleteButtonInDialogWindow(); clickOnSaveButton(); - workspaceServers.checkServerIsNotExists("agent", "80"); } @Test @@ -229,7 +132,7 @@ public void workingWithMachines() { createMachine(machineName); workspaceMachines.clickOnDeleteMachineButton(machineName); workspaceDetails.clickOnCloseButtonInDialogWindow(); - loader.waitOnClosed(); + WaitUtils.sleepQuietly(1); workspaceMachines.clickOnDeleteMachineButton(machineName); workspaceDetails.clickOnDeleteButtonInDialogWindow(); workspaceMachines.checkMachineIsNotExists(machineName); @@ -242,53 +145,21 @@ public void workingWithMachines() { workspaceMachines.clickOnEditNameDialogButton(); workspaceMachines.checkMachineExists("machine"); clickOnSaveButton(); + workspaceMachines.checkMachineExists("machine"); } @Test(priority = 1) - public void workingWithProjects() { - workspaceDetails.selectTabInWorkspaceMenu(PROJECTS); - - // create a new project and save changes - workspaceProjects.clickOnAddNewProjectButton(); - projectSourcePage.selectSample(PROJECT_NAME); - projectSourcePage.clickOnAddProjectButton(); - clickOnSaveButton(); - - // check that project exists(workspace will restart) - workspaceProjects.waitProjectIsPresent(WEB_JAVA_PETCLINIC); - - // start the workspace and check that the new project exists + public void startWorkspaceAndCheckChanges() { + // check that created machine exists in the Process Console tree workspaceDetails.clickOpenInIdeWsBtn(); seleniumWebDriver.switchFromDashboardIframeToIde(); projectExplorer.waitProjectExplorer(); - projectExplorer.waitItem(PROJECT_NAME); - projectExplorer.waitFolderDefinedTypeOfFolderByPath(WEB_JAVA_PETCLINIC, PROJECT_FOLDER); - // check that created machine exists in the Process Console tree + terminal.waitTerminalTab(LOADER_TIMEOUT_SEC); consoles.waitProcessInProcessConsoleTree("machine"); consoles.waitTabNameProcessIsPresent("machine"); } - private void createMaps() { - installers.put("C# language server", false); - installers.put("Exec", true); - installers.put("File sync", false); - installers.put("Git credentials", false); - installers.put("JSON language server", false); - installers.put("PHP language server", false); - installers.put("Python language server", false); - installers.put("Simple Test language server", false); - installers.put("SSH", false); - installers.put("Terminal", true); - installers.put("TypeScript language server", false); - installers.put("Yaml language server", false); - - variables.put("MYSQL_DATABASE", "petclinic"); - variables.put("MYSQL_PASSWORD", "password"); - variables.put("MYSQL_ROOT_PASSWORD", "password"); - variables.put("MYSQL_USER", "petclinic"); - } - private void clickOnSaveButton() { workspaceDetails.clickOnSaveChangesBtn(); dashboard.waitNotificationMessage("Workspace updated"); @@ -309,7 +180,6 @@ private void createWsFromJavaMySqlStack() { createWorkspace.clickOnCreateWorkspaceButton(); seleniumWebDriver.switchFromDashboardIframeToIde(60); - loader.waitOnClosed(); projectExplorer.waitProjectExplorer(); terminal.waitTerminalTab(LOADER_TIMEOUT_SEC); @@ -333,4 +203,17 @@ private void createMachine(String machineName) { workspaceDetails.clickOnAddButtonInDialogWindow(); workspaceMachines.checkMachineExists(machineName); } + + private void createVariable(String varName, String varValue) { + workspaceEnvVariables.clickOnAddEnvVariableButton(); + workspaceEnvVariables.checkAddNewEnvVarialbleDialogIsOpen(); + workspaceEnvVariables.addNewEnvironmentVariable(varName, varValue); + workspaceDetails.clickOnAddButtonInDialogWindow(); + } + + private void deleteVariable(String varName, String varValue) { + workspaceEnvVariables.clickOnDeleteEnvVariableButton(varName); + workspaceDetails.clickOnDeleteButtonInDialogWindow(); + workspaceEnvVariables.checkValueIsNotExists(varName, varValue); + } } diff --git a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/dashboard/WorkspaceDetailsSingleMachineTest.java b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/dashboard/WorkspaceDetailsSingleMachineTest.java new file mode 100644 index 000000000000..fbdffac5ef3b --- /dev/null +++ b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/dashboard/WorkspaceDetailsSingleMachineTest.java @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.selenium.dashboard; + +import static org.eclipse.che.selenium.core.project.ProjectTemplates.MAVEN_SPRING; +import static org.eclipse.che.selenium.pageobject.ProjectExplorer.FolderTypes.PROJECT_FOLDER; +import static org.eclipse.che.selenium.pageobject.dashboard.ProjectSourcePage.Template.CONSOLE_JAVA_SIMPLE; +import static org.eclipse.che.selenium.pageobject.dashboard.ProjectSourcePage.Template.WEB_JAVA_SPRING; +import static org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails.StateWorkspace.RUNNING; +import static org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails.StateWorkspace.STOPPED; +import static org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails.TabNames.INSTALLERS; +import static org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails.TabNames.OVERVIEW; +import static org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails.TabNames.PROJECTS; +import static org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails.TabNames.SERVERS; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import com.google.common.collect.ImmutableMap; +import com.google.inject.Inject; +import java.net.URL; +import java.nio.file.Paths; +import java.util.Map; +import org.eclipse.che.commons.lang.NameGenerator; +import org.eclipse.che.selenium.core.SeleniumWebDriver; +import org.eclipse.che.selenium.core.client.TestProjectServiceClient; +import org.eclipse.che.selenium.core.client.TestWorkspaceServiceClient; +import org.eclipse.che.selenium.core.user.TestUser; +import org.eclipse.che.selenium.core.utils.WaitUtils; +import org.eclipse.che.selenium.core.workspace.TestWorkspace; +import org.eclipse.che.selenium.pageobject.Consoles; +import org.eclipse.che.selenium.pageobject.Loader; +import org.eclipse.che.selenium.pageobject.ProjectExplorer; +import org.eclipse.che.selenium.pageobject.dashboard.Dashboard; +import org.eclipse.che.selenium.pageobject.dashboard.ProjectSourcePage; +import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails; +import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceInstallers; +import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceMachines; +import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceOverview; +import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceProjects; +import org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceServers; +import org.eclipse.che.selenium.pageobject.dashboard.workspaces.Workspaces; +import org.eclipse.che.selenium.pageobject.machineperspective.MachineTerminal; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** @author Skoryk Serhii */ +public class WorkspaceDetailsSingleMachineTest { + private static final String PROJECT_NAME = NameGenerator.generate("project", 4); + private static final Map EXPECTED_INSTALLERS = + ImmutableMap.builder() + .put("C# language server", false) + .put("Exec", false) + .put("File sync", false) + .put("Git credentials", false) + .put("JSON language server", false) + .put("PHP language server", false) + .put("Python language server", false) + .put("Simple Test language server", false) + .put("SSH", false) + .put("Terminal", true) + .put("TypeScript language server", false) + .put("Yaml language server", false) + .build(); + + private String workspaceName; + + @Inject private TestUser testUser; + @Inject private ProjectExplorer projectExplorer; + @Inject private Loader loader; + @Inject private Dashboard dashboard; + @Inject private WorkspaceDetails workspaceDetails; + @Inject private SeleniumWebDriver seleniumWebDriver; + @Inject private TestWorkspaceServiceClient workspaceServiceClient; + @Inject private WorkspaceProjects workspaceProjects; + @Inject private Workspaces workspaces; + @Inject private ProjectSourcePage projectSourcePage; + @Inject private WorkspaceMachines workspaceMachines; + @Inject private WorkspaceServers workspaceServers; + @Inject private WorkspaceInstallers workspaceInstallers; + @Inject private WorkspaceOverview workspaceOverview; + @Inject private MachineTerminal terminal; + @Inject private TestWorkspace testWorkspace; + @Inject private TestProjectServiceClient testProjectServiceClient; + @Inject private Consoles consoles; + + @BeforeClass + public void setUp() throws Exception { + workspaceName = testWorkspace.getName(); + URL resource = + WorkspaceDetailsSingleMachineTest.this.getClass().getResource("/projects/guess-project"); + testProjectServiceClient.importProject( + testWorkspace.getId(), Paths.get(resource.toURI()), PROJECT_NAME, MAVEN_SPRING); + + dashboard.open(); + dashboard.selectWorkspacesItemOnDashboard(); + dashboard.waitToolbarTitleName("Workspaces"); + workspaces.selectWorkspaceItemName(workspaceName); + workspaces.waitToolbarTitleName(workspaceName); + workspaceDetails.selectTabInWorkspaceMenu(OVERVIEW); + workspaceDetails.checkStateOfWorkspace(RUNNING); + workspaceDetails.clickOnStopWorkspace(); + workspaceDetails.checkStateOfWorkspace(STOPPED); + } + + @AfterClass + public void tearDown() throws Exception { + workspaceServiceClient.delete(workspaceName, testUser.getName()); + } + + @Test + public void checkOverviewTab() { + workspaceOverview.checkNameWorkspace(workspaceName); + workspaceOverview.isDeleteWorkspaceButtonExists(); + + // check the Export feature + workspaceOverview.clickExportWorkspaceBtn(); + workspaceOverview.waitClipboardWorkspaceJsonFileBtn(); + workspaceOverview.waitDownloadWorkspaceJsonFileBtn(); + workspaceOverview.clickOnHideWorkspaceJsonFileBtn(); + } + + @Test + public void checkWorkingWithInstallers() { + workspaceDetails.selectTabInWorkspaceMenu(INSTALLERS); + + // check both versions of the 'Workspace API' installer + assertTrue(workspaceInstallers.isInstallerStateTurnedOn("Workspace API", "1.0.1")); + assertFalse(workspaceInstallers.isInstallerStateTurnedOn("Workspace API", "1.0.0")); + assertTrue(workspaceInstallers.isInstallerStateNotChangeable("Workspace API", "1.0.1")); + assertTrue(workspaceInstallers.isInstallerStateNotChangeable("Workspace API", "1.0.0")); + + // check all needed installers in dev-machine exist + workspaceMachines.selectMachine("Workspace Installers", "dev-machine"); + EXPECTED_INSTALLERS.forEach( + (name, value) -> { + workspaceInstallers.checkInstallerExists(name); + }); + + // switch all installers and save changes + EXPECTED_INSTALLERS.forEach( + (name, value) -> { + assertEquals(workspaceInstallers.isInstallerStateTurnedOn(name), value); + workspaceInstallers.switchInstallerState(name); + WaitUtils.sleepQuietly(1); + }); + clickOnSaveButton(); + + // switch all installers, save changes and check its states are as previous(by default for the + // Java stack) + EXPECTED_INSTALLERS.forEach( + (name, value) -> { + workspaceInstallers.switchInstallerState(name); + loader.waitOnClosed(); + }); + clickOnSaveButton(); + EXPECTED_INSTALLERS.forEach( + (name, value) -> { + assertEquals(workspaceInstallers.isInstallerStateTurnedOn(name), value); + }); + } + + @Test + public void checkWorkingWithServers() { + workspaceDetails.selectTabInWorkspaceMenu(SERVERS); + + // add a new server, save changes and check it exists + createServer("agen", "8083", "https"); + + // edit the server and check it exists + workspaceServers.clickOnEditServerButton("agen"); + workspaceServers.enterReference("agent"); + workspaceServers.enterPort("83"); + workspaceServers.enterProtocol("http"); + workspaceDetails.clickOnUpdateButtonInDialogWindow(); + workspaceServers.checkServerExists("agent", "83"); + + // delete the server and check it is not exist + workspaceServers.clickOnDeleteServerButton("agent"); + workspaceDetails.clickOnDeleteButtonInDialogWindow(); + clickOnSaveButton(); + workspaceServers.checkServerIsNotExists("agent", "83"); + + // add a new server which will be checked after the workspace staring + createServer("agent", "8082", "https"); + } + + @Test + public void checkWorkingWithProjects() { + workspaceDetails.selectTabInWorkspaceMenu(PROJECTS); + + // add new project and cancel adding + addNewProject(WEB_JAVA_SPRING); + workspaceDetails.clickOnCancelChangesBtn(); + workspaceProjects.waitProjectIsNotPresent(WEB_JAVA_SPRING); + + // add two projects and save changes + workspaceProjects.clickOnAddNewProjectButton(); + projectSourcePage.selectSample(WEB_JAVA_SPRING); + projectSourcePage.selectSample(CONSOLE_JAVA_SIMPLE); + projectSourcePage.clickOnAddProjectButton(); + clickOnSaveButton(); + + // check that project exists(workspace will restart) + workspaceProjects.waitProjectIsPresent(WEB_JAVA_SPRING); + workspaceProjects.waitProjectIsPresent(CONSOLE_JAVA_SIMPLE); + } + + @Test(priority = 1) + public void startWorkspaceAndCheckChanges() { + // start the workspace and check that the added projects exist + workspaceDetails.clickOpenInIdeWsBtn(); + seleniumWebDriver.switchFromDashboardIframeToIde(); + projectExplorer.waitProjectExplorer(); + projectExplorer.waitItem(PROJECT_NAME); + projectExplorer.waitFolderDefinedTypeOfFolderByPath(PROJECT_NAME, PROJECT_FOLDER); + projectExplorer.waitFolderDefinedTypeOfFolderByPath(CONSOLE_JAVA_SIMPLE, PROJECT_FOLDER); + projectExplorer.waitFolderDefinedTypeOfFolderByPath(WEB_JAVA_SPRING, PROJECT_FOLDER); + + // check that the added "agent" server is existed in the Servers tab + checkServerInServersList("agent"); + } + + private void addNewProject(String projectName) { + workspaceProjects.clickOnAddNewProjectButton(); + projectSourcePage.selectSample(projectName); + projectSourcePage.clickOnAddProjectButton(); + workspaceProjects.waitProjectIsPresent(projectName); + } + + private void clickOnSaveButton() { + workspaceDetails.clickOnSaveChangesBtn(); + dashboard.waitNotificationMessage("Workspace updated"); + dashboard.waitNotificationIsClosed(); + } + + private void createServer(String serverName, String serverPort, String serverProtocol) { + workspaceServers.clickOnAddServerButton(); + workspaceServers.waitAddServerDialogIsOpen(); + workspaceServers.enterReference(serverName); + workspaceServers.enterPort(serverPort); + workspaceServers.enterProtocol(serverProtocol); + workspaceDetails.clickOnAddButtonInDialogWindow(); + clickOnSaveButton(); + workspaceServers.checkServerExists(serverName, serverPort); + } + + private void checkServerInServersList(String serverName) { + consoles.clickOnPlusMenuButton(); + consoles.clickOnServerItemInContextMenu(); + consoles.waitProcessInProcessConsoleTree("Servers"); + consoles.waitTabNameProcessIsPresent("Servers"); + consoles.waitExpectedTextIntoServerTableCation("Servers of dev-machine:"); + assertTrue(consoles.checkThatServerExists(serverName)); + } +} diff --git a/selenium/che-selenium-test/src/test/resources/suites/CheSuite.xml b/selenium/che-selenium-test/src/test/resources/suites/CheSuite.xml index a663b1a6dfbb..8f0a940a82f3 100644 --- a/selenium/che-selenium-test/src/test/resources/suites/CheSuite.xml +++ b/selenium/che-selenium-test/src/test/resources/suites/CheSuite.xml @@ -28,7 +28,8 @@ - + + From 3da22f62471fbb931af58d971e38027a9e981eb0 Mon Sep 17 00:00:00 2001 From: Eugene Ivantsov Date: Wed, 20 Dec 2017 09:41:07 +0200 Subject: [PATCH 19/30] Make sure traefik runs in an openshift workspace (#7955) * Make sure traefik run in an openshift workspace * Make sure traefik run in an openshift workspace --- dockerfiles/dev/Dockerfile | 14 ++++++------- dockerfiles/dev/entrypoint.sh | 39 +++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 7 deletions(-) create mode 100755 dockerfiles/dev/entrypoint.sh diff --git a/dockerfiles/dev/Dockerfile b/dockerfiles/dev/Dockerfile index dce64517dcd6..a485efb43834 100644 --- a/dockerfiles/dev/Dockerfile +++ b/dockerfiles/dev/Dockerfile @@ -43,7 +43,6 @@ RUN mkdir $HOME/.m2 && \ USER user - ENV LD_LIBRARY_PATH=/opt/rh/rh-nodejs6/root/usr/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} \ PYTHONPATH=/opt/rh/rh-nodejs6/root/usr/lib/python2.7/site-packages${PYTHONPATH:+:${PYTHONPATH}} \ MANPATH=/opt/rh/rh-nodejs6/root/usr/share/man:$MANPATH \ @@ -57,17 +56,18 @@ ENV LD_LIBRARY_PATH=/opt/rh/rh-nodejs6/root/usr/lib64${LD_LIBRARY_PATH:+:${LD_LI ENV PATH=$HOME/node_modules/.bin/:$HOME/.npm-global/bin/:$GOPATH/bin:$M2_HOME/bin:/opt/rh/rh-nodejs6/root/usr/bin:/usr/local/go/bin:$PATH - RUN mkdir /home/user/traefik ;\ wget -O /home/user/traefik/traefik "https://github.com/containous/traefik/releases/download/v1.4.3/traefik_linux-amd64"; \ chmod +x /home/user/traefik/traefik COPY traefik.toml /home/user/traefik/ - - -RUN sudo mkdir /var/run/sshd -RUN sudo ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N '' && \ +ADD entrypoint.sh /home/user/entrypoint.sh +RUN sudo chgrp -R 0 ~/traefik && \ + sudo chmod -R g+rwX ~/traefik && \ + sudo mkdir /var/run/sshd && \ + sudo ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N '' && \ sudo ssh-keygen -t rsa -f /etc/ssh/ssh_host_ecdsa_key -N '' && \ sudo ssh-keygen -t rsa -f /etc/ssh/ssh_host_ed25519_key -N '' && \ npm install -g typescript@2.5.3 typescript-language-server@0.1.4 - WORKDIR /projects +ENTRYPOINT ["/home/user/entrypoint.sh"] +CMD tail -f /dev/null diff --git a/dockerfiles/dev/entrypoint.sh b/dockerfiles/dev/entrypoint.sh new file mode 100755 index 000000000000..0c34c50a2a5f --- /dev/null +++ b/dockerfiles/dev/entrypoint.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Copyright (c) 2012-2017 Red Hat, Inc. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Red Hat, Inc.- initial API and implementation + +set -e + +export USER_ID=$(id -u) +export GROUP_ID=$(id -g) + +if ! grep -Fq "${USER_ID}" /etc/passwd; then + # current user is an arbitrary + # user (its uid is not in the + # container /etc/passwd). Let's fix that + cat ${HOME}/passwd.template | \ + sed "s/\${USER_ID}/${USER_ID}/g" | \ + sed "s/\${GROUP_ID}/${GROUP_ID}/g" | \ + sed "s/\${HOME}/\/home\/user/g" > /etc/passwd + + cat ${HOME}/group.template | \ + sed "s/\${USER_ID}/${USER_ID}/g" | \ + sed "s/\${GROUP_ID}/${GROUP_ID}/g" | \ + sed "s/\${HOME}/\/home\/user/g" > /etc/group +fi + +is_current_user_sudoer() { + sudo -n true > /dev/null 2>&1 +} + + +if ! is_current_user_sudoer; then + sed -i "s/che-host/che-host.eclipse-che.svc/g" /home/user/traefik/traefik.toml +fi +exec "$@" From 1aec57c26ab1a6f11238c6271471e66f4eb8f60c Mon Sep 17 00:00:00 2001 From: Igor Vinokur Date: Wed, 20 Dec 2017 08:00:34 +0000 Subject: [PATCH 20/30] CHE-6330: Line should appear in the middle of the editor after setCursorPosition() (#7920) --- .../editor/orion/client/OrionDocument.java | 7 ++++++- .../orion/client/jso/OrionEditorOverlay.java | 4 ++++ .../jso/OrionTextViewShowOptionsOverlay.java | 20 +++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/ide/che-core-orion-editor/src/main/java/org/eclipse/che/ide/editor/orion/client/OrionDocument.java b/ide/che-core-orion-editor/src/main/java/org/eclipse/che/ide/editor/orion/client/OrionDocument.java index 49c36ac19719..abf90a80d0c8 100644 --- a/ide/che-core-orion-editor/src/main/java/org/eclipse/che/ide/editor/orion/client/OrionDocument.java +++ b/ide/che-core-orion-editor/src/main/java/org/eclipse/che/ide/editor/orion/client/OrionDocument.java @@ -10,6 +10,8 @@ */ package org.eclipse.che.ide.editor.orion.client; +import static org.eclipse.che.ide.editor.orion.client.jso.OrionTextViewShowOptionsOverlay.ViewAnchorValue.CENTER; + import com.google.web.bindery.event.shared.HandlerRegistration; import org.eclipse.che.ide.api.editor.document.AbstractDocument; import org.eclipse.che.ide.api.editor.document.Document; @@ -30,6 +32,7 @@ import org.eclipse.che.ide.editor.orion.client.jso.OrionTextModelOverlay; import org.eclipse.che.ide.editor.orion.client.jso.OrionTextModelOverlay.EventHandler; import org.eclipse.che.ide.editor.orion.client.jso.OrionTextViewOverlay; +import org.eclipse.che.ide.editor.orion.client.jso.OrionTextViewShowOptionsOverlay; /** * The implementation of {@link Document} for Orion. @@ -160,7 +163,9 @@ public TextPosition getCursorPosition() { @Override public void setCursorPosition(final TextPosition position) { - this.editorOverlay.setCaretOffset(getIndexFromPosition(position)); + OrionTextViewShowOptionsOverlay showOptionsOverlay = OrionTextViewShowOptionsOverlay.create(); + showOptionsOverlay.setViewAnchor(CENTER.getValue()); + this.editorOverlay.setCaretOffset(getIndexFromPosition(position), showOptionsOverlay); } public int getCursorOffset() { diff --git a/ide/che-core-orion-editor/src/main/java/org/eclipse/che/ide/editor/orion/client/jso/OrionEditorOverlay.java b/ide/che-core-orion-editor/src/main/java/org/eclipse/che/ide/editor/orion/client/jso/OrionEditorOverlay.java index 8122ab8f1cda..d6334c33968e 100644 --- a/ide/che-core-orion-editor/src/main/java/org/eclipse/che/ide/editor/orion/client/jso/OrionEditorOverlay.java +++ b/ide/che-core-orion-editor/src/main/java/org/eclipse/che/ide/editor/orion/client/jso/OrionEditorOverlay.java @@ -60,6 +60,10 @@ public final native void setCaretOffset(int offset) /*-{ this.setCaretOffset(offset, true); }-*/; + public final native void setCaretOffset(int offset, OrionTextViewShowOptionsOverlay show) /*-{ + this.setCaretOffset(offset, show); + }-*/; + public final native int getCaretOffset() /*-{ return this.getCaretOffset(); }-*/; diff --git a/ide/che-core-orion-editor/src/main/java/org/eclipse/che/ide/editor/orion/client/jso/OrionTextViewShowOptionsOverlay.java b/ide/che-core-orion-editor/src/main/java/org/eclipse/che/ide/editor/orion/client/jso/OrionTextViewShowOptionsOverlay.java index e4723037231b..22e83d6468e9 100644 --- a/ide/che-core-orion-editor/src/main/java/org/eclipse/che/ide/editor/orion/client/jso/OrionTextViewShowOptionsOverlay.java +++ b/ide/che-core-orion-editor/src/main/java/org/eclipse/che/ide/editor/orion/client/jso/OrionTextViewShowOptionsOverlay.java @@ -14,6 +14,22 @@ public class OrionTextViewShowOptionsOverlay extends JavaScriptObject { + public enum ViewAnchorValue { + TOP("top"), + BOTTOM("bottom"), + CENTER("center"); + + private final String value; + + ViewAnchorValue(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + protected OrionTextViewShowOptionsOverlay() {} public final native String getScrollPolicy() /*-{ @@ -47,4 +63,8 @@ public final native String getViewAnchorOffset() /*-{ public final native void setViewAnchorOffset(final String newValue) /*-{ this.viewAnchorOffset = newValue; }-*/; + + public static native OrionTextViewShowOptionsOverlay create() /*-{ + return {}; + }-*/; } From 059b2e3f4a3172b3e0a0fa858d5bd8f7a8dca3b3 Mon Sep 17 00:00:00 2001 From: Oleksandr Andriienko Date: Wed, 20 Dec 2017 10:00:59 +0200 Subject: [PATCH 21/30] CHE-5564: Fix encoding for full text search. (#7864) Signed-off-by: Oleksandr Andriienko --- .../che/ide/api/project/ProjectServiceClientImpl.java | 5 +++-- .../org/eclipse/che/ide/search/FullTextSearchPresenter.java | 4 +--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/project/ProjectServiceClientImpl.java b/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/project/ProjectServiceClientImpl.java index cae7d4c8219a..8499b753a6da 100644 --- a/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/project/ProjectServiceClientImpl.java +++ b/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/project/ProjectServiceClientImpl.java @@ -14,6 +14,7 @@ import static com.google.gwt.http.client.RequestBuilder.DELETE; import static com.google.gwt.http.client.RequestBuilder.PUT; import static com.google.gwt.http.client.URL.encodePathSegment; +import static com.google.gwt.http.client.URL.encodeQueryString; import static org.eclipse.che.ide.MimeType.APPLICATION_JSON; import static org.eclipse.che.ide.rest.HTTPHeader.ACCEPT; import static org.eclipse.che.ide.rest.HTTPHeader.CONTENT_TYPE; @@ -146,10 +147,10 @@ public Promise search(QueryExpression expression) { StringBuilder queryParameters = new StringBuilder(); if (expression.getName() != null && !expression.getName().isEmpty()) { - queryParameters.append("&name=").append(expression.getName()); + queryParameters.append("&name=").append(encodeQueryString(expression.getName())); } if (expression.getText() != null && !expression.getText().isEmpty()) { - queryParameters.append("&text=").append(expression.getText()); + queryParameters.append("&text=").append(encodeQueryString(expression.getText())); } if (expression.getMaxItems() == 0) { expression.setMaxItems( diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/search/FullTextSearchPresenter.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/search/FullTextSearchPresenter.java index 8ae863c73610..584fa13dd47e 100644 --- a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/search/FullTextSearchPresenter.java +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/search/FullTextSearchPresenter.java @@ -31,7 +31,6 @@ public class FullTextSearchPresenter implements FullTextSearchView.ActionDelegate { public static final int SEARCH_RESULT_ITEMS = 30; - private static final String URL_ENCODED_BACKSLASH = "%5C"; private static final String AND_OPERATOR = "AND"; private final FullTextSearchView view; @@ -93,7 +92,6 @@ public void search(final String text) { private String prepareQuery(String text) { StringBuilder sb = new StringBuilder(); for (char character : text.toCharArray()) { - // Escape those characters that QueryParser expects to be escaped if (character == '\\' || character == '+' || character == '-' @@ -113,7 +111,7 @@ private String prepareQuery(String text) { || character == '|' || character == '&' || character == '/') { - sb.append(URL_ENCODED_BACKSLASH); + sb.append("\\"); } sb.append(character); } From e98c9e8094d4af9a811e2c39900fe3b2dc1cbc2d Mon Sep 17 00:00:00 2001 From: Sergey Skorik Date: Wed, 20 Dec 2017 10:09:34 +0200 Subject: [PATCH 22/30] added waiting that test workspace is stopping after renaming it in ProjectStateAfterRenameWorkspaceTest selenium test (#7944) --- .../workspaces/ProjectStateAfterRenameWorkspaceTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/workspaces/ProjectStateAfterRenameWorkspaceTest.java b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/workspaces/ProjectStateAfterRenameWorkspaceTest.java index bfb7ce12dcbe..bb4b859dcdd1 100644 --- a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/workspaces/ProjectStateAfterRenameWorkspaceTest.java +++ b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/workspaces/ProjectStateAfterRenameWorkspaceTest.java @@ -12,6 +12,7 @@ import static org.eclipse.che.selenium.core.constant.TestWorkspaceConstants.RUNNING_WORKSPACE_MESS; import static org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails.StateWorkspace.RUNNING; +import static org.eclipse.che.selenium.pageobject.dashboard.workspaces.WorkspaceDetails.StateWorkspace.STOPPING; import static org.testng.Assert.fail; import com.google.inject.Inject; @@ -96,6 +97,7 @@ public void checkProjectAfterRenameWs() throws Exception { workspaces.selectWorkspaceItemName(testWorkspace.getName()); workspaceOverview.enterNameWorkspace(WORKSPACE_NEW_NAME); workspaceDetails.clickOnSaveChangesBtn(); + workspaceDetails.checkStateOfWorkspace(STOPPING); workspaceDetails.checkStateOfWorkspace(RUNNING); workspaceOverview.checkNameWorkspace(WORKSPACE_NEW_NAME); From 9be8ccb8f79cb40a068a6940d68d3b0e5aed49e6 Mon Sep 17 00:00:00 2001 From: Aleksandr Shmaraiev Date: Tue, 19 Dec 2017 17:37:02 +0200 Subject: [PATCH 23/30] Add 'Assert.fail()' to the 'JavaTestPluginJunit4Test' related to known issue --- .../selenium/testrunner/JavaTestPluginJunit4Test.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/testrunner/JavaTestPluginJunit4Test.java b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/testrunner/JavaTestPluginJunit4Test.java index f006e68805f3..d8f7a2522dd7 100644 --- a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/testrunner/JavaTestPluginJunit4Test.java +++ b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/testrunner/JavaTestPluginJunit4Test.java @@ -17,6 +17,7 @@ import static org.eclipse.che.selenium.pageobject.plugins.JavaTestRunnerPluginConsole.JunitMethodsState.IGNORED; import static org.eclipse.che.selenium.pageobject.plugins.JavaTestRunnerPluginConsole.JunitMethodsState.PASSED; import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; import com.google.inject.Inject; import java.nio.file.Paths; @@ -35,6 +36,7 @@ import org.eclipse.che.selenium.pageobject.ProjectExplorer; import org.eclipse.che.selenium.pageobject.intelligent.CommandsPalette; import org.eclipse.che.selenium.pageobject.plugins.JavaTestRunnerPluginConsole; +import org.openqa.selenium.TimeoutException; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -118,7 +120,14 @@ public void shouldExecuteJUnit4TestClassWithDifferentStatuses() throws Interrupt pluginConsole.waitFqnOfTesClassInResultTree("org.eclipse.che.examples.AppOneTest"); pluginConsole.waitMethodMarkedAsPassed("shouldSuccessOfAppOne"); - pluginConsole.waitMethodMarkedAsFailed("shouldFailOfAppOne"); + + try { + pluginConsole.waitMethodMarkedAsFailed("shouldFailOfAppAnother"); + } catch (TimeoutException ex) { + // remove try-catch block after issue has been resolved + fail("Known issue https://github.com/eclipse/che/issues/7338", ex); + } + pluginConsole.waitMethodMarkedAsIgnored("shouldBeIgnoredOfAppOne"); assertTrue(pluginConsole.getAllNamesOfMethodsMarkedDefinedStatus(PASSED).size() == 1); assertTrue(pluginConsole.getAllNamesOfMethodsMarkedDefinedStatus(FAILED).size() == 1); From f7a886e42eb10fde251030acc6414d877d0d1d5b Mon Sep 17 00:00:00 2001 From: Sergey Skorik Date: Wed, 20 Dec 2017 10:10:46 +0200 Subject: [PATCH 24/30] changed issue url in try/catch block of WorkingWithTerminalTest selenium test (#7943) --- .../che/selenium/miscellaneous/WorkingWithTerminalTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/miscellaneous/WorkingWithTerminalTest.java b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/miscellaneous/WorkingWithTerminalTest.java index cab4427d9a19..5cf967a3a500 100644 --- a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/miscellaneous/WorkingWithTerminalTest.java +++ b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/miscellaneous/WorkingWithTerminalTest.java @@ -164,7 +164,7 @@ public void shouldScrollIntoTerminal() throws InterruptedException { } catch (TimeoutException ex) { // remove try-catch block after issue has been resolved - fail("Known issue https://github.com/eclipse/che/issues/7592", ex); + fail("Known issue https://github.com/eclipse/che-lib/issues/57", ex); } terminal.moveDownListTerminal(".dockerenv"); @@ -185,7 +185,7 @@ public void shouldResizeTerminal() { } } catch (TimeoutException ex) { // remove try-catch block after issue has been resolved - fail("Known issue https://github.com/eclipse/che/issues/7592", ex); + fail("Known issue https://github.com/eclipse/che-lib/issues/57", ex); } terminal.waitExpectedTextNotPresentTerminal(".dockerenv"); @@ -226,7 +226,7 @@ public void shouldNavigateToMC() { } } catch (TimeoutException ex) { // remove try-catch block after issue has been resolved - fail("Known issue https://github.com/eclipse/che/issues/7592", ex); + fail("Known issue https://github.com/eclipse/che-lib/issues/57", ex); } terminal.typeIntoTerminal(Keys.F10.toString()); From 28ca6c5415705e36501ba34a2120d99e535f7739 Mon Sep 17 00:00:00 2001 From: Igor Ohrimenko Date: Wed, 20 Dec 2017 10:39:48 +0200 Subject: [PATCH 25/30] Refactor ProjectExplorer page-object in the selenium tests (#7631) --- ...stProjectExplorerContextMenuConstants.java | 65 +-- .../selenium/pageobject/ProjectExplorer.java | 421 ++++++++++-------- ...tocompleteFeaturesInTheTestFolderTest.java | 1 + 3 files changed, 275 insertions(+), 212 deletions(-) diff --git a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/core/constant/TestProjectExplorerContextMenuConstants.java b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/core/constant/TestProjectExplorerContextMenuConstants.java index c4f210fabb42..a8f5e5fc8057 100644 --- a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/core/constant/TestProjectExplorerContextMenuConstants.java +++ b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/core/constant/TestProjectExplorerContextMenuConstants.java @@ -14,49 +14,52 @@ public final class TestProjectExplorerContextMenuConstants { /** First level context menu items */ - public static final String NEW = "contextMenu/New"; + public static final String NEW = "gwt-debug-contextMenu/newGroup"; - public static final String COMMANDS = "contextMenu/Commands"; - public static final String PREVIEW = "contextMenu/Preview"; - public static final String SHOW_REFERENCES = "contextMenu/Show References"; + public static final String COMMANDS = "gwt-debug-contextMenu/commandsActionGroup"; + public static final String PREVIEW = "gwt-debug-contextMenu/previewHTML"; + public static final String SHOW_REFERENCES = "gwt-debug-contextMenu/showReference"; public static final String GO_INTO = "gwt-debug-contextMenu/goInto"; - public static final String GO_BACK = "contextMenu/Go Back"; - public static final String CUT = "contextMenu/Cut"; - public static final String PASTE = "contextMenu/Paste"; - public static final String RENAME = "contextMenu/Rename..."; - public static final String DELETE = "contextMenu/Delete..."; - public static final String DOWNLOAD = "contextMenu/Download..."; - public static final String CONVERT_TO_PROJECT = "contextMenu/Convert To Project"; - public static final String BUILD_PATH = "contextMenu/Build Path"; - public static final String EDIT = "contextMenu/Edit file"; - public static final String MAVEN = "contextMenu/Maven"; + public static final String GO_BACK = "gwt-debug-contextMenu/goInto"; + public static final String CUT = "gwt-debug-contextMenu/cut"; + public static final String PASTE = "gwt-debug-contextMenu/paste"; + public static final String RENAME = "gwt-debug-contextMenu/renameResource"; + public static final String DELETE = "gwt-debug-contextMenu/deleteItem"; + public static final String DOWNLOAD = "gwt-debug-contextMenu/downloadItemAction"; + public static final String CONVERT_TO_PROJECT = "gwt-debug-contextMenu/convertFolderToProject"; + public static final String BUILD_PATH = "gwt-debug-contextMenu/markDirectoryAsSourceGroup"; + public static final String EDIT = "gwt-debug-contextMenu/editFile"; + public static final String MAVEN = "gwt-debug-contextMenu/mavenGroupContextMenu"; public static final String REFRESH = "gwt-debug-contextMenu/refreshPathAction"; - public static final String REIMPORT = "contextMenu/Maven/Reimport"; + public static final String REIMPORT = + "gwt-debug-contextMenu/Maven/reimportMavenDependenciesAction"; public static final String TEST = "gwt-debug-contextMenu/TestingContextGroup"; /** Submenu for new items */ public static final class SubMenuNew { - public static final String JAVA_CLASS = "contextMenu/New/Java Class"; - public static final String JAVA_PACKAGE = "contextMenu/New/Java Package"; - public static final String FILE = "contextMenu/New/File"; - public static final String FOLDER = "contextMenu/New/Folder"; - public static final String XML_FILE = "contextMenu/New/XML File"; - public static final String CSS_FILE = "contextMenu/New/CSS File"; - public static final String LESS_FILE = "contextMenu/New/Less File"; - public static final String HTML_FILE = "contextMenu/New/HTML File"; - public static final String JAVASCRIPT_FILE = "contextMenu/New/JavaScript File"; - public static final String PYTHON_FILE = "contextMenu/New/Python File"; - public static final String C_FILE = "contextMenu/New/New C File"; - public static final String C_PLUS_PLUS_FILE = "contextMenu/New/New C++ File"; - public static final String H_FILE = "contextMenu/New/New H File"; + public static final String JAVA_CLASS = "gwt-debug-contextMenu/New/newJavaClass"; + public static final String JAVA_PACKAGE = "gwt-debug-contextMenu/New/newJavaPackage"; + public static final String FILE = "gwt-debug-contextMenu/New/newFile"; + public static final String FOLDER = "gwt-debug-contextMenu/New/newFolder"; + public static final String XML_FILE = "gwt-debug-contextMenu/New/newXmlFile"; + public static final String CSS_FILE = "gwt-debug-contextMenu/New/newCssFile"; + public static final String LESS_FILE = "gwt-debug-contextMenu/New/newLessFile"; + public static final String HTML_FILE = "gwt-debug-contextMenu/New/newHtmlFile"; + public static final String JAVASCRIPT_FILE = "gwt-debug-contextMenu/New/newJavaScriptFile"; + public static final String PYTHON_FILE = "gwt-debug-contextMenu/New/pythonFile"; + public static final String C_FILE = "gwt-debug-contextMenu/New/newCFile"; + public static final String C_PLUS_PLUS_FILE = "gwt-debug-contextMenu/New/newCppFile"; + public static final String H_FILE = "gwt-debug-contextMenu/New/newHFile"; } /** Submenu for Build Path Configuration (use for Java project only) */ public static final class SubMenuBuildPath { - public static final String USE_AS_SOURCE_FOLDER = "contextMenu/Build Path/Use as Source Folder"; + public static final String USE_AS_SOURCE_FOLDER = + "gwt-debug-contextMenu/Build Path/markDirectoryAsSource"; public static final String UNMARK_AS_SOURCE_FOLDER = - "contextMenu/Build Path/Unmark as Source Folder"; - public static final String CONFIGURE_CLASSPATH = "contextMenu/Build Path/Configure Classpath"; + "gwt-debug-contextMenu/Build Path/unmarkDirectoryAsSource"; + public static final String CONFIGURE_CLASSPATH = + "gwt-debug-contextMenu/Build Path/projectProperties"; } /** Submenu for Test Runner */ diff --git a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/ProjectExplorer.java b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/ProjectExplorer.java index 670293d93908..a1ca6bdf7b54 100644 --- a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/ProjectExplorer.java +++ b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/ProjectExplorer.java @@ -10,25 +10,45 @@ */ package org.eclipse.che.selenium.pageobject; +import static java.util.Arrays.asList; +import static java.util.stream.Collectors.toList; +import static org.eclipse.che.selenium.core.constant.TestProjectExplorerContextMenuConstants.COMMANDS; import static org.eclipse.che.selenium.core.constant.TestTimeoutsConstants.ELEMENT_TIMEOUT_SEC; import static org.eclipse.che.selenium.core.constant.TestTimeoutsConstants.EXPECTED_MESS_IN_CONSOLE_SEC; import static org.eclipse.che.selenium.core.constant.TestTimeoutsConstants.LOADER_TIMEOUT_SEC; import static org.eclipse.che.selenium.core.constant.TestTimeoutsConstants.LOAD_PAGE_TIMEOUT_SEC; -import static org.eclipse.che.selenium.core.constant.TestTimeoutsConstants.MULTIPLE; import static org.eclipse.che.selenium.core.constant.TestTimeoutsConstants.REDRAW_UI_ELEMENTS_TIMEOUT_SEC; import static org.eclipse.che.selenium.core.constant.TestTimeoutsConstants.WIDGET_TIMEOUT_SEC; +import static org.eclipse.che.selenium.core.utils.WaitUtils.sleepQuietly; +import static org.eclipse.che.selenium.pageobject.ProjectExplorer.Locators.ALL_PROJECTS_XPATH; +import static org.eclipse.che.selenium.pageobject.ProjectExplorer.Locators.CONTEXT_MENU_ID; +import static org.eclipse.che.selenium.pageobject.ProjectExplorer.Locators.EXPLORER_RIGHT_TAB_ID; +import static org.eclipse.che.selenium.pageobject.ProjectExplorer.Locators.PROJECT_EXPLORER_TAB_IN_THE_LEFT_PANEL; +import static org.eclipse.che.selenium.pageobject.ProjectExplorer.Locators.PROJECT_EXPLORER_TREE_ITEMS; +import static org.eclipse.che.selenium.pageobject.ProjectExplorer.ProjectExplorerOptionsMenuItem.COLLAPSE_ALL; import static org.eclipse.che.selenium.pageobject.ProjectExplorer.ProjectExplorerOptionsMenuItem.REFRESH_MAIN; +import static org.eclipse.che.selenium.pageobject.ProjectExplorer.ProjectExplorerOptionsMenuItem.REVEAL_RESOURCE; +import static org.openqa.selenium.Keys.ARROW_DOWN; +import static org.openqa.selenium.Keys.CONTROL; +import static org.openqa.selenium.Keys.ENTER; +import static org.openqa.selenium.Keys.F6; +import static org.openqa.selenium.Keys.LEFT; +import static org.openqa.selenium.Keys.RIGHT; +import static org.openqa.selenium.Keys.SHIFT; +import static org.openqa.selenium.Keys.UP; +import static org.openqa.selenium.support.ui.ExpectedConditions.invisibilityOfElementLocated; +import static org.openqa.selenium.support.ui.ExpectedConditions.not; +import static org.openqa.selenium.support.ui.ExpectedConditions.presenceOfAllElementsLocatedBy; +import static org.openqa.selenium.support.ui.ExpectedConditions.presenceOfNestedElementLocatedBy; +import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOf; +import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfAllElementsLocatedBy; +import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated; import com.google.inject.Inject; import com.google.inject.Singleton; -import java.util.Arrays; import java.util.List; -import java.util.stream.Collectors; import org.eclipse.che.selenium.core.SeleniumWebDriver; import org.eclipse.che.selenium.core.action.ActionsFactory; -import org.eclipse.che.selenium.core.constant.TestProjectExplorerContextMenuConstants; -import org.eclipse.che.selenium.core.constant.TestTimeoutsConstants; -import org.eclipse.che.selenium.core.utils.WaitUtils; import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.Keys; @@ -38,7 +58,6 @@ import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.support.FindBy; 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; @@ -87,15 +106,16 @@ public interface CommandsGoal { } public interface PROJECT_EXPLORER_CONTEXT_MENU_MAVEN { - String REIMPORT = "contextMenu/Maven/Reimport"; + String REIMPORT = "gwt-debug-contextMenu/Maven/reimportMavenDependenciesAction"; } public interface FileWatcherExcludeOperations { - String ADD_TO_FILE_WATCHER_EXCLUDES = "contextMenu/Add to File Watcher excludes"; - String REMOVE_FROM_FILE_WATCHER_EXCLUDES = "contextMenu/Remove from File Watcher excludes"; + String ADD_TO_FILE_WATCHER_EXCLUDES = "gwt-debug-contextMenu/Add to File Watcher excludes"; + String REMOVE_FROM_FILE_WATCHER_EXCLUDES = + "gwt-debug-contextMenu/Remove from File Watcher excludes"; } - private interface Locators { + protected interface Locators { String PROJECT_EXPLORER_TREE_ITEMS = "gwt-debug-projectTree"; String EXPLORER_RIGHT_TAB_ID = "gwt-debug-partButton-Explorer"; String CONTEXT_MENU_ID = "gwt-debug-contextMenu/newGroup"; @@ -123,10 +143,10 @@ public interface ProjectExplorerOptionsMenuItem { String LINK_WITH_EDITOR = "gwt-debug-contextMenu/linkWithEditor"; } - @FindBy(id = Locators.PROJECT_EXPLORER_TREE_ITEMS) + @FindBy(id = PROJECT_EXPLORER_TREE_ITEMS) WebElement projectExplorerTree; - @FindBy(id = Locators.EXPLORER_RIGHT_TAB_ID) + @FindBy(id = EXPLORER_RIGHT_TAB_ID) WebElement projectExplorerTab; @FindBy(id = Locators.GO_BACK_BUTTON) @@ -135,7 +155,7 @@ public interface ProjectExplorerOptionsMenuItem { @FindBy(id = Locators.COLLAPSE_ALL_BUTTON) WebElement collapseAllBtn; - @FindBy(xpath = Locators.ALL_PROJECTS_XPATH) + @FindBy(xpath = ALL_PROJECTS_XPATH) WebElement allProjects; @FindBy(id = Locators.MENU_BUTTON_PART_STACK_ID) @@ -144,23 +164,31 @@ public interface ProjectExplorerOptionsMenuItem { @FindBy(id = Locators.REFRESH_CONTEXT_MENU_ID) WebElement refreshContextMenuItem; - @FindBy(xpath = Locators.PROJECT_EXPLORER_TAB_IN_THE_LEFT_PANEL) + @FindBy(xpath = PROJECT_EXPLORER_TAB_IN_THE_LEFT_PANEL) WebElement projectExplorerTabInTheLeftPanel; + /** + * @param path path to item in Project Explorer + * @param timeout timeout in seconds + * @return found WebElement + */ + private WebElement getProjectExplorerItem(String path, int timeout) { + return new WebDriverWait(seleniumWebDriver, timeout) + .until(visibilityOfElementLocated(By.xpath(String.format("//div[@path='/%s']/div", path)))); + } + /** * @param path path to item in Project Explorer * @return item by path */ private WebElement getProjectExplorerItem(String path) { - return redrawUiElementsWait.until( - ExpectedConditions.visibilityOfElementLocated( - By.xpath(String.format("//div[@path='/%s']/div", path)))); + return getProjectExplorerItem(path, REDRAW_UI_ELEMENTS_TIMEOUT_SEC); } public void clickOnProjectExplorerOptionsButton() { redrawUiElementsWait .until( - ExpectedConditions.visibilityOfElementLocated( + visibilityOfElementLocated( By.xpath( "//div[@id='gwt-debug-navPanel']//div[@name='workBenchIconPartStackOptions']"))) .click(); @@ -168,9 +196,7 @@ public void clickOnProjectExplorerOptionsButton() { public void clickOnOptionsMenuItem(String menuID) { redrawUiElementsWait - .until( - ExpectedConditions.visibilityOfElementLocated( - By.xpath(String.format("//tr[@id='%s']", menuID)))) + .until(visibilityOfElementLocated(By.xpath(String.format("//tr[@id='%s']", menuID)))) .click(); } @@ -180,15 +206,9 @@ public void openPanel() { waitProjectExplorer(); } - /** wait appearance of the IDE Project Explorer */ - public void waitProjectExplorer() { - new WebDriverWait(seleniumWebDriver, EXPECTED_MESS_IN_CONSOLE_SEC) - .until(ExpectedConditions.visibilityOf(projectExplorerTree)); - } - /** press on the project explorer tab */ public void clickOnProjectExplorerTab() { - redrawUiElementsWait.until(ExpectedConditions.visibilityOf(projectExplorerTab)).click(); + redrawUiElementsWait.until(visibilityOfElementLocated(By.id(EXPLORER_RIGHT_TAB_ID))).click(); } /** @@ -198,7 +218,12 @@ public void clickOnProjectExplorerTab() { */ public void clickOnEmptyAreaOfProjectTree(int timeOutForWaiting) { waitProjectExplorer(timeOutForWaiting); - projectExplorerTree.click(); + loadPageTimeout.until(visibilityOf(projectExplorerTree)).click(); + } + + /** wait appearance of the IDE Project Explorer */ + public void waitProjectExplorer() { + waitProjectExplorer(EXPECTED_MESS_IN_CONSOLE_SEC); } /** @@ -208,7 +233,7 @@ public void clickOnEmptyAreaOfProjectTree(int timeOutForWaiting) { */ public void waitProjectExplorer(int timeout) { new WebDriverWait(seleniumWebDriver, timeout) - .until(ExpectedConditions.visibilityOf(projectExplorerTree)); + .until(visibilityOfElementLocated(By.id(PROJECT_EXPLORER_TREE_ITEMS))); } /** @@ -219,11 +244,7 @@ public void waitProjectExplorer(int timeout) { * @param path */ public void waitItem(String path) { - String locator = "//div[@path='/%s']/div"; - loader.waitOnClosed(); - new WebDriverWait(seleniumWebDriver, TestTimeoutsConstants.EXPECTED_MESS_IN_CONSOLE_SEC) - .until(ExpectedConditions.presenceOfElementLocated(By.xpath(String.format(locator, path)))); - loader.waitOnClosed(); + waitItem(path, EXPECTED_MESS_IN_CONSOLE_SEC); } /** @@ -235,9 +256,9 @@ public void waitItem(String path) { * @param timeout user timeout */ public void waitItem(String path, int timeout) { - String locator = "//div[@path='/" + path + "']/div"; + loader.waitOnClosed(); new WebDriverWait(seleniumWebDriver, timeout) - .until(ExpectedConditions.presenceOfElementLocated(By.xpath(locator))); + .until(visibilityOfElementLocated(By.xpath(String.format("//div[@path='/%s']/div", path)))); } /** @@ -248,19 +269,19 @@ public void waitItem(String path, int timeout) { public void waitLibraryIsPresent(String libraryName) { new WebDriverWait(seleniumWebDriver, WIDGET_TIMEOUT_SEC) .until( - ExpectedConditions.presenceOfElementLocated( + visibilityOfElementLocated( By.xpath(String.format("//div[@synthetic='true'and @name='%s']", libraryName)))); } /** - * wait until library will be present in External Libraries + * wait until library will be not present in External Libraries * * @param libraryName name of library */ public void waitLibraryIsNotPresent(String libraryName) { new WebDriverWait(seleniumWebDriver, WIDGET_TIMEOUT_SEC) .until( - ExpectedConditions.invisibilityOfElementLocated( + invisibilityOfElementLocated( By.xpath(String.format("//div[@synthetic='true'and @name='%s']", libraryName)))); } @@ -275,9 +296,10 @@ public void waitLibraryIsNotPresent(String libraryName) { * @param path */ public void waitVisibleItem(String path) { - String locator = "//div[@path='/" + path + "']//div[string-length(text()) > 0]"; new WebDriverWait(seleniumWebDriver, ELEMENT_TIMEOUT_SEC) - .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(locator))); + .until( + visibilityOfElementLocated( + By.xpath("//div[@path='/" + path + "']//div[string-length(text()) > 0]"))); } /** @@ -286,14 +308,14 @@ public void waitVisibleItem(String path) { * @param path path to item */ public void waitItemIsDisappeared(String path) { - String locator = "//div[@path='/" + path + "']/div"; new WebDriverWait(seleniumWebDriver, LOADER_TIMEOUT_SEC) - .until(ExpectedConditions.invisibilityOfElementLocated(By.xpath(locator))); + .until( + invisibilityOfElementLocated(By.xpath(String.format("//div[@path='/%s']/div", path)))); } public void waitYellowNode(String path) { loadPageTimeout.until( - ExpectedConditions.visibilityOfElementLocated( + visibilityOfElementLocated( By.xpath( String.format( "//div[@id='gwt-debug-projectTree']//div[@path='/%s']/descendant::div[@style='%s']", @@ -302,7 +324,7 @@ public void waitYellowNode(String path) { public void waitGreenNode(String path) { loadPageTimeout.until( - ExpectedConditions.visibilityOfElementLocated( + visibilityOfElementLocated( By.xpath( String.format( "//div[@id='gwt-debug-projectTree']//div[@path='/%s']/descendant::div[@style='%s']", @@ -311,7 +333,7 @@ public void waitGreenNode(String path) { public void waitBlueNode(String path) { loadPageTimeout.until( - ExpectedConditions.visibilityOfElementLocated( + visibilityOfElementLocated( By.xpath( String.format( "//div[@id='gwt-debug-projectTree']//div[@path='/%s']/descendant::div[@style='%s']", @@ -320,7 +342,7 @@ public void waitBlueNode(String path) { public void waitDefaultColorNode(String path) { loadPageTimeout.until( - ExpectedConditions.visibilityOfElementLocated( + visibilityOfElementLocated( By.xpath( String.format( "//div[@id='gwt-debug-projectTree']//div[@path='/%s']/descendant::div[@style='%s']", @@ -335,8 +357,7 @@ public void waitDefaultColorNode(String path) { * @param item */ public void waitItemInVisibleArea(String item) { - String locator = String.format("//div[@id='gwt-debug-projectTree']//div[text()='%s']", item); - loadPageTimeout.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(locator))); + waitItemInVisibleArea(item, LOAD_PAGE_TIMEOUT_SEC); } /** @@ -347,8 +368,26 @@ public void waitItemInVisibleArea(String item) { * @param item */ public void waitItemInVisibleArea(String item, final int timeOut) { + loader.waitOnClosed(); new WebDriverWait(seleniumWebDriver, timeOut) - .until(ExpectedConditions.visibilityOfElementLocated(By.name(item))); + .until( + visibilityOfElementLocated( + By.xpath( + String.format("//div[@id='gwt-debug-projectTree']//div[text()='%s']", item)))); + } + + /** + * get web element by his visible name + * + * @param item visible name + * @return found WebElement + */ + private WebElement getVisibleElement(String item) { + return new WebDriverWait(seleniumWebDriver, LOAD_PAGE_TIMEOUT_SEC) + .until( + visibilityOfElementLocated( + By.xpath( + String.format("//div[@id='gwt-debug-projectTree']//div[text()='%s']", item)))); } /** @@ -356,10 +395,10 @@ public void waitItemInVisibleArea(String item, final int timeOut) { * project can be some folder. Into each folder can be a file with same name. This method will be * track only first item.) * - * @param item + * @param item visible name */ public void waitItemIsNotPresentVisibleArea(String item) { - loadPageTimeout.until(ExpectedConditions.invisibilityOfElementLocated(By.name(item))); + loadPageTimeout.until(invisibilityOfElementLocated(By.name(item))); } /** @@ -369,26 +408,7 @@ public void waitItemIsNotPresentVisibleArea(String item) { * @param path full path to project item */ public void selectItem(String path) { - String locator = "//div[@path='/" + path + "']/div"; - - waitItem(path); - try { - new WebDriverWait(seleniumWebDriver, EXPECTED_MESS_IN_CONSOLE_SEC) - .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(locator))) - .click(); - } - // sometimes an element in the project explorer may not be attached to the DOM. We should - // refresh all items. - catch (StaleElementReferenceException ex) { - LOG.debug(ex.getLocalizedMessage(), ex); - - waitProjectExplorer(); - clickOnRefreshTreeButton(); - waitItem(path); - new WebDriverWait(seleniumWebDriver, EXPECTED_MESS_IN_CONSOLE_SEC) - .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(locator))) - .click(); - } + selectItem(path, EXPECTED_MESS_IN_CONSOLE_SEC); } /** @@ -401,12 +421,9 @@ public void selectItem(String path) { * tree */ public void selectItem(String path, int timeoutForWaitingItem) { - String locator = "//div[@path='/" + path + "']/div"; - waitItem(path, timeoutForWaitingItem); + waitItem(path); try { - new WebDriverWait(seleniumWebDriver, EXPECTED_MESS_IN_CONSOLE_SEC) - .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(locator))) - .click(); + getProjectExplorerItem(path, timeoutForWaitingItem).click(); } // sometimes an element in the project explorer may not be attached to the DOM. We should // refresh all items. @@ -416,9 +433,7 @@ public void selectItem(String path, int timeoutForWaitingItem) { waitProjectExplorer(); clickOnRefreshTreeButton(); waitItem(path); - new WebDriverWait(seleniumWebDriver, EXPECTED_MESS_IN_CONSOLE_SEC) - .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(locator))) - .click(); + getProjectExplorerItem(path, EXPECTED_MESS_IN_CONSOLE_SEC).click(); } } @@ -429,32 +444,30 @@ public void selectItem(String path, int timeoutForWaitingItem) { * @param item */ public void selectVisibleItem(String item) { - String locator = "//div[@name='" + item + "']/div"; - redrawUiElementsWait - .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(locator))) - .click(); + getVisibleElement(item).click(); } /** wait external maven Libraries relative module */ - public void waitLibraries(String modulePath) { - String locator = "//div [@name='External Libraries' and @project='/" + modulePath + "']"; - new WebDriverWait(seleniumWebDriver, 10) - .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(locator))); + public WebElement waitLibraries(String modulePath) { + return loadPageTimeout.until( + visibilityOfElementLocated( + By.xpath( + String.format( + "//div [@name='External Libraries' and @project='/%s']", modulePath)))); } /** wait disappearance external maven Libraries relative module */ public void waitLibrariesIsNotPresent(String modulePath) { - String locator = "//div [@name='External Libraries' and @project='/" + modulePath + "']"; - new WebDriverWait(seleniumWebDriver, 10) - .until(ExpectedConditions.invisibilityOfElementLocated(By.xpath(locator))); + loadPageTimeout.until( + invisibilityOfElementLocated( + By.xpath( + String.format( + "//div [@name='External Libraries' and @project='/%s']", modulePath)))); } /** select external maven Library relative module */ public void selectLibraries(String modulePath) { - String locator = "//div [@name='External Libraries' and @project='/" + modulePath + "']"; - new WebDriverWait(seleniumWebDriver, 10) - .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(locator))) - .click(); + waitLibraries(modulePath).click(); } /** @@ -479,13 +492,10 @@ public void scrollAndSelectItem(String path) { */ public void openItemByPath(String path) { Actions action = actionsFactory.createAction(seleniumWebDriver); - waitItem(path); selectItem(path); waitItemIsSelected(path); try { - getProjectExplorerItem(path).click(); - waitItemIsSelected(path); action.moveToElement(getProjectExplorerItem(path)).perform(); action.doubleClick().perform(); } @@ -495,8 +505,7 @@ public void openItemByPath(String path) { LOG.debug(ex.getLocalizedMessage(), ex); clickOnRefreshTreeButton(); - waitItem(path); - getProjectExplorerItem(path).click(); + selectItem(path); waitItemIsSelected(path); action.moveToElement(getProjectExplorerItem(path)).perform(); action.doubleClick().perform(); @@ -512,13 +521,11 @@ public void openItemByPath(String path) { * @param visibleItem */ public void openItemByVisibleNameInExplorer(String visibleItem) { - loader.waitOnClosed(); - waitItemInVisibleArea(visibleItem); - String locator = - String.format("//div[@id='gwt-debug-projectTree']//div[text()='%s']", visibleItem); - WebElement item = seleniumWebDriver.findElement(By.xpath(locator)); - item.click(); - actionsFactory.createAction(seleniumWebDriver).doubleClick(item).perform(); + getVisibleElement(visibleItem).click(); + actionsFactory + .createAction(seleniumWebDriver) + .doubleClick(getVisibleElement(visibleItem)) + .perform(); loader.waitOnClosed(); } @@ -528,10 +535,10 @@ public void openItemByVisibleNameInExplorer(String visibleItem) { * @param packageName */ public void openVisiblePackage(String packageName) { - String locator = "//div[text()='" + packageName + "']"; - loadPageTimeout.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(locator))); - WebElement visiblePacksge = seleniumWebDriver.findElement(By.xpath(locator)); - actionsFactory.createAction(seleniumWebDriver).doubleClick(visiblePacksge).perform(); + actionsFactory + .createAction(seleniumWebDriver) + .doubleClick(getVisibleElement(packageName)) + .perform(); } /** @@ -540,9 +547,10 @@ public void openVisiblePackage(String packageName) { * @param pathToItem full path to item in the codenvy project explorer */ public void waitDisappearItemByPath(String pathToItem) { - String locator = "//div[@path='/" + pathToItem + "']/div"; new WebDriverWait(seleniumWebDriver, ELEMENT_TIMEOUT_SEC) - .until(ExpectedConditions.invisibilityOfElementLocated(By.xpath(locator))); + .until( + invisibilityOfElementLocated( + By.xpath(String.format("//div[@path='/%s']/div", pathToItem)))); } /** @@ -553,13 +561,12 @@ public void waitDisappearItemByPath(String pathToItem) { * javaSource folder. We can use this types from ProjectExlorer.FolderTypes public interface. */ public void waitFolderDefinedTypeOfFolderByPath(String pathToFolder, String typeFolder) { - String locator = - "//div[@path='/" - + pathToFolder - + "']/div/*[local-name() = 'svg' and @id='" - + typeFolder - + "']"; - loadPageTimeout.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(locator))); + loadPageTimeout.until( + visibilityOfElementLocated( + By.xpath( + String.format( + "//div[@path='/%s']/div/*[local-name() = 'svg' and @id='%s']", + pathToFolder, typeFolder)))); } /** @@ -568,11 +575,10 @@ public void waitFolderDefinedTypeOfFolderByPath(String pathToFolder, String type * @param pathToItem full path to item in the codenvy project explorer */ public void waitRemoveItemsByPath(String pathToItem) { - String locator = "//div[@path='/" + pathToItem + "']/div"; - new WebDriverWait(seleniumWebDriver, 10) - .until( - ExpectedConditions.not( - ExpectedConditions.presenceOfAllElementsLocatedBy(By.xpath(locator)))); + loadPageTimeout.until( + not( + presenceOfAllElementsLocatedBy( + By.xpath(String.format("//div[@path='/%s']/div", pathToItem))))); } /** @@ -597,7 +603,7 @@ public void waitContextMenu() { "//tr[@id='gwt-debug-contextMenu/newGroup']/parent::tbody"); new WebDriverWait(seleniumWebDriver, WIDGET_TIMEOUT_SEC) - .until(ExpectedConditions.visibilityOfElementLocated(By.id(Locators.CONTEXT_MENU_ID))); + .until(visibilityOfElementLocated(By.id(CONTEXT_MENU_ID))); } /** @@ -606,7 +612,11 @@ public void waitContextMenu() { * @param item */ public void clickOnItemInContextMenu(String item) { - loadPageTimeout.until(ExpectedConditions.visibilityOfElementLocated(By.id(item))).click(); + loadPageTimeout + .until( + visibilityOfElementLocated( + By.xpath(String.format("//tr[@item-enabled='true' and @id='%s']", item)))) + .click(); } /** @@ -615,16 +625,17 @@ public void clickOnItemInContextMenu(String item) { * @param item item form {@code SubMenuNew} */ public void clickOnNewContextMenuItem(String item) { - new WebDriverWait(seleniumWebDriver, 10) - .until(ExpectedConditions.visibilityOf(seleniumWebDriver.findElement(By.id(item)))) + loadPageTimeout + .until( + visibilityOfElementLocated( + By.xpath(String.format("//tr[@item-enabled='true' and @id='%s']", item)))) .click(); waitContextMenuPopUpClosed(); } public void waitContextMenuPopUpClosed() { - loadPageTimeout.until( - ExpectedConditions.invisibilityOfElementLocated(By.id(Locators.CONTEXT_MENU_ID))); + loadPageTimeout.until(invisibilityOfElementLocated(By.id(CONTEXT_MENU_ID))); } /** @@ -634,40 +645,72 @@ public void waitContextMenuPopUpClosed() { */ public void selectMultiFilesByCtrlKeys(String path) { Actions actions = actionsFactory.createAction(seleniumWebDriver); - actions.keyDown(Keys.CONTROL).perform(); + actions.keyDown(CONTROL).perform(); selectItem(path); - actions.keyUp(Keys.CONTROL).perform(); + waitItemIsSelected(path); + actions.keyUp(CONTROL).perform(); } /** Click on the 'Reveal in project explorer' in 'Options'menu */ public void revealResourceByOptionsButton() { clickOnProjectExplorerOptionsButton(); - clickOnOptionsMenuItem(ProjectExplorerOptionsMenuItem.REVEAL_RESOURCE); + clickOnOptionsMenuItem(REVEAL_RESOURCE); + } + + /** + * perform the multi-select by Shift key + * + * @param path is the path to the selected item + */ + public void selectMultiFilesByShiftKey(String path) { + Actions actions = actionsFactory.createAction(seleniumWebDriver); + actions.keyDown(SHIFT).perform(); + selectItem(path); + waitItemIsSelected(path); + actions.keyUp(Keys.SHIFT).perform(); + } + + /** + * perform the multi-select by Shift key with check selected items + * + * @param clickItemPath is the path to the selected item + * @param selectedItemsPaths is the paths to the each selected items after click with shift button + */ + public void selectMultiFilesByShiftKeyWithCheckMultiselection( + String clickItemPath, List selectedItemsPaths) { + Actions actions = actionsFactory.createAction(seleniumWebDriver); + actions.keyDown(SHIFT).perform(); + selectItem(clickItemPath); + waitAllItemsIsSelected(selectedItemsPaths); + actions.keyUp(SHIFT).perform(); } /** click on the 'collapse all' in the project explorer */ public void collapseProjectTreeByOptionsButton() { clickOnProjectExplorerOptionsButton(); - clickOnOptionsMenuItem(ProjectExplorerOptionsMenuItem.COLLAPSE_ALL); + clickOnOptionsMenuItem(COLLAPSE_ALL); } /** click on the 'go back' in the project explorer */ public void clickGoBackButton() { - loadPageTimeout.until(ExpectedConditions.elementToBeClickable(goBackBtn)); - goBackBtn.click(); + loadPageTimeout.until(visibilityOf(goBackBtn)).click(); } /** launch the 'Refactor Rename' form by keyboard after select a package or Java class */ public void launchRefactorByKeyboard() { loader.waitOnClosed(); - Actions action = actionsFactory.createAction(seleniumWebDriver); - action.keyDown(Keys.SHIFT).sendKeys(Keys.F6).keyUp(Keys.SHIFT).perform(); + actionsFactory + .createAction(seleniumWebDriver) + .keyDown(SHIFT) + .sendKeys(F6) + .keyUp(SHIFT) + .perform(); } /** launch the 'Refactor Move' form by keyboard after select a package or Java class */ public void launchRefactorMoveByKeyboard() { loader.waitOnClosed(); - actionsFactory.createAction(seleniumWebDriver).sendKeys(Keys.F6).perform(); + actionsFactory.createAction(seleniumWebDriver).sendKeys(F6).perform(); } /** @@ -676,14 +719,11 @@ public void launchRefactorMoveByKeyboard() { * @return list of names */ public List getNamesAllProjects() { - List projects = - loadPageTimeout.until( - ExpectedConditions.visibilityOfAllElementsLocatedBy( - By.xpath(Locators.ALL_PROJECTS_XPATH))); - return projects + return loadPageTimeout + .until(visibilityOfAllElementsLocatedBy(By.xpath(ALL_PROJECTS_XPATH))) .stream() .map((webElement) -> webElement.getAttribute("name")) - .collect(Collectors.toList()); + .collect(toList()); } /** @@ -692,33 +732,32 @@ public List getNamesAllProjects() { * @return list of items */ public List getNamesOfAllOpenItems() { - List result = Arrays.asList(projectExplorerTree.getText().split("\n")); - return result; + return asList(projectExplorerTree.getText().split("\n")); } /** perform right arrow key pressed in a browser */ public void sendToItemRightArrowKey() { - actionsFactory.createAction(seleniumWebDriver).sendKeys(Keys.RIGHT.toString()).perform(); + actionsFactory.createAction(seleniumWebDriver).sendKeys(RIGHT.toString()).perform(); } /** perform left arrow key pressed in a browser */ public void sendToItemLeftArrowKey() { - actionsFactory.createAction(seleniumWebDriver).sendKeys(Keys.LEFT.toString()).perform(); + actionsFactory.createAction(seleniumWebDriver).sendKeys(LEFT.toString()).perform(); } /** perform up arrow key pressed in a browser */ public void sendToItemUpArrowKey() { - actionsFactory.createAction(seleniumWebDriver).sendKeys(Keys.UP.toString()).perform(); + actionsFactory.createAction(seleniumWebDriver).sendKeys(UP.toString()).perform(); } /** perform down arrow key pressed in a browser */ public void sendToItemDownArrowKey() { - actionsFactory.createAction(seleniumWebDriver).sendKeys(Keys.ARROW_DOWN.toString()).perform(); + actionsFactory.createAction(seleniumWebDriver).sendKeys(ARROW_DOWN.toString()).perform(); } /** perform enter key pressed in a browser */ public void sendToItemEnterKey() { - actionsFactory.createAction(seleniumWebDriver).sendKeys(Keys.ENTER.toString()).perform(); + actionsFactory.createAction(seleniumWebDriver).sendKeys(ENTER.toString()).perform(); } /** wait refresh button and click this one */ @@ -729,25 +768,35 @@ public void clickOnRefreshTreeButton() { public void clickOnImportProjectLink(int userTimeout) { waitProjectExplorer(); - projectExplorerTree.findElement(By.xpath("//div[text()='Import Project...']")).click(); + WebElement importProjectLink = + new WebDriverWait(seleniumWebDriver, userTimeout) + .until( + presenceOfNestedElementLocatedBy( + projectExplorerTree, By.xpath("//div[text()='Import Project...']"))); + + loadPageTimeout.until(visibilityOf(importProjectLink)).click(); } public void clickOnCreateProjectLink(int userTimeout) { waitProjectExplorer(); - projectExplorerTree.findElement(By.xpath("//div[text()='Create Project...']")).click(); + WebElement createProjectLink = + new WebDriverWait(seleniumWebDriver, userTimeout) + .until( + presenceOfNestedElementLocatedBy( + projectExplorerTree, By.xpath("//div[text()='Create Project...']"))); + + loadPageTimeout.until(visibilityOf(createProjectLink)).click(); } public void clickOnProjectExplorerTabInTheLeftPanel() { redrawUiElementsWait - .until(ExpectedConditions.visibilityOf(projectExplorerTabInTheLeftPanel)) + .until(visibilityOfElementLocated(By.xpath(PROJECT_EXPLORER_TAB_IN_THE_LEFT_PANEL))) .click(); } /** invoke command from context menu. Work for Common scope commands only */ public void invokeCommandWithContextMenu( String commandsGoal, String pathToItem, String commandName) { - String commandNameLocator = "//tr[@id[contains(.,'%s')]]"; - try { openContextMenuByPathSelectedItem(pathToItem); } catch (NoSuchElementException e) { @@ -756,42 +805,45 @@ public void invokeCommandWithContextMenu( pathToItem); // there context menu may not be opened from the first try } - clickOnItemInContextMenu(TestProjectExplorerContextMenuConstants.COMMANDS); + clickOnItemInContextMenu(COMMANDS); clickOnItemInContextMenu(commandsGoal); - new WebDriverWait(seleniumWebDriver, MULTIPLE) + redrawUiElementsWait .until( - ExpectedConditions.visibilityOfElementLocated( - By.xpath(String.format(commandNameLocator, commandName)))) + visibilityOfElementLocated( + By.xpath(String.format("//tr[@id[contains(.,'%s')]]", commandName)))) .click(); } public void invokeCommandWithContextMenu( String commandsGoal, String pathToItem, String commandName, String machineName) { - String commandNameLocator = "//tr[@id[contains(.,'%s')]]"; - String machineNameLocator = "//select[@class = 'gwt-ListBox']//option[contains(.,'%s')]"; selectItem(pathToItem); openContextMenuByPathSelectedItem(pathToItem); - clickOnItemInContextMenu(TestProjectExplorerContextMenuConstants.COMMANDS); + clickOnItemInContextMenu(COMMANDS); clickOnItemInContextMenu(commandsGoal); - new WebDriverWait(seleniumWebDriver, TestTimeoutsConstants.MULTIPLE) + redrawUiElementsWait .until( - ExpectedConditions.visibilityOfElementLocated( - By.xpath(String.format(commandNameLocator, commandName)))) + visibilityOfElementLocated( + By.xpath(String.format("//tr[@id[contains(.,'%s')]]", commandName)))) .click(); loader.waitOnClosed(); - new Actions(seleniumWebDriver) + actionsFactory + .createAction(seleniumWebDriver) .doubleClick( - seleniumWebDriver.findElement(By.xpath(String.format(machineNameLocator, machineName)))) - .build() + seleniumWebDriver.findElement( + By.xpath( + String.format( + "//select[@class = 'gwt-ListBox']//option[contains(.,'%s')]", + machineName)))) .perform(); } public void scrollToItemByPath(String path) { waitItem(path); - String locator = "//div[@path='/" + path + "']/div"; - WebElement item = seleniumWebDriver.findElement(By.xpath(locator)); - actionsFactory.createAction(seleniumWebDriver).moveToElement(item).perform(); + actionsFactory + .createAction(seleniumWebDriver) + .moveToElement(getProjectExplorerItem(path)) + .perform(); } /** @@ -888,7 +940,7 @@ public void expandToFileWithRevealResource(String file, String pathToFile) { try { navigateToFile.waitFileNamePopUp(); } catch (StaleElementReferenceException ex) { - WaitUtils.sleepQuietly(1); + sleepQuietly(1); } navigateToFile.waitListOfFilesNames(file); navigateToFile.selectFileByName(file); @@ -926,9 +978,16 @@ public void quickRevealToItemWithJavaScript(String absPathToResource) { } public void waitItemIsSelected(String path) { - String locator = - "//div[@path='/%s']/div[contains(concat(' ', normalize-space(@class), ' '), ' selected')]"; - new WebDriverWait(seleniumWebDriver, TestTimeoutsConstants.ELEMENT_TIMEOUT_SEC) - .until(ExpectedConditions.presenceOfElementLocated(By.xpath(String.format(locator, path)))); + new WebDriverWait(seleniumWebDriver, ELEMENT_TIMEOUT_SEC) + .until( + visibilityOfElementLocated( + By.xpath( + String.format( + "//div[@path='/%s']/div[contains(concat(' ', normalize-space(@class), ' '), ' selected')]", + path)))); + } + + public void waitAllItemsIsSelected(List paths) { + paths.forEach(this::waitItemIsSelected); } } diff --git a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/editor/autocomplete/CheckAutocompleteFeaturesInTheTestFolderTest.java b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/editor/autocomplete/CheckAutocompleteFeaturesInTheTestFolderTest.java index f7d3bf61965d..9e599474c3dd 100644 --- a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/editor/autocomplete/CheckAutocompleteFeaturesInTheTestFolderTest.java +++ b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/editor/autocomplete/CheckAutocompleteFeaturesInTheTestFolderTest.java @@ -68,6 +68,7 @@ public void checkAutocompleteFeaturesInTheTestFolderTest() { } private void checkOpenDeclaration() { + editor.waitActive(); editor.goToCursorPositionVisible(35, 21); editor.waitActive(); editor.waitSpecifiedValueForLineAndChar(35, 21); From d4ab115e81bd0bc03c342a369818fef77bdbaae6 Mon Sep 17 00:00:00 2001 From: Vladyslav Zhukovskyi Date: Wed, 20 Dec 2017 10:57:52 +0200 Subject: [PATCH 26/30] Use trash icon from FontAwesome for delete command operation (#7951) * Use trash icon from FontAwesome for delete command operation Signed-off-by: Vladyslav Zhukovskyi * Fix formatting issue Signed-off-by: Vladyslav Zhukovskyi --- .../explorer/CommandsTreeRenderer.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/command/explorer/CommandsTreeRenderer.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/command/explorer/CommandsTreeRenderer.java index 9da2918a1de5..dead8908c5e9 100644 --- a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/command/explorer/CommandsTreeRenderer.java +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/command/explorer/CommandsTreeRenderer.java @@ -14,7 +14,10 @@ import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.SpanElement; +import com.google.gwt.dom.client.Style; import com.google.gwt.user.client.Event; +import org.eclipse.che.ide.FontAwesome; import org.eclipse.che.ide.command.CommandResources; import org.eclipse.che.ide.command.explorer.CommandsExplorerView.ActionDelegate; import org.eclipse.che.ide.command.node.CommandFileNode; @@ -81,7 +84,7 @@ public Element render(Node node, String domID, Tree.Joint joint, int depth) { private void renderCommandNode(CommandFileNode node, Element nodeContainerElement) { nodeContainerElement.addClassName(resources.commandsExplorerCss().commandNode()); - final Element removeCommandButton = createButton(resources.removeCommand()); + final Element removeCommandButton = createButton(FontAwesome.TRASH); Event.setEventListener( removeCommandButton, event -> { @@ -132,12 +135,26 @@ private void renderCommandGoalNode(Element nodeContainerElement) { addCommandButton.setId("commands_tree-button-add"); } - private Element createButton(SVGResource icon) { + private Element createButton(Object icon) { final Element button = Document.get().createSpanElement(); - button.appendChild(icon.getSvg().getElement()); + button.appendChild(getIconElement(icon)); Event.sinkEvents(button, ONCLICK); return button; } + + private Element getIconElement(Object icon) { + if (icon instanceof SVGResource) { + return ((SVGResource) icon).getSvg().getElement(); + } else if (icon instanceof String) { + SpanElement element = Document.get().createSpanElement(); + element.getStyle().setFontSize(11., Style.Unit.PT); + element.getStyle().setMarginTop(2., Style.Unit.PT); + element.setInnerHTML((String) icon); + return element; + } + + throw new IllegalArgumentException("Icon type is undefined"); + } } From db70d737bf9bd62ece2ede02e5320d73ebd56514 Mon Sep 17 00:00:00 2001 From: Dmytro Nochevnov Date: Wed, 20 Dec 2017 12:50:24 +0000 Subject: [PATCH 27/30] Create test user at start of selenium tests execution (#7965) * Create test user at start of selenium tests execution * Rename 'CHE_SELENIUM_INFRASTRUCTURE' to 'CHE_INFRASTRUCTURE' in selenium tests --- selenium/che-selenium-core/bin/webdriver.sh | 63 +++++++++++++++++++ .../core/factory/TestFactoryInitializer.java | 2 +- .../core/utils/WorkspaceDtoDeserializer.java | 2 +- selenium/che-selenium-test/README.md | 28 ++++----- ...TestDefaultUserHttpJsonRequestFactory.java | 4 +- .../TestCheAdminHttpJsonRequestFactory.java | 4 +- .../selenium/core/user/CheAdminTestUser.java | 4 +- .../core/user/CheDefaultTestUser.java | 4 +- .../test/resources/conf/selenium.properties | 14 ----- 9 files changed, 85 insertions(+), 40 deletions(-) diff --git a/selenium/che-selenium-core/bin/webdriver.sh b/selenium/che-selenium-core/bin/webdriver.sh index eb6eb00e84ce..32ff7fb61414 100755 --- a/selenium/che-selenium-core/bin/webdriver.sh +++ b/selenium/che-selenium-core/bin/webdriver.sh @@ -50,7 +50,9 @@ initVariables() { readonly FAILSAFE_REPORT="target/site/failsafe-report.html" readonly SINGLE_TEST_MSG="single test/package" + export CHE_MULTIUSER=${CHE_MULTIUSER:-false} + export CHE_INFRASTRUCTURE=${CHE_INFRASTRUCTURE:-docker} # CALLER variable contains parent caller script name # CUR_DIR variable contains the current directory where CALLER is executed @@ -820,6 +822,67 @@ prepareToFirstRun() { checkIfProductIsRun cleanUpEnvironment initRunMode + + if [[ ${CHE_MULTIUSER} == false ]]; then + prepareTestUserForSingleuserChe + else + prepareTestUserForMultiuserChe + fi +} + +prepareTestUserForSingleuserChe() { + export CHE_ADMIN_EMAIL= + export CHE_ADMIN_PASSWORD= + + export CHE_TESTUSER_EMAIL=che@eclipse.org + export CHE_TESTUSER_PASSWORD=secret +} + +prepareTestUserForMultiuserChe() { + export CHE_ADMIN_NAME=${CHE_ADMIN_NAME:-admin} + export CHE_ADMIN_EMAIL=${CHE_ADMIN_EMAIL:-admin@admin.com} + export CHE_ADMIN_PASSWORD=${CHE_ADMIN_PASSWORD:-admin} + + if [[ -n ${CHE_TESTUSER_EMAIL+x} ]] && [[ -n ${CHE_TESTUSER_PASSWORD+x} ]]; then + return + fi + + # create test user by executing kcadm.sh commands inside keycloak docker container if there are no its credentials among environment variables + if [[ "${PRODUCT_HOST}" == "$(detectDockerInterfaceIp)" ]] || [[ "${CHE_INFRASTRUCTURE}" == "openshift" ]]; then + + echo "[TEST] Creating test user..." + local time=$(date +%s) + export CHE_TESTUSER_NAME=${CHE_TESTUSER_NAME:-user${time}} + export CHE_TESTUSER_EMAIL=${CHE_TESTUSER_EMAIL:-${CHE_TESTUSER_NAME}@1.com} + export CHE_TESTUSER_PASSWORD=${CHE_TESTUSER_PASSWORD:-${time}} + + if [[ "${CHE_INFRASTRUCTURE}" == "openshift" ]]; then + local kc_container_id=$(docker ps | grep keycloak_keycloak-1 | cut -d ' ' -f1) + else + local kc_container_id=$(docker ps | grep che_keycloak_1 | cut -d ' ' -f1) + fi + + local cli_auth="--no-config --server http://localhost:8080/auth --user ${CHE_ADMIN_NAME} --password ${CHE_ADMIN_PASSWORD} --realm master" + local response=$(docker exec -i $kc_container_id sh -c "keycloak/bin/kcadm.sh create users -r che -s username=${CHE_TESTUSER_NAME} -s enabled=true $cli_auth 2>&1") + if [[ "$response" =~ "Created new user with id" ]]; then + userId=$(echo "$response" | grep "Created new user with id" | sed -e "s#Created new user with id ##" | sed -e "s#'##g") + # set test user's permanent password + docker exec -i $kc_container_id sh -c "keycloak/bin/kcadm.sh set-password -r che --username ${CHE_TESTUSER_NAME} --new-password ${CHE_TESTUSER_PASSWORD} $cli_auth" + # set email of test user to ${cheTestUserEmail} + docker exec -i $kc_container_id sh -c "keycloak/bin/kcadm.sh update users/$userId -r che --set email=${CHE_TESTUSER_EMAIL} $cli_auth" + # add realm role "user" test user + docker exec -i $kc_container_id sh -c "keycloak/bin/kcadm.sh add-roles -r che --uusername ${CHE_TESTUSER_NAME} --rolename user $cli_auth" + # add role "read-token" of client "broker" to test user + docker exec -i $kc_container_id sh -c "keycloak/bin/kcadm.sh add-roles -r che --uusername ${CHE_TESTUSER_NAME} --cclientid broker --rolename read-token $cli_auth" + else + # set test user credentials to be equal to admin ones in case of problem with creation of user + echo -e "${RED}[WARN] There is a problem with creation of test user in Keycloak server: '${response}'.${NO_COLOUR}" + echo -e "Admin user will be used as a test user." + CHE_TESTUSER_NAME=${CHE_ADMIN_NAME} + CHE_TESTUSER_EMAIL=${CHE_ADMIN_EMAIL} + CHE_TESTUSER_PASSWORD=${CHE_ADMIN_PASSWORD} + fi + fi } testProduct() { diff --git a/selenium/che-selenium-core/src/main/java/org/eclipse/che/selenium/core/factory/TestFactoryInitializer.java b/selenium/che-selenium-core/src/main/java/org/eclipse/che/selenium/core/factory/TestFactoryInitializer.java index e88b6d29e854..6d8a1e3eab29 100644 --- a/selenium/che-selenium-core/src/main/java/org/eclipse/che/selenium/core/factory/TestFactoryInitializer.java +++ b/selenium/che-selenium-core/src/main/java/org/eclipse/che/selenium/core/factory/TestFactoryInitializer.java @@ -57,7 +57,7 @@ public class TestFactoryInitializer { @Inject private SeleniumWebDriver seleniumWebDriver; @Inject - @Named("che.selenium.infrastructure") + @Named("che.infrastructure") private String infrastructure; /** diff --git a/selenium/che-selenium-core/src/main/java/org/eclipse/che/selenium/core/utils/WorkspaceDtoDeserializer.java b/selenium/che-selenium-core/src/main/java/org/eclipse/che/selenium/core/utils/WorkspaceDtoDeserializer.java index 1374895c5c83..3597d4d52f5e 100644 --- a/selenium/che-selenium-core/src/main/java/org/eclipse/che/selenium/core/utils/WorkspaceDtoDeserializer.java +++ b/selenium/che-selenium-core/src/main/java/org/eclipse/che/selenium/core/utils/WorkspaceDtoDeserializer.java @@ -37,7 +37,7 @@ public class WorkspaceDtoDeserializer { private static final Logger LOG = LoggerFactory.getLogger(WorkspaceDtoDeserializer.class); @Inject - @Named("che.selenium.infrastructure") + @Named("che.infrastructure") private String infrastructure; public WorkspaceConfigDto deserializeWorkspaceTemplate(String templateName) { diff --git a/selenium/che-selenium-test/README.md b/selenium/che-selenium-test/README.md index 65b7f7b43b51..1c627e83dd63 100644 --- a/selenium/che-selenium-test/README.md +++ b/selenium/che-selenium-test/README.md @@ -17,13 +17,6 @@ newly created [OAuth application](https://github.com/settings/developers). Set `CHE_LOCAL_CONF_DIR` environment variable and point to the folder where selenium tests configuration will be stored. Create file `selenium.properties` in that folder with the following content: ``` -# Credentials of Eclipse Che multiuser assemblies -che.admin_user.email= -che.admin_user.password= - -che.test_user.email= -che.test_user.password= - # GitHub account credentials github.username= github.password= @@ -35,6 +28,15 @@ google.user= google.password= ``` +In case of running of tests for Eclipse Che in Multi User mode you can set your own credentials of test user or admin instead of default ones +export CHE_ADMIN_NAME= +export CHE_ADMIN_EMAIL= +export CHE_ADMIN_PASSWORD= + +export CHE_TESTUSER_NAME= +export CHE_TESTUSER_EMAIL= +export CHE_TESTUSER_PASSWORD= + #### 3. Prepare repository Fork all repositories from [https://github.com/idexmai?tab=repositories](https://github.com/idexmai?tab=repositories) into the main GitHub account. Fork the repository [https://github.com/iedexmain1/pull-request-plugin-fork-test](https://github.com/iedexmain1/pull-request-plugin-fork-test) into the auxiliary GitHub account. @@ -48,15 +50,9 @@ Follow the guide: [https://github.com/eclipse/che](https://github.com/eclipse/ch Simply launch `./selenium-tests.sh` ### How to run tests on OpenShift -#### Che in container case -##### 1. Set workspace runtime infrastructure implementation -export CHE_SELENIUM_INFRASTRUCTURE=openshift -##### 2. Run tests in the default way -Simply launch `./selenium-tests.sh` -#### Che inside of OpenShift case -##### 1. Set workspace runtime infrastructure implementation -export CHE_SELENIUM_INFRASTRUCTURE=openshift -##### 2. Run tests and specify host and port of Che deployed to OpenShift +#### 1. Set workspace runtime infrastructure implementation +export CHE_INFRASTRUCTURE=openshift +#### 2. Run tests and specify host and port of Che deployed to OpenShift Launch `./selenium-tests.sh --host= --port=80` Example: `./selenium-tests.sh --host=che-spi.192.168.99.100.nip.io --port=80` diff --git a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/core/requestfactory/CheTestDefaultUserHttpJsonRequestFactory.java b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/core/requestfactory/CheTestDefaultUserHttpJsonRequestFactory.java index 11e8dafd8e96..029978977d31 100644 --- a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/core/requestfactory/CheTestDefaultUserHttpJsonRequestFactory.java +++ b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/core/requestfactory/CheTestDefaultUserHttpJsonRequestFactory.java @@ -20,8 +20,8 @@ public class CheTestDefaultUserHttpJsonRequestFactory extends TestUserHttpJsonRe @Inject public CheTestDefaultUserHttpJsonRequestFactory( TestAuthServiceClient authServiceClient, - @Named("che.test_user.email") String email, - @Named("che.test_user.password") String password) { + @Named("che.testuser.email") String email, + @Named("che.testuser.password") String password) { super(authServiceClient, email, password); } } diff --git a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/core/requestfactory/TestCheAdminHttpJsonRequestFactory.java b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/core/requestfactory/TestCheAdminHttpJsonRequestFactory.java index 50e112cec4b2..c402c36f168f 100644 --- a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/core/requestfactory/TestCheAdminHttpJsonRequestFactory.java +++ b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/core/requestfactory/TestCheAdminHttpJsonRequestFactory.java @@ -20,8 +20,8 @@ public class TestCheAdminHttpJsonRequestFactory extends TestUserHttpJsonRequestF @Inject public TestCheAdminHttpJsonRequestFactory( TestAuthServiceClient authServiceClient, - @Named("che.admin_user.email") String adminEmail, - @Named("che.admin_user.password") String adminPassword) { + @Named("che.admin.email") String adminEmail, + @Named("che.admin.password") String adminPassword) { super(authServiceClient, adminEmail, adminPassword); } } diff --git a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/core/user/CheAdminTestUser.java b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/core/user/CheAdminTestUser.java index ef88e9ddda38..a693ec274333 100644 --- a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/core/user/CheAdminTestUser.java +++ b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/core/user/CheAdminTestUser.java @@ -23,8 +23,8 @@ public class CheAdminTestUser implements AdminTestUser { @Inject public CheAdminTestUser( TestUserFactory userFactory, - @Named("che.admin_user.email") String email, - @Named("che.admin_user.password") String password) + @Named("che.admin.email") String email, + @Named("che.admin.password") String password) throws Exception { this.delegate = userFactory.create(email, password); } diff --git a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/core/user/CheDefaultTestUser.java b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/core/user/CheDefaultTestUser.java index 31ad15774a21..7646d9b621c5 100644 --- a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/core/user/CheDefaultTestUser.java +++ b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/core/user/CheDefaultTestUser.java @@ -31,8 +31,8 @@ public class CheDefaultTestUser implements TestUser { @Inject public CheDefaultTestUser( TestUserFactory userFactory, - @Named("che.test_user.email") String email, - @Named("che.test_user.password") String password) + @Named("che.testuser.email") String email, + @Named("che.testuser.password") String password) throws Exception { this.delegate = userFactory.create(email, password); } diff --git a/selenium/che-selenium-test/src/test/resources/conf/selenium.properties b/selenium/che-selenium-test/src/test/resources/conf/selenium.properties index 17b3dab93706..dc8a2924132d 100644 --- a/selenium/che-selenium-test/src/test/resources/conf/selenium.properties +++ b/selenium/che-selenium-test/src/test/resources/conf/selenium.properties @@ -25,17 +25,3 @@ github.auxiliary.password= google.user= google.password= -# Workspace infrastructure implementation -che.selenium.infrastructure=docker - -# Define configuration for che default test user. -# For che single user assembly, the default values will be enough. -# For che multiuser assembly, user must be already created on identity provider service. -che.test_user.email=che@eclipse.org -che.test_user.password=secret - -# Define configuration for admin test user. -# Note that admin user needs only for multiuser assembly and -# must be already created on identity provider service -che.admin_user.email= -che.admin_user.password= From 1019695e69430e1c7525e6a7d99d42ce71a6ccf3 Mon Sep 17 00:00:00 2001 From: Maxim Musienko Date: Wed, 20 Dec 2017 15:52:17 +0200 Subject: [PATCH 28/30] Add handling in the CheckMainFeatureForCSharpLanguageTest for possible failing after first initialization (#7966) * add handling for failing of LS by timeout --- ...CheckMainFeatureForCSharpLanguageTest.java | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/languageserver/CheckMainFeatureForCSharpLanguageTest.java b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/languageserver/CheckMainFeatureForCSharpLanguageTest.java index 4e7d4511680f..14057847aa1b 100644 --- a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/languageserver/CheckMainFeatureForCSharpLanguageTest.java +++ b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/languageserver/CheckMainFeatureForCSharpLanguageTest.java @@ -10,21 +10,31 @@ */ package org.eclipse.che.selenium.languageserver; +import static org.eclipse.che.selenium.core.constant.TestTimeoutsConstants.MINIMUM_SEC; import static org.eclipse.che.selenium.pageobject.CodenvyEditor.MarkersType.ERROR_MARKER; import com.google.inject.Inject; +import java.util.List; import org.eclipse.che.commons.lang.NameGenerator; +import org.eclipse.che.selenium.core.SeleniumWebDriver; +import org.eclipse.che.selenium.core.client.TestCommandServiceClient; import org.eclipse.che.selenium.core.constant.TestMenuCommandsConstants; import org.eclipse.che.selenium.core.workspace.InjectTestWorkspace; import org.eclipse.che.selenium.core.workspace.TestWorkspace; import org.eclipse.che.selenium.core.workspace.WorkspaceTemplate; import org.eclipse.che.selenium.pageobject.CodenvyEditor; +import org.eclipse.che.selenium.pageobject.Consoles; import org.eclipse.che.selenium.pageobject.Ide; import org.eclipse.che.selenium.pageobject.Loader; import org.eclipse.che.selenium.pageobject.Menu; import org.eclipse.che.selenium.pageobject.ProjectExplorer; import org.eclipse.che.selenium.pageobject.Wizard; +import org.eclipse.che.selenium.pageobject.intelligent.CommandsPalette; +import org.openqa.selenium.By; import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -32,6 +42,7 @@ public class CheckMainFeatureForCSharpLanguageTest { private final String PROJECT_NAME = NameGenerator.generate("AspProject", 4); + private final String COMMAND_NAME_FOR_RESTORE_LS = PROJECT_NAME + ": update dependencies"; @InjectTestWorkspace(template = WorkspaceTemplate.UBUNTU_LSP) private TestWorkspace workspace; @@ -42,6 +53,11 @@ public class CheckMainFeatureForCSharpLanguageTest { @Inject private CodenvyEditor editor; @Inject private Menu menu; @Inject private Wizard wizard; + @Inject private SeleniumWebDriver seleniumWebDriver; + @Inject private TestCommandServiceClient testCommandServiceClient; + @Inject private CommandsPalette commandsPalette; + + @Inject private Consoles consoles; @BeforeClass public void setUp() throws Exception { @@ -49,7 +65,7 @@ public void setUp() throws Exception { } @Test - public void checkLaunchingCodeserver() throws Exception { + public void checkLaunchingCodeserver() { projectExplorer.waitProjectExplorer(); menu.runCommand( TestMenuCommandsConstants.Workspace.WORKSPACE, @@ -62,6 +78,7 @@ public void checkLaunchingCodeserver() throws Exception { projectExplorer.waitItem(PROJECT_NAME + "/Program.cs", 240); projectExplorer.openItemByPath(PROJECT_NAME + "/Program.cs"); loader.waitOnClosed(); + checkLanguageServerInitStateAndLaunch(); editor.goToCursorPositionVisible(24, 12); for (int i = 0; i < 9; i++) { editor.typeTextIntoEditor(Keys.BACK_SPACE.toString()); @@ -75,4 +92,33 @@ public void checkLaunchingCodeserver() throws Exception { editor.typeTextIntoEditor(";"); editor.waitAllMarkersDisappear(ERROR_MARKER); } + + private void checkLanguageServerInitStateAndLaunch() { + if (isLanguageServerInitFailed()) { + reInitLanguageServer(); + } + } + + private void reInitLanguageServer() { + commandsPalette.openCommandPalette(); + commandsPalette.startCommandByDoubleClick(COMMAND_NAME_FOR_RESTORE_LS); + consoles.waitExpectedTextIntoConsole("Restore completed"); + editor.closeAllTabs(); + projectExplorer.openItemByPath(PROJECT_NAME + "/Program.cs"); + loader.waitOnClosed(); + } + + private boolean isLanguageServerInitFailed() { + String xpathLocatorForEventMessages = + "//div[contains(@id,'gwt-debug-notification-wrappergwt-uid')]"; + List textMessages = + new WebDriverWait(seleniumWebDriver, MINIMUM_SEC) + .until( + ExpectedConditions.presenceOfAllElementsLocatedBy( + By.xpath(xpathLocatorForEventMessages))); + return textMessages + .stream() + .anyMatch( + message -> message.getAttribute("textContent").contains("Timeout initializing error")); + } } From 758d400e5f36e4e18b227b8079b59655987c0125 Mon Sep 17 00:00:00 2001 From: Roman Iuvshyn Date: Wed, 20 Dec 2017 17:28:34 +0200 Subject: [PATCH 29/30] Clean up after merge che6 to master (#7979) --- .../src/main/resources/che-in-che.json | 4 ++-- .../init/modules/openshift/files/scripts/deploy_che.sh | 8 ++++---- .../files/scripts/multi-user/deploy_postgres_only.sh | 2 +- selenium/che-selenium-core/bin/webdriver.sh | 4 ++-- .../org/eclipse/che/selenium/pageobject/Preferences.java | 2 +- .../eclipse/che/selenium/gwt/CheckSimpleGwtAppTest.java | 2 +- .../CheckIntelligenceCommandFromToolbarTest.java | 6 +++--- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/assembly/assembly-wsmaster-war/src/main/resources/che-in-che.json b/assembly/assembly-wsmaster-war/src/main/resources/che-in-che.json index 91da42fdf9dc..4ee687c3fef6 100644 --- a/assembly/assembly-wsmaster-war/src/main/resources/che-in-che.json +++ b/assembly/assembly-wsmaster-war/src/main/resources/che-in-che.json @@ -24,7 +24,7 @@ ], "source": { "type": "image", - "origin": "eclipse/che-dev:che6" + "origin": "eclipse/che-dev:nightly" }, "workspaceConfig": { "environments": { @@ -68,7 +68,7 @@ } }, "recipe": { - "location": "eclipse/che-dev:che6", + "location": "eclipse/che-dev:nightly", "type": "dockerimage" } } diff --git a/dockerfiles/init/modules/openshift/files/scripts/deploy_che.sh b/dockerfiles/init/modules/openshift/files/scripts/deploy_che.sh index 5c267bbafd08..5903f480113b 100755 --- a/dockerfiles/init/modules/openshift/files/scripts/deploy_che.sh +++ b/dockerfiles/init/modules/openshift/files/scripts/deploy_che.sh @@ -8,11 +8,11 @@ # This script is meant for quick & easy install of Che on OpenShift via: # # ``` bash -# DEPLOY_SCRIPT_URL=https://raw.githubusercontent.com/eclipse/che/che6/dockerfiles/cli/scripts/openshift/deploy_che.sh +# DEPLOY_SCRIPT_URL=https://raw.githubusercontent.com/eclipse/che/master/dockerfiles/cli/scripts/openshift/deploy_che.sh # curl -fsSL ${DEPLOY_SCRIPT_URL} -o get-che.sh -# WAIT_SCRIPT_URL=https://raw.githubusercontent.com/eclipse/che/che6/dockerfiles/cli/scripts/openshift/wait_until_che_is_available.sh +# WAIT_SCRIPT_URL=https://raw.githubusercontent.com/eclipse/che/master/dockerfiles/cli/scripts/openshift/wait_until_che_is_available.sh # curl -fsSL ${WAIT_SCRIPT_URL} -o wait-che.sh -# STACKS_SCRIPT_URL=https://raw.githubusercontent.com/eclipse/che/che6/dockerfiles/cli/scripts/openshift/replace_stacks.sh +# STACKS_SCRIPT_URL=https://raw.githubusercontent.com/eclipse/che/master/dockerfiles/cli/scripts/openshift/replace_stacks.sh # curl -fsSL ${STACKS_SCRIPT_URL} -o stacks-che.sh # bash get-che.sh && wait-che.sh && stacks-che.sh # ``` @@ -182,7 +182,7 @@ CHE_OPENSHIFT_PROJECT=${CHE_OPENSHIFT_PROJECT:-${DEFAULT_CHE_OPENSHIFT_PROJECT}} DEFAULT_COMMAND="deploy" DEFAULT_CHE_MULTIUSER="false" DEFAULT_CHE_IMAGE_REPO="docker.io/eclipse/che-server" -DEFAULT_CHE_IMAGE_TAG="che6" +DEFAULT_CHE_IMAGE_TAG="nightly" DEFAULT_CHE_KEYCLOAK_OSO_ENDPOINT="https://sso.openshift.io/auth/realms/fabric8/broker/openshift-v3/token" DEFAULT_KEYCLOAK_GITHUB_ENDPOINT="https://sso.openshift.io/auth/realms/fabric8/broker/github/token" diff --git a/dockerfiles/init/modules/openshift/files/scripts/multi-user/deploy_postgres_only.sh b/dockerfiles/init/modules/openshift/files/scripts/multi-user/deploy_postgres_only.sh index 4079e736775b..2347350711fa 100755 --- a/dockerfiles/init/modules/openshift/files/scripts/multi-user/deploy_postgres_only.sh +++ b/dockerfiles/init/modules/openshift/files/scripts/multi-user/deploy_postgres_only.sh @@ -18,7 +18,7 @@ if [ "${CHE_EPHEMERAL}" == "true" ]; then oc delete pvc/postgres-data fi -IMAGE_INIT=${IMAGE_INIT:-"eclipse/che-init:che6"} +IMAGE_INIT=${IMAGE_INIT:-"eclipse/che-init:nightly"} oc create -f - <<-EOF diff --git a/selenium/che-selenium-core/bin/webdriver.sh b/selenium/che-selenium-core/bin/webdriver.sh index 32ff7fb61414..bebe6c8cd1ff 100755 --- a/selenium/che-selenium-core/bin/webdriver.sh +++ b/selenium/che-selenium-core/bin/webdriver.sh @@ -519,9 +519,9 @@ fetchActualResults() { # define the URL of CI job to compare result with result on it if [[ ${CHE_MULTIUSER} == true ]]; then - local nameOfCIJob=che-multiuser-integration-tests-che6 + local nameOfCIJob=che-multiuser-integration-tests else - local nameOfCIJob=che-integration-tests-che6 + local nameOfCIJob=che-integration-tests fi [[ -z ${BASE_ACTUAL_RESULTS_URL+x} ]] && { BASE_ACTUAL_RESULTS_URL="https://ci.codenvycorp.com/view/qa/job/$nameOfCIJob/"; } diff --git a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/Preferences.java b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/Preferences.java index d224e3e4a41a..cd4361410e7d 100644 --- a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/Preferences.java +++ b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/Preferences.java @@ -272,7 +272,7 @@ public boolean isSshKeyIsPresent(String host) { return sshKeysTable.getText().contains(host); } - // timeout is changed to 40 sec, is related to running tests on che6-ocp platform + // timeout is changed to 40 sec, is related to running tests on ocp platform public void waitSshKeyIsPresent(final String host) { new WebDriverWait(seleniumWebDriver, WIDGET_TIMEOUT_SEC) .until((ExpectedCondition) driver -> sshKeysTable.getText().contains(host)); diff --git a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/gwt/CheckSimpleGwtAppTest.java b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/gwt/CheckSimpleGwtAppTest.java index 3ea2390211a3..af7ebd4954b9 100644 --- a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/gwt/CheckSimpleGwtAppTest.java +++ b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/gwt/CheckSimpleGwtAppTest.java @@ -135,7 +135,7 @@ public void checkLaunchingCodeServer() throws Exception { .getUrl() .replace("tcp", "http"); - // the timeout needs for che6-ocp platform + // the timeout needs for ocp platform WaitUtils.sleepQuietly(10); seleniumWebDriver.get(url); diff --git a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/intelligencecommand/CheckIntelligenceCommandFromToolbarTest.java b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/intelligencecommand/CheckIntelligenceCommandFromToolbarTest.java index 200f10459cbd..29759678bcab 100644 --- a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/intelligencecommand/CheckIntelligenceCommandFromToolbarTest.java +++ b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/intelligencecommand/CheckIntelligenceCommandFromToolbarTest.java @@ -64,7 +64,7 @@ public void launchClonedWepAppTest() throws Exception { commandsToolbar.clickWithHoldAndLaunchCommandFromList(PROJECT_NAME + ": build and run"); consoles.waitExpectedTextIntoConsole(" Server startup in"); - // it needs when the test is running on the che6-ocp platform + // it needs when the test is running on the ocp platform String previewUrl = consoles.getPreviewUrl(); if (previewUrl.contains("route")) { WaitUtils.sleepQuietly(10); @@ -87,7 +87,7 @@ public void checkButtonsOnToolbar() { String currentWindow = seleniumWebDriver.getWindowHandle(); commandsToolbar.clickExecStopBtn(); - // it needs when the test is running on the che6-ocp platform + // it needs when the test is running on the ocp platform String previewUrl = consoles.getPreviewUrl(); String expectedText = previewUrl.contains("route") @@ -103,7 +103,7 @@ public void checkButtonsOnToolbar() { Assert.assertTrue(commandsToolbar.getTimerValue().matches("\\d\\d:\\d\\d")); Assert.assertTrue(commandsToolbar.getNumOfProcessCounter().equals("#2")); - // it needs when the test is running on the che6-ocp platform + // it needs when the test is running on the ocp platform if (previewUrl.contains("route")) { WaitUtils.sleepQuietly(10); } From 4025610db7dcc29a0e7ece70205b0f0c22bcb1d3 Mon Sep 17 00:00:00 2001 From: Maxim Musienko Date: Wed, 20 Dec 2017 17:42:06 +0200 Subject: [PATCH 30/30] Add assertion with known issue in the typical unstable part of the test (#7978) --- .../che/selenium/testrunner/JavaTestPluginTestNgTest.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/testrunner/JavaTestPluginTestNgTest.java b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/testrunner/JavaTestPluginTestNgTest.java index 2592c0fd2e73..cf6b25be2793 100644 --- a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/testrunner/JavaTestPluginTestNgTest.java +++ b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/testrunner/JavaTestPluginTestNgTest.java @@ -167,7 +167,12 @@ public void shouldExecuteAlltests() { editor.goToCursorPositionVisible(25, 17); menu.runCommand(RUN_MENU, TEST, TEST_NG_TEST_DROP_DAWN_ITEM); notifications.waitExpectedMessageOnProgressPanelAndClosed("Test runner executed successfully."); - pluginConsole.waitMethodMarkedAsPassed("shouldSuccessOfAppAnother"); + try { + pluginConsole.waitMethodMarkedAsPassed("shouldSuccessOfAppAnother"); + } catch (TimeoutException ex) { + // remove try-catch block after issue has been resolved + fail("Known issue https://github.com/eclipse/che/issues/7338", ex); + } assertTrue(pluginConsole.getAllNamesOfMethodsMarkedDefinedStatus(PASSED).size() == 1); editor.goToCursorPositionVisible(30, 17); menu.runCommand(RUN_MENU, TEST, TEST_NG_TEST_DROP_DAWN_ITEM);