Selenium: cover Yaml language server functionality by selenium test (#10525)

6.19.x
Sergey Skorik 2018-07-25 15:07:43 +03:00 committed by GitHub
parent 3467b2e6c2
commit da843e3f51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 565 additions and 1 deletions

View File

@ -27,6 +27,7 @@ public class WorkspaceTemplate {
public static final String PYTHON = "ubuntu_python.json";
public static final String NODEJS_WITH_JSON_LS = "nodejs_with_json_ls.json";
public static final String UBUNTU_CAMEL = "ubuntu_jdk8_with_camel_ls.json";
public static final String ECLIPSE_NODEJS_YAML = "eclipse_nodejs_with_yaml_ls.json";
private WorkspaceTemplate() {}
}

View File

@ -23,6 +23,7 @@ import static org.eclipse.che.selenium.pageobject.CodenvyEditor.Locators.ACTIVE_
import static org.eclipse.che.selenium.pageobject.CodenvyEditor.Locators.ALL_TABS_XPATH;
import static org.eclipse.che.selenium.pageobject.CodenvyEditor.Locators.ASSIST_CONTENT_CONTAINER;
import static org.eclipse.che.selenium.pageobject.CodenvyEditor.Locators.AUTOCOMPLETE_CONTAINER;
import static org.eclipse.che.selenium.pageobject.CodenvyEditor.Locators.AUTOCOMPLETE_PROPOSAL_DOC_ID;
import static org.eclipse.che.selenium.pageobject.CodenvyEditor.Locators.CONTEXT_MENU;
import static org.eclipse.che.selenium.pageobject.CodenvyEditor.Locators.DEBUGGER_BREAKPOINT_CONDITION;
import static org.eclipse.che.selenium.pageobject.CodenvyEditor.Locators.DEBUGGER_BREAKPOINT_DISABLED;
@ -205,7 +206,8 @@ public class CodenvyEditor {
String TOOLTIP_TITLE_CSS = "span.tooltipTitle";
String TEXT_TO_MOVE_CURSOR_XPATH =
ORION_ACTIVE_EDITOR_CONTAINER_XPATH + "//span[contains(text(),'%s')]";
String HOVER_POPUP_XPATH = "//div[@class='textviewTooltip']";
String HOVER_POPUP_XPATH = "//div[@class='textviewTooltip'][last()]";
String AUTOCOMPLETE_PROPOSAL_DOC_ID = "gwt-debug-content-assistant-doc-popup";
}
public enum TabActionLocator {
@ -334,6 +336,9 @@ public class CodenvyEditor {
@FindBy(xpath = HOVER_POPUP_XPATH)
private WebElement hoverPopup;
@FindBy(id = AUTOCOMPLETE_PROPOSAL_DOC_ID)
private WebElement proposalDoc;
/**
* Waits during {@code timeout} until current editor's tab is ready to work.
*
@ -2167,4 +2172,17 @@ public class CodenvyEditor {
seleniumWebDriverHelper.moveCursorTo(
By.xpath(format(Locators.TEXT_TO_MOVE_CURSOR_XPATH, text)));
}
public void checkProposalDocumentation(String expectedText) {
seleniumWebDriverHelper.waitTextContains(proposalDoc, expectedText);
}
public void launchCommentCodeFeature() {
actionsFactory
.createAction(seleniumWebDriver)
.keyDown(CONTROL)
.sendKeys("/")
.keyUp(CONTROL)
.perform();
}
}

View File

@ -123,6 +123,8 @@ public class Preferences {
"gwt-debug-preferences-git-contribute-activateByProjectSelection";
String SHOW_CONTRIBUTE_CHECKBOX_ID =
"gwt-debug-preferences-git-contribute-activateByProjectSelection-input";
String ADD_SCHEMA_URL_BUTTON_ID = "gwt-debug-preferences-addUrl";
String ADD_SCHEMA_URL_INPUT_ID = "gwt-debug-askValueDialog-textBox";
}
public interface DropDownListsHeaders {
@ -138,6 +140,10 @@ public class Preferences {
String MACHINE = "Machine";
}
public interface DropDownLanguageServerSettings {
String YAML = "Yaml";
}
public interface DropDownGitInformationMenu {
String COMMITTER = "Committer";
String CONTRIBUTE_PREFERENCES = "Contribute";
@ -216,6 +222,12 @@ public class Preferences {
@FindBy(id = Locators.SHOW_CONTRIBUTE_CHECKBOX_ID)
private WebElement showContributeCheckbox;
@FindBy(id = Locators.ADD_SCHEMA_URL_BUTTON_ID)
private WebElement addSchemaUrlButton;
@FindBy(id = Locators.ADD_SCHEMA_URL_INPUT_ID)
private WebElement addSchemaUrlInput;
/** wait preferences form */
public void waitPreferencesForm() {
new WebDriverWait(seleniumWebDriver, LOAD_PAGE_TIMEOUT_SEC)
@ -311,6 +323,16 @@ public class Preferences {
.click();
}
public void clickOnAddSchemaUrlButton() {
webDriverHelper.waitAndClick(addSchemaUrlButton);
}
public void addSchemaUrl(String schemaName) {
webDriverHelper.waitVisibility(addSchemaUrlInput);
addSchemaUrlInput.sendKeys(schemaName);
webDriverHelper.waitAndClick(By.id("askValue-dialog-ok"));
}
public void clickOnGenerateAndUploadToGitHub() {
new WebDriverWait(seleniumWebDriver, LOAD_PAGE_TIMEOUT_SEC)
.until(visibilityOf(generateAndUploadBtn))

View File

@ -0,0 +1,227 @@
/*
* Copyright (c) 2012-2018 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.languageserver;
import static java.lang.String.format;
import static org.eclipse.che.commons.lang.NameGenerator.generate;
import static org.eclipse.che.selenium.core.constant.TestMenuCommandsConstants.Profile.PREFERENCES;
import static org.eclipse.che.selenium.core.constant.TestMenuCommandsConstants.Profile.PROFILE_MENU;
import static org.eclipse.che.selenium.core.project.ProjectTemplates.NODE_JS;
import static org.eclipse.che.selenium.core.workspace.WorkspaceTemplate.ECLIPSE_NODEJS_YAML;
import static org.eclipse.che.selenium.pageobject.CodenvyEditor.MarkerLocator.ERROR;
import static org.eclipse.che.selenium.pageobject.Preferences.DropDownLanguageServerSettings.YAML;
import static org.openqa.selenium.Keys.DELETE;
import static org.openqa.selenium.Keys.ENTER;
import com.google.inject.Inject;
import java.net.URL;
import java.nio.file.Paths;
import org.eclipse.che.selenium.core.client.TestProjectServiceClient;
import org.eclipse.che.selenium.core.constant.TestMenuCommandsConstants.Project;
import org.eclipse.che.selenium.core.constant.TestMenuCommandsConstants.Project.New;
import org.eclipse.che.selenium.core.workspace.InjectTestWorkspace;
import org.eclipse.che.selenium.core.workspace.TestWorkspace;
import org.eclipse.che.selenium.pageobject.AskForValueDialog;
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.Menu;
import org.eclipse.che.selenium.pageobject.Preferences;
import org.eclipse.che.selenium.pageobject.ProjectExplorer;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class YamlFileEditingTest {
private static final String PROJECT_NAME = generate("project", 4);
private static final String YAML_FILE_NAME = "openshift.yaml";
private static final String PATH_TO_YAML_FILE = PROJECT_NAME + "/" + YAML_FILE_NAME;
private static final String LS_INIT_MESSAGE =
format("Finished language servers initialization, file path '/%s'", PATH_TO_YAML_FILE);
private static final String COMMENTED_CODE =
"# generation: 4\n"
+ " labels:\n"
+ "# app: che\n"
+ " template: che\n"
+ "# name: che";
private static final String UNCOMMENTED_CODE =
" generation: 4\n"
+ " labels:\n"
+ " app: che\n"
+ " template: che\n"
+ " name: che";
@InjectTestWorkspace(template = ECLIPSE_NODEJS_YAML)
private TestWorkspace workspace;
@Inject private Ide ide;
@Inject private Menu menu;
@Inject private Consoles consoles;
@Inject private CodenvyEditor editor;
@Inject private Preferences preferences;
@Inject private ProjectExplorer projectExplorer;
@Inject private AskForValueDialog askForValueDialog;
@Inject private TestProjectServiceClient testProjectServiceClient;
@BeforeClass
public void setUp() throws Exception {
URL resource = YamlFileEditingTest.class.getResource("/projects/nodejs-with-yaml");
testProjectServiceClient.importProject(
workspace.getId(), Paths.get(resource.toURI()), PROJECT_NAME, NODE_JS);
ide.open(workspace);
ide.waitOpenedWorkspaceIsReadyToUse();
addYamlSchema();
}
@Test
public void checkLanguageServerInitialized() {
projectExplorer.waitAndSelectItem(PROJECT_NAME);
menu.runCommand(Project.PROJECT, New.NEW, New.FILE);
askForValueDialog.createNotJavaFileByName(YAML_FILE_NAME);
editor.waitTabIsPresent(YAML_FILE_NAME);
projectExplorer.openItemByPath(PROJECT_NAME + "/deployment.yaml");
editor.waitTabIsPresent("deployment.yaml");
// check Yaml language server initialized
consoles.selectProcessByTabName("dev-machine");
consoles.waitExpectedTextIntoConsole(LS_INIT_MESSAGE);
}
@Test(priority = 1)
public void checkAutocompleteFeature() {
editor.selectTabByName(YAML_FILE_NAME);
// launch autocomplete feature and check proposal documentation
editor.launchAutocompleteAndWaitContainer();
editor.waitTextIntoAutocompleteContainer("diskName");
editor.selectAutocompleteProposal("diskName");
editor.checkProposalDocumentation("The Name of the data disk in the blob storage");
editor.waitTextIntoAutocompleteContainer("diskURI");
editor.selectAutocompleteProposal("diskURI");
editor.checkProposalDocumentation("The URI the data disk in the blob storage");
// select proposal and check expected text in the Editor
editor.enterAutocompleteProposal("kind");
editor.launchAutocompleteAndWaitContainer();
editor.waitTextIntoAutocompleteContainer("PersistentVolume");
editor.enterAutocompleteProposal("PersistentVolume");
editor.waitTextIntoEditor("kind: PersistentVolume");
editor.typeTextIntoEditor(ENTER.toString());
editor.typeTextIntoEditor(ENTER.toString());
// launch autocomplete feature and check expected text in the Editor
editor.typeTextIntoEditor("api");
editor.launchAutocomplete();
editor.waitTextIntoEditor("apiVersion: ");
editor.launchAutocomplete();
editor.waitTextIntoEditor("apiVersion: v1");
editor.typeTextIntoEditor(ENTER.toString());
editor.typeTextIntoEditor(ENTER.toString());
// launch autocomplete feature, select proposal and check expected text in the Editor
editor.typeTextIntoEditor("me");
editor.launchAutocomplete();
editor.waitTextIntoEditor("metadata:");
editor.launchAutocompleteAndWaitContainer();
editor.waitTextIntoAutocompleteContainer("status");
editor.enterAutocompleteProposal("status");
editor.waitMarkerInPosition(ERROR, 4);
editor.moveToMarkerAndWaitAssistContent(ERROR);
editor.waitTextIntoAnnotationAssist("Using tabs can lead to unpredictable results");
editor.goToPosition(4, 1);
editor.typeTextIntoEditor(DELETE.toString());
editor.waitMarkerInvisibility(ERROR, 4);
editor.goToPosition(5, 1);
editor.launchAutocomplete();
editor.waitTextIntoEditor("spec:");
}
@Test(priority = 1)
public void checkHoverFeature() {
editor.selectTabByName("deployment.yaml");
// move cursor on text and check expected text in hover popup
editor.moveCursorToText("namespace:");
editor.waitTextInHoverPopup("Namespace defines the space within each name must be unique.");
editor.moveCursorToText("kind:");
editor.waitTextInHoverPopup(
"Kind is a string value representing the REST resource this object represents.");
editor.moveCursorToText("apiVersion:");
editor.waitTextInHoverPopup(
"APIVersion defines the versioned schema of this representation of an object.");
}
@Test(priority = 1)
public void checkCodeValidation() {
editor.selectTabByName("deployment.yaml");
editor.waitAllMarkersInvisibility(ERROR);
editor.goToPosition(12, 2);
editor.typeTextIntoEditor("a");
editor.moveCursorToText("aapiVersion");
editor.waitTextInHoverPopup("Unexpected property aapiVersion");
editor.goToPosition(12, 1);
editor.typeTextIntoEditor(DELETE.toString());
editor.waitAllMarkersInvisibility(ERROR);
editor.moveCursorToText("apiVersion:");
editor.waitTextInHoverPopup(
"APIVersion defines the versioned schema of this representation of an object.");
}
@Test(priority = 1)
public void checkCommentCodeFeature() {
editor.selectTabByName("deployment.yaml");
// comment lines by Ctrl+'/' buttons
editor.goToPosition(18, 1);
editor.launchCommentCodeFeature();
editor.waitTextIntoEditor("# generation: 4");
editor.goToPosition(20, 1);
editor.launchCommentCodeFeature();
editor.goToPosition(22, 1);
editor.launchCommentCodeFeature();
editor.waitTextIntoEditor(COMMENTED_CODE);
// uncomment all commented lines
editor.goToPosition(18, 1);
editor.launchCommentCodeFeature();
editor.goToPosition(20, 1);
editor.launchCommentCodeFeature();
editor.goToPosition(22, 1);
editor.launchCommentCodeFeature();
editor.waitTextIntoEditor(UNCOMMENTED_CODE);
}
private void addYamlSchema() {
menu.runCommand(PROFILE_MENU, PREFERENCES);
preferences.waitPreferencesForm();
preferences.waitMenuInCollapsedDropdown(YAML);
preferences.selectDroppedMenuByName(YAML);
preferences.clickOnAddSchemaUrlButton();
preferences.addSchemaUrl("kubernetes");
preferences.clickOnOkBtn();
preferences.closeForm();
}
}

View File

@ -0,0 +1,211 @@
#
# Copyright (c) 2012-2018 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
#
apiVersion: v1
kind: DeploymentConfig
metadata:
annotations:
openshift.io/generated-by: OpenShiftNewApp
creationTimestamp: '2018-07-17T11:11:50Z'
generation: 4
labels:
app: che
template: che
name: che
namespace: eclipse-che
resourceVersion: '9713'
selfLink: /apis/apps.openshift.io/v1/namespaces/eclipse-che/deploymentconfigs/che
uid: 33bda3fd-89b2-11e8-be77-8c1645547d72
spec:
replicas: 1
revisionHistoryLimit: 2
selector:
app: che
strategy:
activeDeadlineSeconds: 21600
recreateParams:
timeoutSeconds: 600
resources: {}
type: Recreate
template:
metadata:
annotations:
openshift.io/generated-by: OpenShiftNewApp
creationTimestamp: "null"
labels:
app: che
spec:
containers:
- env:
- name: CHE_CONF
value: /home/user/che-conf
- name: CHE_IMAGE_REPO
value: eclipse/che-server
- name: CHE_IMAGE_TAG
value: nightly
- name: CHE_INFRASTRUCTURE
value: openshift
- name: CHE_INFRA_KUBERNETES_MASTER__URL
value: 'https://172.0.0.1:8443'
- name: CHE_LOCAL_CONF_DIR
value: /home/user/che-conf
- name: CHE_MULTIUSER
value: 'false'
- name: CHE_OPENSHIFT_PROJECT
value: eclipse-che
- name: OPENSHIFT_KUBE_PING_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: CHE_HOST
value: 'che-${NAMESPACE}.172.0.0.1.nip.io'
- name: CHE_PORT
value: '8080'
- name: CHE_API
value: 'http://che-${NAMESPACE}.172.0.0.1.nip.io/api'
- name: CHE_WEBSOCKET_ENDPOINT
value: 'ws://che-${NAMESPACE}.172.0.0.1.nip.io/api/websocket'
- name: CHE_DEBUG_SERVER
value: 'false'
- name: CHE_INFRASTRUCTURE_ACTIVE
value: openshift
- name: CHE_INFRA_KUBERNETES_BOOTSTRAPPER_BINARY__URL
value: >-
http://che-${NAMESPACE}.172.0.0.1.nip.io/agent-binaries/linux_amd64/bootstrapper/bootstrapper
- name: CHE_INFRA_KUBERNETES_MACHINE__START__TIMEOUT__MIN
value: '5'
- name: CHE_INFRA_KUBERNETES_OAUTH__TOKEN
- name: CHE_INFRA_KUBERNETES_USERNAME
- name: CHE_INFRA_KUBERNETES_PASSWORD
- name: CHE_INFRA_OPENSHIFT_PROJECT
value: eclipse-che
- name: CHE_INFRA_KUBERNETES_PVC_STRATEGY
value: unique
- name: CHE_INFRA_KUBERNETES_PVC_PRECREATE__SUBPATHS
value: 'false'
- name: CHE_INFRA_OPENSHIFT_TLS__ENABLED
value: 'false'
- name: CHE_INFRA_KUBERNETES_TRUST__CERTS
value: 'false'
- name: CHE_LOGS_DIR
value: /data/logs
- name: CHE_LOG_LEVEL
value: INFO
- name: CHE_KEYCLOAK_AUTH__SERVER__URL
value: '${PROTOCOL}://keycloak-${NAMESPACE}.${ROUTING_SUFFIX}/auth'
- name: CHE_INFRA_OPENSHIFT_OAUTH__IDENTITY__PROVIDER
value: 'NULL'
- name: CHE_PREDEFINED_STACKS_RELOAD__ON__START
value: 'true'
- name: JAVA_OPTS
value: >-
-XX:MaxRAMFraction=2 -XX:+UseParallelGC -XX:MinHeapFreeRatio=10
-XX:MaxHeapFreeRatio=20 -XX:GCTimeRatio=4
-XX:AdaptiveSizePolicyWeight=90 -XX:+UnlockExperimentalVMOptions
-XX:+UseCGroupMemoryLimitForHeap
-Dsun.zip.disableMemoryMapping=true -Xms20m
- name: CHE_WORKSPACE_AUTO_START
value: 'false'
- name: CHE_INFRA_KUBERNETES_PVC_QUANTITY
value: 1Gi
- name: PROTOCOL
value: http
- name: ROUTING_SUFFIX
value: 172.19.20.234.nip.io
- name: OPENSHIFT_IDENTITY_PROVIDER_CERTIFICATE
valueFrom:
secretKeyRef:
key: ca.crt
name: openshift-identity-provider
optional: true
- name: CHE_WORKSPACE_FEATURE_API
value: 'http://marketplace:80'
image: 'eclipse/che-server:latest'
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
httpGet:
path: /api/system/state
port: 8080
scheme: HTTP
initialDelaySeconds: 50
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
name: che
ports:
- containerPort: 8080
name: http
protocol: TCP
readinessProbe:
failureThreshold: 5
httpGet:
path: /api/system/state
port: 8080
scheme: HTTP
initialDelaySeconds: 25
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
resources:
limits:
memory: 1Gi
requests:
memory: 256Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /data
name: che-data-volume
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: che
serviceAccountName: che
terminationGracePeriodSeconds: 360
volumes:
- name: che-data-volume
persistentVolumeClaim:
claimName: che-data-volume
test: false
triggers:
- type: ConfigChange
status:
availableReplicas: 1
conditions:
- lastTransitionTime: '2018-07-17T12:49:00Z'
lastUpdateTime: '2018-07-17T12:49:00Z'
message: Deployment config has minimum availability.
status: 'True'
type: Available
- lastTransitionTime: '2018-07-17T12:47:37Z'
lastUpdateTime: '2018-07-17T12:49:29Z'
message: replication controller "che-4" successfully rolled out
reason: NewReplicationControllerAvailable
status: 'True'
type: Progressing
details:
causes:
- type: ConfigChange
message: config change
latestVersion: 4
observedGeneration: 4
readyReplicas: 1
replicas: 1
unavailableReplicas: 0
updatedReplicas: 1

View File

@ -54,6 +54,7 @@
<class name="org.eclipse.che.selenium.languageserver.ClangFileEditingTest"/>
<class name="org.eclipse.che.selenium.languageserver.ApacheCamelFileEditingTest"/>
<class name="org.eclipse.che.selenium.languageserver.JsonFileEditingTest"/>
<class name="org.eclipse.che.selenium.languageserver.YamlFileEditingTest"/>
<class name="org.eclipse.che.selenium.dashboard.CreateAndDeleteProjectsTest"/>
<class name="org.eclipse.che.selenium.dashboard.DeleteRunningWorkspaceTest"/>
<class name="org.eclipse.che.selenium.dashboard.DeleteStoppingWorkspaceTest"/>

View File

@ -0,0 +1,42 @@
{
"name": "replaced_name",
"environments": {
"replaced_name": {
"machines": {
"dev-machine": {
"attributes": {
"memoryLimitBytes": "desired_memory_value"
},
"installers": [
"org.eclipse.che.terminal",
"org.eclipse.che.ws-agent",
"org.eclipse.che.exec",
"org.eclipse.che.ls.yaml"
],
"servers": {
"3000/tcp" : {
"port" : "3000",
"protocol" : "http"
},
"5000/tcp" : {
"port" : "5000",
"protocol" : "http"
},
"9000/tcp" : {
"port" : "9000",
"protocol" : "http"
}
}
}
},
"recipe": {
"location": "eclipse/node",
"type": "dockerimage"
}
}
},
"commands": [],
"projects": [],
"defaultEnv": "replaced_name",
"links": []
}

View File

@ -0,0 +1,42 @@
{
"name": "replaced_name",
"environments": {
"replaced_name": {
"machines": {
"dev-machine": {
"attributes": {
"memoryLimitBytes": "desired_memory_value"
},
"installers": [
"org.eclipse.che.terminal",
"org.eclipse.che.ws-agent",
"org.eclipse.che.exec",
"org.eclipse.che.ls.yaml"
],
"servers": {
"3000/tcp" : {
"port" : "3000",
"protocol" : "http"
},
"5000/tcp" : {
"port" : "5000",
"protocol" : "http"
},
"9000/tcp" : {
"port" : "9000",
"protocol" : "http"
}
}
}
},
"recipe": {
"location": "eclipse/node",
"type": "dockerimage"
}
}
},
"commands": [],
"projects": [],
"defaultEnv": "replaced_name",
"links": []
}