/* * Copyright 2000-2017 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.testGuiFramework.fixtures; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.text.StringUtil; import com.intellij.testGuiFramework.framework.GuiTestUtil; import com.intellij.ui.messages.SheetController; import com.intellij.util.JdomKt; import org.fest.swing.core.GenericTypeMatcher; import org.fest.swing.core.Robot; import org.fest.swing.exception.WaitTimedOutError; import org.fest.swing.fixture.ContainerFixture; import org.fest.swing.fixture.JPanelFixture; import org.fest.swing.timing.Timeout; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import static org.fest.assertions.Assertions.assertThat; import static org.fest.reflect.core.Reflection.field; import static org.junit.Assert.assertNotNull; public class MessagesFixture { @NotNull private final ContainerFixture<? extends Container> myDelegate; @NotNull public static MessagesFixture findByTitle(@NotNull Robot robot, @NotNull Container root, @NotNull String title) { if (Messages.canShowMacSheetPanel()) { return new MessagesFixture(findMacSheetByTitle(robot, root, title)); } MessageDialogFixture dialog = MessageDialogFixture.findByTitle(robot, title); return new MessagesFixture(dialog); } @NotNull public static MessagesFixture findByTitle(@NotNull Robot robot, @NotNull Container root, @NotNull String title, @NotNull Timeout timeout) { if (Messages.canShowMacSheetPanel()) { return new MessagesFixture(findMacSheetByTitle(robot, root, title, timeout)); } MessageDialogFixture dialog = MessageDialogFixture.findByTitle(robot, title, timeout); return new MessagesFixture(dialog); } @NotNull public static MessagesFixture findAny(@NotNull Robot robot, @NotNull Container root) { return findAny(robot, root, GuiTestUtil.LONG_TIMEOUT); } @NotNull public static MessagesFixture findAny(@NotNull Robot robot, @NotNull Container root, @NotNull Timeout timeout) { if (Messages.canShowMacSheetPanel()) { return new MessagesFixture(findMacSheetAny(robot, root, timeout)); } MessageDialogFixture dialog = MessageDialogFixture.findAny(robot, timeout); return new MessagesFixture(dialog); } public static boolean exists(@NotNull Robot robot, @NotNull Container root, @NotNull String title) { try{ findByTitle(robot, root, title); return true; } catch (AssertionError | WaitTimedOutError e) { return false; } } private MessagesFixture(@NotNull ContainerFixture<? extends Container> delegate) { myDelegate = delegate; } @NotNull public MessagesFixture clickOk() { GuiTestUtil.findAndClickOkButton(myDelegate); return this; } @NotNull public MessagesFixture clickYes() { return click("Yes"); } @NotNull public MessagesFixture click(@NotNull String text) { GuiTestUtil.findAndClickButton(myDelegate, text); return this; } @NotNull public MessagesFixture requireMessageContains(@NotNull String message) { String actual = ((Delegate)myDelegate).getMessage(); assertThat(actual).contains(message); return this; } public void clickCancel() { GuiTestUtil.findAndClickCancelButton(myDelegate); } @NotNull static JPanelFixture findMacSheetByTitle(@NotNull Robot robot, @NotNull Container root, @NotNull String title) { return findMacSheetByTitle(robot, root, title, GuiTestUtil.LONG_TIMEOUT); } @NotNull static JPanelFixture findMacSheetByTitle(@NotNull Robot robot, @NotNull Container root, @NotNull String title, @NotNull Timeout timeout) { JPanel sheetPanel = getSheetPanel(robot, root, timeout); String sheetTitle = getTitle(sheetPanel, robot); assertThat(sheetTitle).as("Sheet title").isEqualTo(title); return new MacSheetPanelFixture(robot, sheetPanel); } private static JPanelFixture findMacSheetAny(@NotNull Robot robot, @NotNull Container root) { return findMacSheetAny(robot, root, GuiTestUtil.LONG_TIMEOUT); } private static JPanelFixture findMacSheetAny(@NotNull Robot robot, @NotNull Container root, @NotNull Timeout timeout) { JPanel sheetPanel = getSheetPanel(robot, root, timeout); return new MacSheetPanelFixture(robot, sheetPanel); } @NotNull private static JPanel getSheetPanel(@NotNull Robot robot, @NotNull Container root) { return getSheetPanel(robot, root, GuiTestUtil.LONG_TIMEOUT); } @NotNull private static JPanel getSheetPanel(@NotNull Robot robot, @NotNull Container root, @NotNull Timeout timeout) { return GuiTestUtil.waitUntilFound(robot, root, new GenericTypeMatcher<JPanel>(JPanel.class) { @Override protected boolean isMatching(@NotNull JPanel panel) { if (panel.getClass().getName().startsWith(SheetController.class.getName()) && panel.isShowing()) { SheetController controller = findSheetController(panel); JPanel sheetPanel1 = field("mySheetPanel").ofType(JPanel.class).in(controller).get(); if (sheetPanel1 == panel) { return true; } } return false; } }, timeout); } @Nullable public String getTitle() { if (myDelegate instanceof MacSheetPanelFixture) return ((MacSheetPanelFixture)myDelegate).getTitle(); return ((MessageDialogFixture)myDelegate).target().getTitle(); } @Nullable public static String getTitle(@NotNull JPanel sheetPanel, @NotNull Robot robot) { final JEditorPane messageTextPane = getMessageTextPane(sheetPanel); JEditorPane titleTextPane = robot.finder().find(sheetPanel, new GenericTypeMatcher<JEditorPane>(JEditorPane.class) { @Override protected boolean isMatching(@NotNull JEditorPane editorPane) { return editorPane != messageTextPane; } }); return getHtmlBody(titleTextPane.getText()); } @Nullable public <T extends JComponent> T find(GenericTypeMatcher<T> matcher) { return myDelegate.robot().finder().find(myDelegate.target(), matcher); } interface Delegate { @NotNull String getMessage(); } private static class MacSheetPanelFixture extends JPanelFixture implements Delegate { public MacSheetPanelFixture(@NotNull Robot robot, @NotNull JPanel target) { super(robot, target); } @Nullable public String getTitle(){ final JEditorPane messageTextPane = getMessageTextPane(target()); JEditorPane titleTextPane = robot().finder().find(target(), new GenericTypeMatcher<JEditorPane>(JEditorPane.class) { @Override protected boolean isMatching(@NotNull JEditorPane editorPane) { return editorPane != messageTextPane; } }); return getHtmlBody(titleTextPane.getText()); } @Override @NotNull public String getMessage() { JEditorPane messageTextPane = getMessageTextPane(target()); String text = getHtmlBody(messageTextPane.getText()); return StringUtil.notNullize(text); } } @NotNull private static JEditorPane getMessageTextPane(@NotNull JPanel sheetPanel) { SheetController sheetController = findSheetController(sheetPanel); JEditorPane messageTextPane = field("messageTextPane").ofType(JEditorPane.class).in(sheetController).get(); assertNotNull(messageTextPane); return messageTextPane; } @NotNull public static SheetController findSheetController(@NotNull JPanel sheetPanel) { SheetController sheetController = field("this$0").ofType(SheetController.class).in(sheetPanel).get(); assertNotNull(sheetController); return sheetController; } @Nullable private static String getHtmlBody(@NotNull String html) { try { Element rootElement = JdomKt.loadElement(html); String sheetTitle = rootElement.getChild("body").getText(); return sheetTitle.replace("\n", "").trim(); } catch (Throwable e) { Logger.getInstance(MessagesFixture.class).info("Failed to parse HTML '" + html + "'", e); } return null; } }