diff --git a/plugins/plugin-github/che-plugin-github-ide/pom.xml b/plugins/plugin-github/che-plugin-github-ide/pom.xml index 2cdefba643..95b5770dc4 100644 --- a/plugins/plugin-github/che-plugin-github-ide/pom.xml +++ b/plugins/plugin-github/che-plugin-github-ide/pom.xml @@ -50,6 +50,10 @@ org.eclipse.che.core che-core-api-dto + + org.eclipse.che.core + che-core-api-git-shared + org.eclipse.che.core che-core-api-ssh-shared @@ -75,6 +79,10 @@ org.eclipse.che.core che-core-ide-ui + + org.eclipse.che.plugin + che-plugin-git-ext-git + org.eclipse.che.plugin che-plugin-github-shared diff --git a/plugins/plugin-github/che-plugin-github-ide/src/main/java/org/eclipse/che/plugin/github/ide/GitHubExtension.java b/plugins/plugin-github/che-plugin-github-ide/src/main/java/org/eclipse/che/plugin/github/ide/GitHubExtension.java index 08286974f0..9209f8e037 100644 --- a/plugins/plugin-github/che-plugin-github-ide/src/main/java/org/eclipse/che/plugin/github/ide/GitHubExtension.java +++ b/plugins/plugin-github/che-plugin-github-ide/src/main/java/org/eclipse/che/plugin/github/ide/GitHubExtension.java @@ -11,9 +11,15 @@ */ package org.eclipse.che.plugin.github.ide; +import static org.eclipse.che.ide.api.action.IdeActions.GROUP_EDITOR_CONTEXT_MENU; +import static org.eclipse.che.ide.api.action.IdeActions.GROUP_MAIN_CONTEXT_MENU; + import com.google.inject.Inject; import com.google.inject.Singleton; +import org.eclipse.che.ide.api.action.ActionManager; +import org.eclipse.che.ide.api.action.DefaultActionGroup; import org.eclipse.che.ide.api.extension.Extension; +import org.eclipse.che.plugin.github.ide.action.OpenOnGitHubAction; import org.eclipse.che.plugin.ssh.key.client.SshKeyUploaderRegistry; /** @@ -29,7 +35,18 @@ public class GitHubExtension { @Inject public GitHubExtension( - SshKeyUploaderRegistry registry, GitHubSshKeyUploader gitHubSshKeyProvider) { + SshKeyUploaderRegistry registry, + GitHubSshKeyUploader gitHubSshKeyProvider, + ActionManager actionManager, + OpenOnGitHubAction openOnGitHubAction) { + registry.registerUploader(GITHUB_HOST, gitHubSshKeyProvider); + actionManager.registerAction("openOnGitHub", openOnGitHubAction); + DefaultActionGroup mainContextMenuGroup = + (DefaultActionGroup) actionManager.getAction(GROUP_MAIN_CONTEXT_MENU); + mainContextMenuGroup.add(openOnGitHubAction); + DefaultActionGroup editorContextMenuGroup = + (DefaultActionGroup) actionManager.getAction(GROUP_EDITOR_CONTEXT_MENU); + editorContextMenuGroup.add(openOnGitHubAction); } } diff --git a/plugins/plugin-github/che-plugin-github-ide/src/main/java/org/eclipse/che/plugin/github/ide/GitHubLocalizationConstant.java b/plugins/plugin-github/che-plugin-github-ide/src/main/java/org/eclipse/che/plugin/github/ide/GitHubLocalizationConstant.java index ca23bc67c9..2ed86ec768 100644 --- a/plugins/plugin-github/che-plugin-github-ide/src/main/java/org/eclipse/che/plugin/github/ide/GitHubLocalizationConstant.java +++ b/plugins/plugin-github/che-plugin-github-ide/src/main/java/org/eclipse/che/plugin/github/ide/GitHubLocalizationConstant.java @@ -101,4 +101,8 @@ public interface GitHubLocalizationConstant extends Messages { @Key("view.import.githubImporterPage.branch") String githubImporterPageBranch(); + + @Key("open.on.github.action") + @DefaultMessage("Open on GitHub") + String openOnGitHubAction(); } diff --git a/plugins/plugin-github/che-plugin-github-ide/src/main/java/org/eclipse/che/plugin/github/ide/action/OpenOnGitHubAction.java b/plugins/plugin-github/che-plugin-github-ide/src/main/java/org/eclipse/che/plugin/github/ide/action/OpenOnGitHubAction.java new file mode 100644 index 0000000000..1987674d58 --- /dev/null +++ b/plugins/plugin-github/che-plugin-github-ide/src/main/java/org/eclipse/che/plugin/github/ide/action/OpenOnGitHubAction.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2012-2018 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.github.ide.action; + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import com.google.web.bindery.event.shared.EventBus; +import java.util.Collections; +import org.eclipse.che.ide.api.action.ActionEvent; +import org.eclipse.che.ide.api.action.BaseAction; +import org.eclipse.che.ide.api.app.AppContext; +import org.eclipse.che.ide.api.editor.EditorAgent; +import org.eclipse.che.ide.api.editor.EditorPartPresenter; +import org.eclipse.che.ide.api.editor.document.Document; +import org.eclipse.che.ide.api.editor.texteditor.TextEditor; +import org.eclipse.che.ide.api.notification.NotificationManager; +import org.eclipse.che.ide.api.parts.ActivePartChangedEvent; +import org.eclipse.che.ide.api.parts.ActivePartChangedHandler; +import org.eclipse.che.ide.api.resources.Project; +import org.eclipse.che.ide.api.resources.Resource; +import org.eclipse.che.ide.ext.git.client.GitServiceClient; +import org.eclipse.che.ide.resource.Path; +import org.eclipse.che.ide.util.browser.BrowserUtils; +import org.eclipse.che.plugin.github.ide.GitHubLocalizationConstant; +import org.eclipse.che.plugin.github.shared.GitHubUrlUtils; + +/** @author Vitalii Parfonov */ +@Singleton +public class OpenOnGitHubAction extends BaseAction implements ActivePartChangedHandler { + + private EditorAgent editorAgent; + private GitServiceClient gitServiceClient; + private final AppContext appContext; + private NotificationManager notificationManager; + private boolean editorInFocus; + + @Inject + public OpenOnGitHubAction( + EditorAgent editorAgent, + GitHubLocalizationConstant locale, + GitServiceClient gitServiceClient, + EventBus eventBus, + AppContext appContext, + NotificationManager notificationManager) { + super(locale.openOnGitHubAction()); + this.editorAgent = editorAgent; + this.gitServiceClient = gitServiceClient; + this.appContext = appContext; + this.notificationManager = notificationManager; + eventBus.addHandler(ActivePartChangedEvent.TYPE, this); + } + + /** {@inheritDoc} */ + @Override + public void update(ActionEvent event) { + final Resource resources = appContext.getResource(); + String gitRepoUrl = resources.getProject().getAttribute("git.repository.remotes"); + if (GitHubUrlUtils.isGitHubUrl(gitRepoUrl)) { + event.getPresentation().setEnabledAndVisible(true); + } else { + event.getPresentation().setEnabledAndVisible(false); + } + } + + /** {@inheritDoc} */ + @Override + public void actionPerformed(ActionEvent event) { + if (editorInFocus) { + final EditorPartPresenter editorPart = editorAgent.getActiveEditor(); + if (editorPart == null || !(editorPart instanceof TextEditor)) { + return; + } + Document document = ((TextEditor) editorPart).getDocument(); + openOnGitHubUrl(document); + } else { + Resource resource = appContext.getResource(); + openOnGitHubUrl(resource); + } + } + + private void openOnGitHubUrl(Document document) { + Resource file = (Resource) document.getFile(); + Project project = file.getProject(); + Path projectPath = project.getLocation(); + String httpsUrl = getGitHubRepositoryUrl(project); + String filePath = file.getLocation().makeRelativeTo(projectPath).toString(); + int lineStart; + int lineEnd; + if (document.getSelectedTextRange() != null) { + lineStart = document.getSelectedTextRange().getFrom().getLine() + 1; + lineEnd = document.getSelectedTextRange().getTo().getLine() + 1; + } else { + lineStart = lineEnd = document.getCursorPosition().getLine() + 1; + } + + gitServiceClient + .getStatus(projectPath, Collections.emptyList()) + .then( + status -> { + String refName = status.getRefName(); + String blobUrl = + GitHubUrlUtils.getBlobUrl(httpsUrl, refName, filePath, lineStart, lineEnd); + BrowserUtils.openInNewTab(blobUrl); + }) + .catchError( + error -> { + notificationManager.notify("", error.getMessage()); + }); + } + + private void openOnGitHubUrl(Resource resource) { + final Project project = resource.getProject(); + Path projectPath = project.getLocation(); + String httpsUrl = getGitHubRepositoryUrl(project); + String path = resource.getLocation().makeRelativeTo(projectPath).toString(); + gitServiceClient + .getStatus(projectPath, Collections.emptyList()) + .then( + status -> { + String url; + if (resource.isFile()) { + url = GitHubUrlUtils.getBlobUrl(httpsUrl, status.getRefName(), path); + } else { + url = GitHubUrlUtils.getTreeUrl(httpsUrl, status.getRefName(), path); + } + BrowserUtils.openInNewTab(url); + }) + .catchError( + error -> { + notificationManager.notify("", error.getMessage()); + }); + } + + private String getGitHubRepositoryUrl(Project project) { + String gitRepoUrl = project.getAttribute("git.repository.remotes"); + return GitHubUrlUtils.toHttpsIfNeed(gitRepoUrl); + } + + @Override + public void onActivePartChanged(ActivePartChangedEvent event) { + editorInFocus = event.getActivePart() instanceof EditorPartPresenter; + } +} diff --git a/plugins/plugin-github/che-plugin-github-shared/pom.xml b/plugins/plugin-github/che-plugin-github-shared/pom.xml index c929ade8aa..758a6d0f1d 100644 --- a/plugins/plugin-github/che-plugin-github-shared/pom.xml +++ b/plugins/plugin-github/che-plugin-github-shared/pom.xml @@ -22,6 +22,10 @@ che-plugin-github-shared Che Plugin :: Github :: Shared + + com.google.guava + guava + org.eclipse.che.core che-core-api-dto @@ -30,5 +34,10 @@ org.eclipse.che.core che-core-commons-annotations + + org.testng + testng + test + diff --git a/plugins/plugin-github/che-plugin-github-shared/src/main/java/org/eclipse/che/plugin/github/shared/GitHubUrlUtils.java b/plugins/plugin-github/che-plugin-github-shared/src/main/java/org/eclipse/che/plugin/github/shared/GitHubUrlUtils.java new file mode 100644 index 0000000000..369ddb396e --- /dev/null +++ b/plugins/plugin-github/che-plugin-github-shared/src/main/java/org/eclipse/che/plugin/github/shared/GitHubUrlUtils.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2012-2018 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.github.shared; + +import com.google.common.base.Strings; + +public class GitHubUrlUtils { + + /** + * normalize git@ and https:git@ urls + * + * @param gitUrl + * @return + */ + public static String toHttpsIfNeed(String gitUrl) { + if (Strings.isNullOrEmpty(gitUrl)) { + return gitUrl; + } + String gitRepoUrl = gitUrl; + + if (gitUrl.startsWith("git@")) { + // normalize git@ and https:git@ urls + gitRepoUrl = gitUrl.replaceFirst("git@", "https://"); + gitRepoUrl = gitRepoUrl.replaceFirst(".com:", ".com/"); + } + if (gitRepoUrl.endsWith(".git")) { + gitRepoUrl = gitRepoUrl.substring(0, gitRepoUrl.lastIndexOf(".git")); + } + return gitRepoUrl; + } + + public static String getBlobUrl(String rootGitRepoUrl, String ref, String path) { + return getBlobUrl(rootGitRepoUrl, ref, path, 0, 0); + } + + public static String getBlobUrl( + String rootGitRepoUrl, String ref, String path, int lineStart, int lineEnd) { + return rootGitRepoUrl + + "/blob/" + + ref + + "/" + + path + + (lineStart > 0 ? "#L" + lineStart : "") + + (lineEnd > 0 ? "-L" + lineEnd : ""); + } + + public static String getTreeUrl(String rootGitRepoUrl, String ref, String path) { + return rootGitRepoUrl + "/tree/" + ref + "/" + path; + } + + public static boolean isGitHubUrl(String rootGitRepoUrl) { + if (Strings.isNullOrEmpty(rootGitRepoUrl)) { + return false; + } + return rootGitRepoUrl.startsWith("git@") || rootGitRepoUrl.startsWith("https://github.com"); + } +} diff --git a/plugins/plugin-github/che-plugin-github-shared/src/test/java/org/eclipse/che/plugin/github/GitHUbUrlUtilsTest.java b/plugins/plugin-github/che-plugin-github-shared/src/test/java/org/eclipse/che/plugin/github/GitHUbUrlUtilsTest.java new file mode 100644 index 0000000000..9772dbf9b6 --- /dev/null +++ b/plugins/plugin-github/che-plugin-github-shared/src/test/java/org/eclipse/che/plugin/github/GitHUbUrlUtilsTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2012-2018 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.github; + +import static org.testng.Assert.assertEquals; + +import org.eclipse.che.plugin.github.shared.GitHubUrlUtils; +import org.testng.annotations.Test; + +public class GitHUbUrlUtilsTest { + + private String HTTPS_URL = "https://github.com/che-samples/web-java-spring-petclinic"; + private String SOME_PATH = "che/samples/web-java-spring-petclinic"; + private String SSH_URL = "git@github.com:che-samples/web-java-spring-petclinic.git"; + private String BLOB_URL = + "https://github.com/che-samples/web-java-spring-petclinic/blob/mysql/src/test/java/org/springframework" + + "/samples/petclinic/service/ClinicServiceJdbcTests.java"; + private String FILE = + "src/test/java/org/springframework" + + "/samples/petclinic/service/ClinicServiceJdbcTests.java"; + + @Test + public void shouldConvertToHttps() { + String https = GitHubUrlUtils.toHttpsIfNeed(SSH_URL); + assertEquals(https, HTTPS_URL); + } + + @Test + public void shouldReturnSameUrl() { + String https = GitHubUrlUtils.toHttpsIfNeed(HTTPS_URL); + assertEquals(https, HTTPS_URL); + } + + @Test + public void blobUrl() { + String blobUrl = + GitHubUrlUtils.getBlobUrl( + HTTPS_URL, + "mysql", + "src/test/java/org/springframework" + + "/samples/petclinic/service/ClinicServiceJdbcTests.java"); + assertEquals(blobUrl, BLOB_URL); + } + + @Test + public void blobUrlWithLines() { + String blobUrl = + GitHubUrlUtils.getBlobUrl( + HTTPS_URL, + "mysql", + "src/test/java/org/springframework" + + "/samples/petclinic/service/ClinicServiceJdbcTests.java", + 10, + 20); + assertEquals(blobUrl, BLOB_URL + "#L10-L20"); + } + + @Test + public void getTreeUrl() { + String rootGitRepoUrl = "https://github.com/eclipse/che/"; + String ref = "master"; + String path = "assembly/assembly-wsmaster-war"; + String getTreeUrl = GitHubUrlUtils.getTreeUrl(rootGitRepoUrl, ref, path); + assertEquals(getTreeUrl, rootGitRepoUrl + "/tree/" + ref + "/" + path); + } +} diff --git a/selenium/che-selenium-core/src/main/java/org/eclipse/che/selenium/core/client/TestProjectServiceClient.java b/selenium/che-selenium-core/src/main/java/org/eclipse/che/selenium/core/client/TestProjectServiceClient.java index e37f4aadd0..adaf409425 100644 --- a/selenium/che-selenium-core/src/main/java/org/eclipse/che/selenium/core/client/TestProjectServiceClient.java +++ b/selenium/che-selenium-core/src/main/java/org/eclipse/che/selenium/core/client/TestProjectServiceClient.java @@ -25,10 +25,12 @@ import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import org.eclipse.che.api.core.model.workspace.config.ProjectConfig; import org.eclipse.che.api.core.rest.HttpJsonRequestFactory; import org.eclipse.che.api.workspace.shared.dto.ProjectConfigDto; +import org.eclipse.che.api.workspace.shared.dto.SourceStorageDto; import org.eclipse.che.commons.lang.IoUtil; import org.eclipse.che.commons.lang.ZipUtils; import org.eclipse.che.selenium.core.provider.TestWorkspaceAgentApiEndpointUrlProvider; @@ -147,6 +149,35 @@ public class TestProjectServiceClient { importZipProject(workspaceId, zip, projectName, template); } + /** Import project from file system into a user workspace */ + public void importProject( + String workspaceId, + String projectName, + String location, + String type, + Map parameters) + throws Exception { + SourceStorageDto source = getInstance().createDto(SourceStorageDto.class); + source.setLocation(location); + source.setType(type); + source.setParameters(parameters); + + importProject(workspaceId, projectName, source); + } + + /** Import project from file system into a user workspace */ + public void importProject(String workspaceId, String projectName, SourceStorageDto source) + throws Exception { + + requestFactory + .fromUrl( + workspaceAgentApiEndpointUrlProvider.get(workspaceId) + "project/import/" + projectName) + .usePostMethod() + .setAuthorizationHeader(machineServiceClient.getMachineApiToken(workspaceId)) + .setBody(source) + .request(); + } + /** Creates file in the project. */ public void createFileInProject( String workspaceId, String parentFolder, String fileName, String content) throws Exception { diff --git a/selenium/che-selenium-core/src/main/java/org/eclipse/che/selenium/core/webdriver/SeleniumWebDriverHelper.java b/selenium/che-selenium-core/src/main/java/org/eclipse/che/selenium/core/webdriver/SeleniumWebDriverHelper.java index 4446cd1472..c68de67ce5 100644 --- a/selenium/che-selenium-core/src/main/java/org/eclipse/che/selenium/core/webdriver/SeleniumWebDriverHelper.java +++ b/selenium/che-selenium-core/src/main/java/org/eclipse/che/selenium/core/webdriver/SeleniumWebDriverHelper.java @@ -1393,4 +1393,9 @@ public class SeleniumWebDriverHelper { public void waitSuccessCondition(ExpectedCondition expression) { waitSuccessCondition(expression, DEFAULT_TIMEOUT); } + + public void closeCurrentWindowAndSwitchToAnother(String windowToSwitch) { + seleniumWebDriver.close(); + seleniumWebDriver.switchTo().window(windowToSwitch); + } } 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 59dc705531..b757fb379a 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 @@ -27,6 +27,7 @@ public final class TestProjectExplorerContextMenuConstants { GO_INTO("gwt-debug-contextMenu/goInto"), GO_BACK("gwt-debug-contextMenu/goInto"), OPEN_IN_TERMINAL("gwt-debug-contextMenu/openInTerminal"), + OPEN_ON_GITHUB("gwt-debug-contextMenu/openOnGitHub"), CUT("gwt-debug-contextMenu/cut"), COPY("gwt-debug-contextMenu/copy"), PASTE("gwt-debug-contextMenu/paste"), diff --git a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/CodenvyEditor.java b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/CodenvyEditor.java index 6610a3d74f..e18459d13a 100644 --- a/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/CodenvyEditor.java +++ b/selenium/che-selenium-test/src/main/java/org/eclipse/che/selenium/pageobject/CodenvyEditor.java @@ -269,6 +269,7 @@ public class CodenvyEditor { OPEN_DECLARATION(By.id("contextMenu/Open Declaration")), NAVIGATE_FILE_STRUCTURE(By.id("contextMenu/Navigate File Structure")), FIND(By.id("contextMenu/Find")), + OPEN_ON_GITHUB(By.id("contextMenu/Open on GitHub")), CLOSE(By.id("contextMenu/Close")); @SuppressWarnings("ImmutableEnumChecker") @@ -655,6 +656,23 @@ public class CodenvyEditor { waitCursorPosition(positionLine, positionChar); } + /** + * Select text in defined interval + * + * @param fromLine beginning of first line for selection + * @param numberOfLine end of first line for selection + */ + public void selectLines(int fromLine, int numberOfLine) { + Actions action = seleniumWebDriverHelper.getAction(seleniumWebDriver); + setCursorToLine(fromLine); + action.keyDown(SHIFT).perform(); + for (int i = 0; i < numberOfLine; i++) { + typeTextIntoEditor(Keys.ARROW_DOWN.toString()); + } + action.keyUp(SHIFT).perform(); + action.sendKeys(Keys.END.toString()).keyUp(SHIFT).perform(); + } + /** * Sets cursor to specified {@code positionLine} and {@code positionChar}. * 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 7f051ff6d3..6f6a444c8a 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 @@ -681,6 +681,13 @@ public class ProjectExplorer { By.id(ContextMenuFirstLevelItems.NEW.get()), WIDGET_TIMEOUT_SEC); } + /** Waits on context menu item is not visible */ + public void waitContexMenuItemIsNotVisible(ContextMenuItems item) { + waitContextMenu(); + seleniumWebDriverHelper.waitInvisibility( + By.xpath(format("//tr[@item-enabled='true' and @id='%s']", item.get()))); + } + /** * Clicks on element from context menu by specified {@code itemId} * diff --git a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/git/OpenOnGitHubTest.java b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/git/OpenOnGitHubTest.java new file mode 100644 index 0000000000..1601eb474a --- /dev/null +++ b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/git/OpenOnGitHubTest.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2012-2018 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.selenium.git; + +import static org.eclipse.che.commons.lang.NameGenerator.generate; +import static org.eclipse.che.selenium.pageobject.CodenvyEditor.ContextMenuLocator.OPEN_ON_GITHUB; +import static org.eclipse.che.selenium.pageobject.Wizard.TypeProject.BLANK; +import static org.openqa.selenium.support.ui.ExpectedConditions.*; + +import com.google.inject.Inject; +import com.google.inject.name.Named; +import java.nio.file.Path; +import java.nio.file.Paths; +import org.eclipse.che.selenium.core.SeleniumWebDriver; +import org.eclipse.che.selenium.core.client.TestGitHubRepository; +import org.eclipse.che.selenium.core.client.TestProjectServiceClient; +import org.eclipse.che.selenium.core.client.TestUserPreferencesServiceClient; +import org.eclipse.che.selenium.core.constant.TestProjectExplorerContextMenuConstants; +import org.eclipse.che.selenium.core.project.ProjectTemplates; +import org.eclipse.che.selenium.core.user.DefaultTestUser; +import org.eclipse.che.selenium.core.webdriver.SeleniumWebDriverHelper; +import org.eclipse.che.selenium.core.workspace.TestWorkspace; +import org.eclipse.che.selenium.pageobject.CheTerminal; +import org.eclipse.che.selenium.pageobject.CodenvyEditor; +import org.eclipse.che.selenium.pageobject.Ide; +import org.eclipse.che.selenium.pageobject.ProjectExplorer; +import org.eclipse.che.selenium.pageobject.git.Git; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * Test "Open on Github" action. Will check action calling from context menu on selected project, + * folder and file + * + * @author Vitalii Parfonov + */ +public class OpenOnGitHubTest { + private static final String PROJECT_NAME = generate("project", 4); + private static final String PROJECT_WITHOUT_GIT_FOLDER = "projectWithoutGitCVS"; + private static final String PATH_TO_EXPAND = "src/main/java/che/eclipse/sample"; + private String mainBrowserTabHandle; + + @Inject private TestWorkspace workspace; + + @SuppressWarnings("unused") + @Inject + private Ide ide; + + @SuppressWarnings("unused") + @Inject + private ProjectExplorer projectExplorer; + + @SuppressWarnings("unused") + @Inject + private TestProjectServiceClient testProjectServiceClient; + + @SuppressWarnings("unused") + @Inject + private CheTerminal terminal; + + @SuppressWarnings("unused") + @Inject + private SeleniumWebDriverHelper seleniumWebDriverHelper; + + @SuppressWarnings("unused") + @Inject + private SeleniumWebDriver seleniumWebDriver; + + @Inject private CodenvyEditor editor; + + @Inject private TestUserPreferencesServiceClient testUserPreferencesServiceClient; + + @Inject private DefaultTestUser productUser; + + @Inject private TestGitHubRepository testRepo; + + @Inject + @Named("github.username") + private String gitHubUsername; + + @Inject private Git git; + + @BeforeClass + public void setUp() throws Exception { + testUserPreferencesServiceClient.addGitCommitter(gitHubUsername, productUser.getEmail()); + Path entryPath = + Paths.get(getClass().getResource("/projects/default-spring-project").getPath()); + testProjectServiceClient.importProject( + workspace.getId(), entryPath, PROJECT_WITHOUT_GIT_FOLDER, ProjectTemplates.MAVEN_SPRING); + + testRepo.addContent(entryPath); + ide.open(workspace); + mainBrowserTabHandle = seleniumWebDriver.getWindowHandle(); + git.importJavaApp(testRepo.getHtmlUrl(), PROJECT_NAME, BLANK); + projectExplorer.waitItem(PROJECT_NAME); + projectExplorer.quickExpandWithJavaScript(); + } + + @AfterMethod + public void returnToMainWindow() { + if (seleniumWebDriver.getWindowHandles().size() > 1) { + seleniumWebDriverHelper.closeCurrentWindowAndSwitchToAnother(mainBrowserTabHandle); + } + } + + @Test + public void checkProjectWithoutGitFolder() { + projectExplorer.openContextMenuByPathSelectedItem(PROJECT_WITHOUT_GIT_FOLDER); + projectExplorer.waitContexMenuItemIsNotVisible( + TestProjectExplorerContextMenuConstants.ContextMenuFirstLevelItems.OPEN_ON_GITHUB); + // for closing context menu + projectExplorer.clickOnItemInContextMenu( + TestProjectExplorerContextMenuConstants.ContextMenuFirstLevelItems.COPY); + } + + @Test(priority = 1) + public void openProjectOnGitHubTest() { + projectExplorer.waitAndSelectItem(PROJECT_NAME, 5); + projectExplorer.openContextMenuByPathSelectedItem(PROJECT_NAME); + projectExplorer.waitContextMenu(); + projectExplorer.clickOnItemInContextMenu( + TestProjectExplorerContextMenuConstants.ContextMenuFirstLevelItems.OPEN_ON_GITHUB); + seleniumWebDriverHelper.switchToNextWindow(seleniumWebDriver.getWindowHandle()); + seleniumWebDriverHelper.waitSuccessCondition(urlToBe(testRepo.getHtmlUrl() + "/tree/master/")); + } + + @Test(priority = 2) + public void openFolderOnGitHubTest() { + projectExplorer.waitAndSelectItem(PROJECT_NAME + "/" + PATH_TO_EXPAND, 5); + projectExplorer.waitAndSelectItem(PROJECT_NAME + "/" + PATH_TO_EXPAND, 5); + projectExplorer.openContextMenuByPathSelectedItem(PROJECT_NAME + "/" + PATH_TO_EXPAND); + projectExplorer.waitContextMenu(); + projectExplorer.clickOnItemInContextMenu( + TestProjectExplorerContextMenuConstants.ContextMenuFirstLevelItems.OPEN_ON_GITHUB); + seleniumWebDriverHelper.switchToNextWindow(seleniumWebDriver.getWindowHandle()); + seleniumWebDriverHelper.waitSuccessCondition( + urlToBe(testRepo.getHtmlUrl() + "/tree/master/" + PATH_TO_EXPAND)); + } + + @Test(priority = 3) + public void openFileOnGitHubTest() { + projectExplorer.openItemByPath(PROJECT_NAME + "/" + PATH_TO_EXPAND + "/Aclass.java"); + editor.selectLines(14, 1); + editor.openContextMenuInEditor(); + editor.clickOnItemInContextMenu(OPEN_ON_GITHUB); + seleniumWebDriverHelper.switchToNextWindow(seleniumWebDriver.getWindowHandle()); + seleniumWebDriverHelper.waitSuccessCondition( + urlToBe(testRepo.getHtmlUrl() + "/blob/master/" + PATH_TO_EXPAND + "/Aclass.java#L15-L15")); + } +}