ghidra/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/ProgramManagerPluginScreenShots.java

384 lines
11 KiB
Java

/* ###
* IP: GHIDRA
*
* 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 help.screenshot;
import static org.junit.Assert.*;
import java.awt.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.*;
import org.junit.Assert;
import org.junit.Test;
import docking.DialogComponentProvider;
import docking.options.editor.DateEditor;
import docking.options.editor.OptionsDialog;
import docking.widgets.OptionDialog;
import docking.widgets.tree.GTree;
import docking.widgets.tree.GTreeNode;
import generic.theme.GThemeDefaults.Colors.Palette;
import ghidra.app.plugin.core.codebrowser.CodeViewerProvider;
import ghidra.app.plugin.core.datamgr.DataTypesProvider;
import ghidra.app.plugin.core.progmgr.MultiTabPlugin;
import ghidra.app.services.ProgramManager;
import ghidra.app.util.dialog.CheckoutDialog;
import ghidra.framework.data.CheckinHandler;
import ghidra.framework.main.FrontEndTool;
import ghidra.framework.main.OpenVersionedFileDialog;
import ghidra.framework.model.*;
import ghidra.framework.remote.User;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.SourceType;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskLauncher;
import ghidra.util.task.TaskMonitor;
public class ProgramManagerPluginScreenShots extends GhidraScreenShotGenerator
implements CheckinHandler {
private String checkinComment;
private boolean keepCheckedOut = true;
public ProgramManagerPluginScreenShots() {
super();
}
@Test
public void testClosedTab() throws Exception {
createAndOpenPrograms(2, 1);
closeProvider(DataTypesProvider.class);
captureToolWindow(900, 400);
drawOval(Palette.PURPLE, new Rectangle(280, 92, 190, 60), 8);
}
@Test
public void testEditDate() {
DateEditor dateEditor = new DateEditor();
Component datePanel = dateEditor.getCustomEditor();
final JButton button = (JButton) getInstanceField("browseButton", datePanel);
runSwing(() -> pressButton(button), false);
captureDialog(-1, -1);// Let is keep its size, lest we get a bunch of "..."
}
@Test
public void testFileNotCheckedOut() {
User user = new User("User 1", User.WRITE);
CheckoutDialog checkoutDialog = new CheckoutDialog(program.getDomainFile(), user);
showDialogWithoutBlocking(tool, checkoutDialog);
captureDialog();
}
@Test
public void testFrontEnd3() throws Exception {
createAndOpenPrograms(3, 1);
tool.setConfigChanged(false);
env.closeTool(tool);
FrontEndTool frontEndTool = getFrontEndTool();
captureWindow(frontEndTool.getActiveWindow(), 500, 500);
}
@Test
public void testFrontEndWithProgram() throws Exception {
createAndOpenPrograms(3, 1);
tool.setConfigChanged(false);
FrontEndTool frontEndTool = getFrontEndTool();
captureWindow(frontEndTool.getActiveWindow(), 500, 500);
}
@Test
public void testOpenHistory() throws Exception {
Project project = env.getProject();
ProjectData projectData = project.getProjectData();
projectData.getRootFolder()
.createFile("WinHelloCpp.exe", program,
TaskMonitor.DUMMY);
DomainFile df = program.getDomainFile();
addItemToVersionControl(df, "Added to Version Control", true);
// Make change
Program p = (Program) df.getDomainObject(this, false, false, null);
changeProgram(p, "aaa");
checkinComment = "Version 2";
keepCheckedOut = true;
assertTrue(df.canCheckin());
df.checkin(this, null);
changeProgram(p, "bbb");
checkinComment = "Version 3";
keepCheckedOut = true;
assertTrue(df.canCheckin());
df.checkin(this, null);
p.release(this);
performAction("Open File", "ProgramManagerPlugin", false);
final OpenVersionedFileDialog dialog = (OpenVersionedFileDialog) getDialog();
waitForSwing();
Object treePanel = getInstanceField("treePanel", dialog);
final GTree tree = (GTree) getInstanceField("tree", treePanel);
GTreeNode rootNode = tree.getViewRoot();
GTreeNode child = rootNode.getChild(0);
tree.setSelectedNode(child);
assertNotNull(dialog);
runSwing(() -> invokeInstanceMethod("advancedButtonCallback", dialog));
captureDialog(850, 400);
closeAllWindows();
}
@Test
public void testOpenProgram() throws Exception {
createAndOpenPrograms(3, 1);
performAction("Open File", "ProgramManagerPlugin", false);
captureDialog(500, 400);
closeAllWindows();
}
@Test
public void testOpenProgramMenu() throws Exception {
createAndOpenPrograms(3, 1);
performAction("Open File", "ProgramManagerPlugin", false);
waitForSwing();
DialogComponentProvider dialog = getDialog();
Object treePanel = getInstanceField("treePanel", dialog);
GTree tree = (GTree) getInstanceField("tree", treePanel);
JTree jTree = (JTree) getInstanceField("tree", tree);
Rectangle rowBounds = jTree.getRowBounds(1);
waitForTree(tree);
rightClick(jTree, rowBounds.x + 25, rowBounds.y + 10);
waitForSwing();
captureDialog();
closeAllWindows();
}
@Test
public void testProgramOptionsDialog() {
performAction("Program Options", "ProgramManagerPlugin", false);
OptionsDialog dialog = (OptionsDialog) getDialog();
Object optionsPanel = getInstanceField("panel", dialog);
GTree tree = (GTree) getInstanceField("gTree", optionsPanel);
GTreeNode rootNode = tree.getViewRoot();
GTreeNode child = rootNode.getChild("Program Information");
tree.setSelectedNode(child);
waitForTree(tree);
waitForSwing();
captureDialog();
}
@Test
public void testProgramTabs_No_Hidden() throws Exception {
createAndOpenPrograms(4, 2);
setToolSize(800, 400);
goToListing(0x04002ba);
captureIsolatedProvider(CodeViewerProvider.class, 600, 350);
}
@Test
public void testProgramTabs_With_Hidden_Go_to_Program() throws Exception {
CodeViewerProvider provider = getProvider(CodeViewerProvider.class);
moveProviderToItsOwnWindow(provider);
createAndOpenPrograms(6, 2);
goToListing(0x04002ba);
Window window = windowForComponent(provider.getComponent());
setWindowSize(window, 600, 350);
waitForSwing();
performAction("Go To Program", "MultiTabPlugin", true);
captureProviderWithScreenShot(provider);
}
@Test
public void testProgramTabs_With_Hidden_More_Button() throws Exception {
CodeViewerProvider provider = getProvider(CodeViewerProvider.class);
moveProviderToItsOwnWindow(provider);
Window window = windowForComponent(provider.getComponent());
setWindowSize(window, 600, 350);
waitForSwing();
createAndOpenPrograms(6, 3);
captureProvider(CodeViewerProvider.class);
drawOval(Palette.PURPLE, new Rectangle(440, 16, 70, 50), 8);
}
@Test
public void testProgramTabs_With_Hidden_Popup_Window() throws Exception {
CodeViewerProvider provider = getProvider(CodeViewerProvider.class);
moveProviderToItsOwnWindow(provider);
createAndOpenPrograms(6, 2);
goToListing(0x04002ba);
Window window = windowForComponent(provider.getComponent());
setWindowSize(window, 600, 350);
waitForSwing();
MultiTabPlugin plugin = getPlugin(tool, MultiTabPlugin.class);
Object tabPanel = getInstanceField("tabPanel", plugin);
JLabel label = (JLabel) getInstanceField("showHiddenListLabel", tabPanel);
leftClick(label, 5, 5);
waitForSwing();
Component popupDialog = (Component) getInstanceField("listWindow", tabPanel);
Component dockableComponent = getDockableComponent(provider.getComponent());
captureComponents(Arrays.asList(dockableComponent, popupDialog));
}
@Test
public void testProgramTabs_With_Highlighted_Tab() throws Exception {
CodeViewerProvider provider = getProvider(CodeViewerProvider.class);
moveProviderToItsOwnWindow(provider);
Window window = windowForComponent(provider.getComponent());
setWindowSize(window, 600, 350);
waitForSwing();
createAndOpenPrograms(6, 1);
runSwing(() -> {
MultiTabPlugin plugin = getPlugin(tool, MultiTabPlugin.class);
invokeInstanceMethod("highlightNextProgram", plugin, new Class<?>[] { boolean.class },
new Object[] { true });
});
captureProvider(CodeViewerProvider.class);
drawOval(Palette.PURPLE, new Rectangle(221, 16, 140, 50), 8);
}
@Test
public void testSaveProgram() {
runSwing(() -> OptionDialog.showOptionDialog(tool.getToolFrame(), "Save Program?",
"program1 has changed. Do you want to save it?", "&Save", "Do&n't Save",
OptionDialog.QUESTION_MESSAGE), false);
captureDialog();
}
@Test
public void testSaveProgramAs() throws Exception {
Program p = createAndOpenPrograms(4, 0);
changeProgram(p, "Hey");
performAction("Save As File", "ProgramManagerPlugin", false);
captureDialog(300, 300);
pressButtonOnDialog("Cancel");
}
@Test
public void testTabs() throws Exception {
createAndOpenPrograms(2, 1);
goToListing(0x04002ba);
captureIsolatedProvider(CodeViewerProvider.class, 600, 230);
}
private Program createAndOpenPrograms(int count, int currentProgramIndex) throws Exception {
program = env.getProgram("WinHelloCPP.exe");
CodeViewerProvider provider = getProvider(CodeViewerProvider.class);
Project project = env.getProject();
ProjectData projectData = project.getProjectData();
List<DomainFile> list = new ArrayList<>();
for (int i = 0; i < count; i++) {
String programName = "Program" + (i + 1) + ".exe";
list.add(projectData.getRootFolder()
.createFile(programName, program,
TaskMonitor.DUMMY));
}
program.flushEvents();
ProgramManager service = tool.getService(ProgramManager.class);
service.closeAllPrograms(true);
List<Program> programs = new ArrayList<>();
for (DomainFile domainFile : list) {
programs.add(service.openProgram(domainFile));
}
service.setCurrentProgram(programs.get(currentProgramIndex));
return programs.get(currentProgramIndex);
}
private void changeProgram(Program p, String labelName) {
int txId = p.startTransaction("create symbol");
try {
p.getSymbolTable().createLabel(getAddr(p, 0), labelName, SourceType.USER_DEFINED);
}
catch (Exception e) {
Assert.fail("Unexpected Exception creating symbol");
}
finally {
p.endTransaction(txId, true);
}
try {
p.save(null, null);
}
catch (Exception e) {
Assert.fail("Unexpected Exception saving Exception");
}
}
private void addItemToVersionControl(DomainFile domainFile, String comment,
boolean keepItCheckedOut) throws Exception {
TaskLauncher.launchModal(comment, () -> {
try {
domainFile.addToVersionControl(comment, keepItCheckedOut,
TaskMonitor.DUMMY);
}
catch (CancelledException | IOException e) {
throw new RuntimeException(e);
}
});
waitForSwing();
}
private Address getAddr(Program p, long offset) {
AddressFactory addrMap = p.getAddressFactory();
AddressSpace space = addrMap.getDefaultAddressSpace();
return space.getAddress(offset);
}
@Override
public String getComment() {
return checkinComment;
}
@Override
public boolean keepCheckedOut() {
return keepCheckedOut;
}
@Override
public boolean createKeepFile() throws CancelledException {
return false;
}
}