Java tutorial
/* * Copyright (C) 2015 The Android Open Source Project * * 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.android.tools.idea.tests.gui.framework.fixture; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.ui.Messages; import com.intellij.ui.messages.SheetController; import org.fest.swing.core.GenericTypeMatcher; import org.fest.swing.core.Robot; import org.fest.swing.fixture.ContainerFixture; import org.fest.swing.fixture.JPanelFixture; import org.fest.swing.timing.Wait; import org.jdom.Document; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import static com.android.tools.idea.tests.gui.framework.GuiTests.*; import static com.google.common.base.Strings.nullToEmpty; import static com.google.common.truth.Truth.assertThat; import static com.intellij.openapi.util.JDOMUtil.loadDocument; import static org.fest.reflect.core.Reflection.field; public class MessagesFixture { @NotNull private final ContainerFixture<? extends Container> myDelegate; @NotNull private final JDialog myDialog; // Mac changes the panel window before closing animation. We keep a reference here. @NotNull public static MessagesFixture findByTitle(@NotNull Robot robot, @NotNull String title) { if (Messages.canShowMacSheetPanel()) { JPanelFixture panelFixture = findMacSheetByTitle(robot, title); JDialog dialog = (JDialog) SwingUtilities.getWindowAncestor(panelFixture.target()); return new MessagesFixture(panelFixture, dialog); } MessageDialogFixture dialog = MessageDialogFixture.findByTitle(robot, title); return new MessagesFixture(dialog, dialog.target()); } private MessagesFixture(@NotNull ContainerFixture<? extends Container> delegate, @NotNull JDialog dialog) { myDelegate = delegate; myDialog = dialog; } @NotNull public MessagesFixture clickOk() { findAndClickOkButton(myDelegate); waitUntilNotShowing(); return this; } @NotNull public MessagesFixture clickYes() { return click("Yes"); } @NotNull public MessagesFixture click(@NotNull String text) { findAndClickButton(myDelegate, text); waitUntilNotShowing(); return this; } @NotNull public MessagesFixture requireMessageContains(@NotNull String message) { String actual = ((Delegate) myDelegate).getMessage(); assertThat(actual).contains(message); return this; } public void clickCancel() { findAndClickCancelButton(myDelegate); waitUntilNotShowing(); } private void waitUntilNotShowing() { Wait.seconds(1).expecting("not showing").until(() -> !myDialog.isShowing()); } @NotNull static JPanelFixture findMacSheetByTitle(@NotNull Robot robot, @NotNull String title) { JPanel sheetPanel = waitUntilShowing(robot, new GenericTypeMatcher<JPanel>(JPanel.class) { @Override protected boolean isMatching(@NotNull JPanel panel) { if (panel.getClass().getName().startsWith(SheetController.class.getName())) { SheetController controller = findSheetController(panel); JPanel sheetPanel = field("mySheetPanel").ofType(JPanel.class).in(controller).get(); if (sheetPanel == panel) { return true; } } return false; } }); String sheetTitle = getTitle(sheetPanel, robot); assertThat(sheetTitle).named("Sheet title").isEqualTo(title); return new MacSheetPanelFixture(robot, sheetPanel); } @Nullable private 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); } @Override @NotNull public String getMessage() { JEditorPane messageTextPane = getMessageTextPane(target()); String text = getHtmlBody(messageTextPane.getText()); return nullToEmpty(text); } } @NotNull private static JEditorPane getMessageTextPane(@NotNull JPanel sheetPanel) { SheetController sheetController = findSheetController(sheetPanel); return field("messageTextPane").ofType(JEditorPane.class).in(sheetController).get(); } @NotNull private static SheetController findSheetController(@NotNull JPanel sheetPanel) { return field("this$0").ofType(SheetController.class).in(sheetPanel).get(); } @Nullable private static String getHtmlBody(@NotNull String html) { try { Document document = loadDocument(html); Element rootElement = document.getRootElement(); 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; } }