package com.windowtester.test.eclipse; import static com.windowtester.runtime.swt.internal.abbot.TreeItemTester.NO_CHILDREN_EXPANSION_ERROR_MSG_DETAIL; import static com.windowtester.runtime.swt.locator.eclipse.EclipseLocators.view; import com.windowtester.runtime.IUIContext; import com.windowtester.runtime.WidgetNotFoundException; import com.windowtester.runtime.WidgetSearchException; import com.windowtester.runtime.condition.ICondition; import com.windowtester.runtime.locator.ILocator; import com.windowtester.runtime.swt.UITestCaseSWT; import com.windowtester.runtime.swt.condition.SWTIdleCondition; import com.windowtester.runtime.swt.condition.eclipse.JobsCompleteCondition; import com.windowtester.runtime.swt.condition.eclipse.ProjectExistsCondition; import com.windowtester.runtime.swt.condition.shell.ShellDisposedCondition; import com.windowtester.runtime.swt.condition.shell.ShellShowingCondition; import com.windowtester.runtime.swt.internal.condition.eclipse.DirtyEditorCondition; import com.windowtester.runtime.swt.locator.ButtonLocator; import com.windowtester.runtime.swt.locator.CTabItemLocator; import com.windowtester.runtime.swt.locator.MenuItemLocator; import com.windowtester.runtime.swt.locator.TreeItemLocator; import com.windowtester.runtime.swt.locator.eclipse.ViewLocator; import com.windowtester.test.util.TypingLinuxHelper; /******************************************************************************* * Copyright (c) 2012 Google, 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: * Google, Inc. - initial API and implementation *******************************************************************************/ public class ProjectExplorerStressTest extends UITestCaseSWT { // private static final String FAILED_TO_FIND_ERROR_MSG_DETAIL = "Failed to find match for"; private static final String DELETE_RESOURCES_SHELL_TITLE = EclipseUtil.isAtLeastVersion_34() ? "Delete Resources" : "Confirm Project Delete"; private static final String DELETE_RESOURCES_SHELL_ACCEPT_BUTTON_TEXT = EclipseUtil.isAtLeastVersion_34() ? "OK" : "Yes"; private static final String PROJECT_EXPLORER_VIEW_CATEGORY = "(Simple|General)"; private class LifeCycleHelper { //useful for tearDown protected void saveAllIfNecessary() throws WidgetSearchException { if (anyUnsavedChanges()) getUI().click(new MenuItemLocator("File/Save All")); } private boolean anyUnsavedChanges() { return new DirtyEditorCondition().test(); } protected void closeWelcomePageIfNecessary() throws Exception { getUI().ensureThat(view("Welcome").isClosed()); } } private class TestProjectManager { private int projectIndex = 0; void createNewProject() throws WidgetSearchException { createSimpleProject(getUI(), getFreshProjectName()); } private String getFreshProjectName() { return getProjectNamePrefix() + nextIndex(); } // private String getLastProjectName() { // return getProjectNamePrefix() + lastIndex(); // } private int nextIndex() { return projectIndex++; } // private int lastIndex() { // return projectIndex; // } private String getProjectNamePrefix() { return ProjectExplorerStressTest.class.getName() + "Project"; } void createSimpleProject(IUIContext ui, String projectName) throws WidgetSearchException { try{ TypingLinuxHelper.switchToInsertStrategyIfNeeded(); ensureNotNull(ui, projectName); ui.click(new MenuItemLocator("File/New/Project...")); ui.wait(new ShellShowingCondition("New Project")); ui.click(new TreeItemLocator("(Simple|General)/Project")); ui.click(new ButtonLocator("Next >")); ui.assertThat(new ButtonLocator("Finish").isEnabled(false)); ui.enterText(projectName); ui.assertThat(new ButtonLocator("Finish").isEnabled(true)); ui.click(new ButtonLocator("Finish")); ui.wait(new ShellDisposedCondition("New Project")); ui.wait(new JobsCompleteCondition()); ui.wait(new SWTIdleCondition()); }finally{ TypingLinuxHelper.restoreOriginalStrategy(); } } // void closeProject(String projectName) throws WidgetSearchException { // IUIContext ui = getUI(); // ui.contextClick(projectTree(projectName), "Close Project"); // ui.wait(new ShellDisposedCondition("Close Project")); // //TODO: wait for closed project condition... // } void deleteProject(String projectName) throws WidgetSearchException { IUIContext ui = getUI(); ui.contextClick(projectTree(projectName), "Delete"); ui.wait(new ShellShowingCondition(DELETE_RESOURCES_SHELL_TITLE)); ui.click(new ButtonLocator(DELETE_RESOURCES_SHELL_ACCEPT_BUTTON_TEXT)); ui.wait(new ShellDisposedCondition(DELETE_RESOURCES_SHELL_TITLE)); ui.wait(new ProjectExistsCondition(projectName, false)); } void deleteAll() throws Exception { ensureProjectViewIsVisible(); eachDo(new ProjectAction() { public void run(String projectName) throws WidgetSearchException { deleteProject(projectName); } }); } void eachDo(ProjectAction projectAction) throws Exception { for (int i=0; i < projectIndex; ++i) projectAction.run(getProjectNamePrefix() + i); } } private static interface ProjectAction { void run(String projectName) throws Exception; } private static final String PROJECT_EXPLORER_VIEW_NAME = "Project Explorer"; private static final String PROJECT_EXPLORER_VIEW_ID = "org.eclipse.ui.navigator.ProjectExplorer"; private final TestProjectManager projectManager = new TestProjectManager(); private final LifeCycleHelper lifecycleHelper = new LifeCycleHelper(); ////////////////////////////////////////////////////////////////////////// // // Tests // ////////////////////////////////////////////////////////////////////////// public void XtestCreateMultipleSimpleProjects() throws Exception { createProjects(5); eachProjectDo(new ProjectAction() { public void run(String projectName) throws WidgetSearchException { clickProjectTree(projectName + "/.project"); } }); } public void testClickNonExistentProjectContent() throws Exception { createProjects(1); eachProjectDo(new ProjectAction() { public void run(String projectName) throws WidgetSearchException { String treePath = projectName + "/.project"; try { clickProjectTree(treePath); fail("Expected WidgetSearchException"); } catch (WidgetSearchException e) { assertExceptionMessage("testClickNonExistentProjectContent", e, NO_CHILDREN_EXPANSION_ERROR_MSG_DETAIL, "No tree items found for '"); } } }); } private void assertExceptionMessage(String testMethodName, Exception e, String w1ExMsg, String w2ExMsg) { String message = e.getMessage(); System.err.println("--- " + testMethodName); e.printStackTrace(); if (!message.contains(w1ExMsg) && !message.contains(w2ExMsg)) fail(("message should have contained: " + w1ExMsg + "\n or: " + w2ExMsg + "\n but got: " + message)); } public void testClickNonExistentProjectInEmptyTree() throws Exception { try { clickProjectTree("NonExistent"); fail("Expected WidgetSearchException"); } catch(WidgetNotFoundException e) { assertExceptionMessage("testClickNonExistentProjectInEmptyTree", e, "Item: [NonExistent] not found", "No tree items found for 'NonExistent' in"); } } public void testClickNonExistentProjectInPopulatedTree() throws Exception { createProjects(1); try { clickProjectTree("NonExistent"); fail("Expected WidgetSearchException"); } catch(WidgetNotFoundException e) { assertExceptionMessage("testClickNonExistentProjectInPopulatedTree", e, "Item: [NonExistent] not found", "No tree items found for 'NonExistent' in"); } } ////////////////////////////////////////////////////////////////////////// // // Lifecycle // ////////////////////////////////////////////////////////////////////////// /* (non-Javadoc) * @see junit.framework.TestCase#tearDown() */ protected void tearDown() throws Exception { lifecycleHelper.saveAllIfNecessary(); projectManager.deleteAll(); } /* (non-Javadoc) * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { lifecycleHelper.closeWelcomePageIfNecessary(); } ////////////////////////////////////////////////////////////////////////// // // Utils // ////////////////////////////////////////////////////////////////////////// private void eachProjectDo(ProjectAction projectAction) throws Exception { projectManager.eachDo(projectAction); } protected void clickProjectTree(String treePath) throws WidgetSearchException { ensureProjectViewIsVisible(); getUI().click(projectTree(treePath)); } private void createProjects(int numProjects) throws WidgetSearchException { for (int i=0; i < numProjects; ++i) projectManager.createNewProject(); } void showProjectExplorer() throws WidgetSearchException { openView(PROJECT_EXPLORER_VIEW_CATEGORY + "/" + PROJECT_EXPLORER_VIEW_NAME); } void openView(String viewPath) throws WidgetSearchException { ensureNotNull(viewPath); IUIContext ui = getUI(); ui.click(new MenuItemLocator("&Window/Show &View/&Other.*")); //3.* safe path ui.wait(new ShellShowingCondition("Show View")); ui.click(new TreeItemLocator(viewPath)); ui.click(new ButtonLocator("OK")); ui.wait(new ShellDisposedCondition("Show View")); } void ensureProjectViewIsVisible() throws WidgetSearchException { if (isProjectViewOpen()) return; //already open showProjectExplorer(); } void closeView(String viewName) throws WidgetSearchException { ensureNotNull(viewName); if (!(isProjectViewOpen())) return; //already closed IUIContext ui = getUI(); ui.contextClick(new CTabItemLocator(viewName), "Close"); ui.wait(projectViewClosed()); } private ICondition projectViewClosed() { return new ViewLocator(PROJECT_EXPLORER_VIEW_ID).isVisible(false); } private boolean isProjectViewOpen() throws WidgetSearchException { return new ViewLocator(PROJECT_EXPLORER_VIEW_ID).isVisible(getUI()); } void ensureNotNull(Object ... args) { for (Object arg : args) assertNotNull(arg); } static ILocator projectTree(String treePath) { return new TreeItemLocator(treePath, new ViewLocator(PROJECT_EXPLORER_VIEW_ID)); } }