gui-tests-framework: GitGuiTest and scripting parts

This commit is contained in:
Sergey Karashevich
2016-10-09 17:59:25 +03:00
parent 17f607abcb
commit 5e3daf315f
15 changed files with 259 additions and 105 deletions
@@ -86,11 +86,12 @@ public class IdeFrameFixture extends ComponentFixture<IdeFrameFixture, IdeFrameI
private EditorFixture myEditor;
@NotNull
public static IdeFrameFixture find(@NotNull final Robot robot, @NotNull final File projectPath, @Nullable final String projectName) {
public static IdeFrameFixture find(@NotNull final Robot robot, @Nullable final File projectPath, @Nullable final String projectName) {
final GenericTypeMatcher<IdeFrameImpl> matcher = new GenericTypeMatcher<IdeFrameImpl>(IdeFrameImpl.class) {
@Override
protected boolean isMatching(@NotNull IdeFrameImpl frame) {
Project project = frame.getProject();
if (projectPath == null && project != null) return true;
if (project != null && toSystemIndependentName(projectPath.getPath()).equals(project.getBasePath())) {
return projectName == null || projectName.equals(project.getName());
}
@@ -98,7 +99,7 @@ public class IdeFrameFixture extends ComponentFixture<IdeFrameFixture, IdeFrameI
}
};
pause(new Condition("IdeFrame " + quote(projectPath.getPath()) + " to show up") {
pause(new Condition("IdeFrame " + (projectPath != null ? quote(projectPath.getPath()) : "") + " to show up") {
@Override
public boolean test() {
Collection<IdeFrameImpl> frames = robot.finder().findAll(matcher);
@@ -107,7 +108,7 @@ public class IdeFrameFixture extends ComponentFixture<IdeFrameFixture, IdeFrameI
}, LONG_TIMEOUT);
IdeFrameImpl ideFrame = robot.finder().find(matcher);
return new IdeFrameFixture(robot, ideFrame, projectPath);
return new IdeFrameFixture(robot, ideFrame, new File(ideFrame.getProject().getBasePath()));
}
public IdeFrameFixture(@NotNull Robot robot, @NotNull IdeFrameImpl target, @NotNull File projectPath) {
@@ -0,0 +1,117 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.tests.gui.fixtures;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.ui.components.JBList;
import com.intellij.ui.popup.PopupFactoryImpl;
import org.fest.swing.core.GenericTypeMatcher;
import org.fest.swing.core.MouseButton;
import org.fest.swing.core.Robot;
import org.fest.swing.timing.Condition;
import org.junit.Assert;
import javax.annotation.Nonnull;
import javax.swing.*;
import java.awt.*;
import static com.intellij.tests.gui.framework.GuiTests.SHORT_TIMEOUT;
import static org.fest.swing.timing.Pause.pause;
/**
* Created by jetbrains on 29/08/16.
*/
public class ListPopupFixture extends JComponentFixture<ListPopupFixture, JBList> {
private static final Logger LOG = Logger.getInstance("#com.intellij.tests.gui.fixtures.ListPopupFixture");
private JBList myJBList;
private Robot myRobot;
private ListPopupFixture(JBList jbList, Robot robot) {
super(ListPopupFixture.class, robot, jbList);
myJBList = jbList;
myRobot = robot;
}
public static ListPopupFixture findListPopup(Robot robot) {
pause(new Condition("Find list popup") {
@Override
public boolean test() {
final JBList jblist = getList(robot);
return jblist != null;
}
}, SHORT_TIMEOUT);
final JBList jblist = getList(robot);
Assert.assertNotNull(jblist);
return new ListPopupFixture(jblist, robot);
}
private static JBList getList(Robot robot) {
return robot.finder().find(new GenericTypeMatcher<JBList>(JBList.class) {
@Override
protected boolean isMatching(@Nonnull JBList list) {
Container parent = list.getRootPane().getParent();
if (parent == null) return false;
if (parent instanceof JWindow && ((JWindow)parent).getType() == Window.Type.POPUP) {
return true;
}
return false;
}
});
}
public void assertContainsAction(String actionName) {
boolean assertion = false;
ListModel listModel = myJBList.getModel();
for (int i = 0; i < myJBList.getItemsCount(); i++) {
Object elementAt = listModel.getElementAt(i);
if (elementAt instanceof PopupFactoryImpl.ActionItem) {
if (((PopupFactoryImpl.ActionItem)elementAt).getText().toLowerCase().contains(actionName.toLowerCase())) assertion = true;
}
}
if (!assertion) LOG.error("Unable to find action \"" + actionName + "\" in popupList");
assert assertion;
}
public void invokeAction(String actionName) {
int actionIndex = -1;
ListModel listModel = myJBList.getModel();
for (int i = 0; i < myJBList.getItemsCount(); i++) {
Object elementAt = listModel.getElementAt(i);
if (elementAt instanceof PopupFactoryImpl.ActionItem) {
if (((PopupFactoryImpl.ActionItem)elementAt).getText().toLowerCase().contains(actionName.toLowerCase())) actionIndex = i;
}
}
if (actionIndex == -1) {
LOG.error("Unable to find action \"" + actionName + "\" in popupMenu");
} else {
final Rectangle cellBounds = myJBList.getCellBounds(actionIndex, actionIndex);
final Point locationOnScreen = myJBList.getLocationOnScreen();
final Point point =
new Point(locationOnScreen.x + cellBounds.x + cellBounds.width / 2,
locationOnScreen.y + cellBounds.y + cellBounds.height / 2);
robot().click(point, MouseButton.LEFT_BUTTON, 1);
}
}
}
@@ -36,19 +36,19 @@ class MessageDialogFixture extends IdeaDialogFixture<DialogWrapper> implements M
JDialog dialog = waitUntilFound(robot, new GenericTypeMatcher<JDialog>(JDialog.class) {
@Override
protected boolean isMatching(@NotNull JDialog dialog) {
if (!title.equals(dialog.getTitle()) || !dialog.isShowing()) {
if (!title.equals(dialog.getTitle()) || !dialog.isShowing()) {
return false;
}
DialogWrapper wrapper = getDialogWrapperFrom(dialog, DialogWrapper.class);
if (wrapper != null) {
String typeName = Messages.class.getName() + "$MessageDialog";
if (typeName.equals(wrapper.getClass().getName())) {
wrapperRef.set(wrapper);
return true;
}
}
return false;
}
DialogWrapper wrapper = getDialogWrapperFrom(dialog, DialogWrapper.class);
if (wrapper != null) {
String typeName = Messages.class.getName() + "$MessageDialog";
if (typeName.equals(wrapper.getClass().getName())) {
wrapperRef.set(wrapper);
return true;
}
}
return false;
}
});
return new MessageDialogFixture(robot, dialog, wrapperRef.get());
}
@@ -387,6 +387,11 @@ public abstract class GuiTestCase {
return IdeFrameFixture.find(myRobot, projectPath, null);
}
protected IdeFrameFixture findIdeFrame(){
return IdeFrameFixture.find(myRobot, null, null);
}
protected void refreshFiles() {
execute(new GuiTask() {
@Override
@@ -50,6 +50,7 @@ import org.fest.swing.exception.WaitTimedOutError;
import org.fest.swing.fixture.ContainerFixture;
import org.fest.swing.fixture.DialogFixture;
import org.fest.swing.fixture.JListFixture;
import org.fest.swing.fixture.JTextComponentFixture;
import org.fest.swing.timing.Condition;
import org.fest.swing.timing.Pause;
import org.fest.swing.timing.Timeout;
@@ -61,6 +62,7 @@ import org.jetbrains.annotations.Nullable;
import javax.annotation.Nonnull;
import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -612,7 +614,7 @@ public final class GuiTests {
Collection<JLabel> labels = robot.finder().findAll(container, new GenericTypeMatcher<JLabel>(JLabel.class) {
@Override
protected boolean isMatching(@Nonnull JLabel label) {
return label.getLabelFor().equals(textField);
return (label.getLabelFor() != null && label.getLabelFor().equals(textField));
}
});
if (labels != null && !labels.isEmpty()) return labels.iterator().next();
@@ -752,5 +754,11 @@ public final class GuiTests {
return jdkBundle.getLocation().getAbsolutePath() + homeSubPath;
}
@NotNull
public static JTextComponentFixture findTextField(@NotNull Robot robot, @NotNull final String labelText) {
return new JTextComponentFixture(robot, robot.finder().findByLabel(labelText, JTextComponent.class));
}
}
@@ -28,6 +28,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.impl.ApplicationImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.SystemProperties;
import com.intellij.util.lang.UrlClassLoader;
import com.intellij.util.text.StringTokenizer;
@@ -1,6 +1,5 @@
package com.intellij.tests.gui.framework
import com.intellij.openapi.ui.JBPopupMenu
import com.intellij.tests.gui.fixtures.WelcomeFrameFixture
import com.intellij.ui.components.JBList
import org.fest.swing.core.Robot
@@ -11,6 +10,8 @@ import java.awt.Container
/**
We presume that IDEA is already started, shows "Welcome dialog" and we could create a new project
!!UNFINISHED!!
**/
@@ -1,24 +0,0 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.tests.gui.script
/**
* Created by jetbrains on 15/08/16.
*/
interface ScriptInterface{
fun script()
}
@@ -17,7 +17,11 @@ package com.intellij.tests.gui.script
import com.intellij.internal.inspector.UiDropperActionExtension
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.tests.gui.framework.GuiTests
import org.fest.swing.core.BasicRobot
import org.fest.swing.core.Robot
import java.awt.Component
import java.awt.Container
import javax.swing.*
/**
@@ -59,7 +63,11 @@ class ScriptRecorder() : AnAction(), UiDropperActionExtension {
is JButton -> write(Templates.findAndClickButton(cmp.text))
is com.intellij.ui.components.labels.ActionLink -> write(Templates.clickActionLink(cmp.text))
is JTextField -> {
write(Templates.findJTextField())
val label = getLabel(currentContextComponent as Container, cmp)
if (label == null)
write(Templates.findJTextField())
else
write(Templates.findJTextFieldByLabel(label.text))
}
is com.intellij.ui.components.JBList -> {
val itemName = e.dataContext.getData("ItemName") as String
@@ -72,6 +80,10 @@ class ScriptRecorder() : AnAction(), UiDropperActionExtension {
}
private fun isPopupList(cmp: Component) = cmp.javaClass.name.toLowerCase().contains("listpopup")
private fun getLabel(container: Container, jTextField: JTextField): JLabel? {
val robot = BasicRobot.robotWithCurrentAwtHierarchyWithoutScreenLock()
return GuiTests.findBoundedLabel(container, jTextField, robot)
}
fun checkContext(cmp: Component) {
cmp as JComponent
@@ -0,0 +1,82 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.tests.gui.test
import com.intellij.dvcs.ui.CloneDvcsDialog
import com.intellij.dvcs.ui.DvcsBundle
import com.intellij.openapi.project.DumbService
import com.intellij.openapi.vcs.VcsBundle
import com.intellij.tests.gui.BelongsToTestGroups
import com.intellij.tests.gui.fixtures.*
import com.intellij.tests.gui.framework.GuiTestCase
import com.intellij.tests.gui.framework.GuiTests
import com.intellij.tests.gui.framework.TestGroup
import com.intellij.ui.EditorComboBox
import org.fest.swing.edt.GuiActionRunner
import org.fest.swing.edt.GuiTask
import org.fest.swing.fixture.DialogFixture
import org.fest.swing.fixture.JTextComponentFixture
import org.junit.Test
import javax.swing.text.JTextComponent
/**
* Created by karashevich on 18/06/16.
*/
@BelongsToTestGroups(TestGroup.PROJECT)
class GitGuiTest : GuiTestCase() {
@Test
fun testGitImport(){
val vcsName = "Git"
val gitPath = "https://github.com/karashevich/test.git"
val welcomeFrame = WelcomeFrameFixture.find(myRobot)
welcomeFrame.checkoutFrom()
ListPopupFixture.findListPopup(myRobot).invokeAction(vcsName)
val cloneVcsDialog = DialogFixture(myRobot, IdeaDialogFixture.find(myRobot, CloneDvcsDialog::class.java).dialog) //don't miss robot as the first argument or you'll stuck with a deadlock
with(cloneVcsDialog) {
val labelText = DvcsBundle.message("clone.repository.url", vcsName)
val editorComboBox = myRobot.finder().findByLabel(this.target(), labelText, EditorComboBox::class.java)
GuiActionRunner.execute(object : GuiTask() {
@Throws(Throwable::class)
override fun executeInEDT() {
editorComboBox.text = gitPath
}
})
GuiTests.findAndClickButton(this, DvcsBundle.getString("clone.button"))
}
MessagesFixture.findByTitle(myRobot, welcomeFrame.target(), VcsBundle.message("checkout.title")).clickYes()
val dialog1 = com.intellij.tests.gui.fixtures.DialogFixture.find(myRobot, "Import Project")
with (dialog1) {
GuiTests.findAndClickButton(this, "Next")
val textField = GuiTests.findTextField(myRobot, "Project name:").click()
GuiTests.findAndClickButton(this, "Next")
GuiTests.findAndClickButton(this, "Next")
GuiTests.findAndClickButton(this, "Finish")
}
val ideFrame = findIdeFrame()
val projectView = ideFrame.projectView
val paneFixture = projectView.selectProjectPane()
ToolWindowFixture.showToolwindowStripes(myRobot)
//prevent from ProjectLeak (if the project is closed during the indexing
DumbService.getInstance(ideFrame.project).waitForSmartMode()
}
}
@@ -1,54 +0,0 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.tests.gui.test
import com.intellij.dvcs.ui.CloneDvcsDialog
import com.intellij.dvcs.ui.DvcsBundle
import com.intellij.tests.gui.BelongsToTestGroups
import com.intellij.tests.gui.fixtures.IdeaDialogFixture
import com.intellij.tests.gui.fixtures.JBPopupFixture
import com.intellij.tests.gui.fixtures.WelcomeFrameFixture
import com.intellij.tests.gui.framework.GuiTestCase
import com.intellij.tests.gui.framework.GuiTests
import com.intellij.tests.gui.framework.TestGroup
import org.fest.swing.fixture.DialogFixture
import org.fest.swing.fixture.JTextComponentFixture
import org.junit.Test
import javax.swing.text.JTextComponent
/**
* Created by karashevich on 18/06/16.
*/
@BelongsToTestGroups(TestGroup.PROJECT)
class GitTest : GuiTestCase() {
@Test
fun testGitImport(){
val vcsName = "Git"
val gitPath = "https://github.com/karashevich/test.git"
WelcomeFrameFixture.find(myRobot).checkoutFrom()
JBPopupFixture.findContextMenu(myRobot).invokeAction(vcsName)
val cloneVcsDialog = DialogFixture(IdeaDialogFixture.find(myRobot, CloneDvcsDialog::class.java).dialog)
val labelText = DvcsBundle.message("clone.repository.url", vcsName)
val urlTextField = JTextComponentFixture(myRobot, myRobot.finder().findByLabel(labelText, JTextComponent::class.java))
urlTextField.setText(gitPath)
GuiTests.findAndClickButton(cloneVcsDialog, DvcsBundle.getString("clone.button"))
}
}
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.tests.gui;
package com.intellij.tests.gui.test;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.progress.ProgressManager;
@@ -21,6 +21,7 @@ import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.project.ProjectUtil;
import com.intellij.tests.gui.BelongsToTestGroups;
import com.intellij.tests.gui.fixtures.ActionLinkFixture;
import com.intellij.tests.gui.fixtures.ProjectViewFixture;
import com.intellij.tests.gui.fixtures.ToolWindowFixture;
@@ -13,18 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.tests.gui
package com.intellij.tests.gui.test
import com.intellij.tests.gui.fixtures.ActionLinkFixture
import com.intellij.tests.gui.BelongsToTestGroups
import com.intellij.tests.gui.fixtures.DialogFixtures.CreateDialogFixture
import com.intellij.tests.gui.fixtures.EditorFixture
import com.intellij.tests.gui.fixtures.JBPopupFixture
import com.intellij.tests.gui.framework.*
import com.intellij.ui.components.JBList
import com.intellij.tests.gui.framework.GuiTestCase
import com.intellij.tests.gui.framework.TestGroup
import com.intellij.tests.gui.framework.clickListItem
import com.intellij.tests.gui.framework.createNewProject
import org.junit.Ignore
import org.junit.Test
import java.io.File
import javax.swing.JTextField
import javax.swing.text.JTextComponent
/**
@@ -13,13 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.tests.gui;
package com.intellij.tests.gui.test;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.tests.gui.BelongsToTestGroups;
import com.intellij.tests.gui.fixtures.ProjectViewFixture;
import com.intellij.tests.gui.fixtures.newProjectWizard.NewProjectWizardFixture;
import com.intellij.tests.gui.framework.*;
import com.intellij.tests.gui.framework.GuiTestCase;
import com.intellij.tests.gui.framework.GuiTests;
import com.intellij.tests.gui.framework.IdeGuiTest;
import com.intellij.tests.gui.framework.TestGroup;
import org.junit.Ignore;
import org.junit.Test;
@@ -49,7 +53,6 @@ public class NewProjectTest extends GuiTestCase {
Date date = new Date();
String projectName = "smoke-test-project-" + dateFormat.format(date);
findWelcomeFrame().createNewProject();
NewProjectWizardFixture newProjectWizard = findNewProjectWizard();
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.tests.gui
package com.intellij.tests.gui.test
import com.intellij.tests.gui.BelongsToTestGroups
import com.intellij.tests.gui.framework.GuiTestCase