/* Copyright (C) 2009 Mobile Sorcery AB
This program is free software; you can redistribute it and/or modify it
under the terms of the Eclipse Public License v1.0.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the Eclipse Public License v1.0 for
more details.
You should have received a copy of the Eclipse Public License v1.0 along
with this program. It is also available at http://www.eclipse.org/legal/epl-v10.html
*/
package com.mobilesorcery.sdk.smoketests;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.TimeUnit;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.mobilesorcery.sdk.core.CoreMoSyncPlugin;
import com.mobilesorcery.sdk.core.IEmulatorProcessListener;
import com.mobilesorcery.sdk.core.MoSyncBuilder;
import com.mobilesorcery.sdk.core.MoSyncNature;
import com.mobilesorcery.sdk.core.MoSyncProject;
import com.mobilesorcery.sdk.core.MoSyncTool;
import com.mobilesorcery.sdk.swtbot.SWTBotProjectExplorer;
/**
* <p>
* The main entry point for automated functional testing, with focus on a few
* major use cases being 'smoke tested' (although we do some asserts while we're
* at it, so it's a tad more than just 'does it start at all?')
* <p>
* <b>Tested use cases (or planned to be):</b>
* <ul>
* <li>Build and run on emulator</li>
* <li>Start a debugging session, set a few breakpoints, make sure they are hit</li>
* <li>Simple incremental build and dependencies between projects</li>
* </ul>
* </p>
*
* @author Mattias Bybro, mattias.bybro@purplescout.com/mattias@bybro.com
*
*/
@RunWith(SWTBotJunit4ClassRunner.class)
public class Main {
private static final int RUN = 0;
private static final int DEBUG = 1;
private static SWTWorkbenchBot ui;
private static boolean firstTest = true;
@BeforeClass
public static void beforeClass() throws Exception {
ui = new SWTWorkbenchBot();
// Close welcome view.
ui.viewByTitle("Welcome").close();
}
@Before
public void pause() throws InterruptedException {
if (!firstTest) {
Thread.sleep(3000);
// Just to allow sockets etc to close between tests.
}
firstTest = false;
}
@Test
public void createAndRunProject() throws Exception {
MoSyncProject projectA = createProjectWithFiles("a", new String[] {
"/files/test.c", "/files/dummy.c" }, new String[] { "test.c",
"dummy.c" });
defaultInit(projectA);
MockEmulatorProcessListener listener = new MockEmulatorProcessListener();
listener.connect();
try {
botRunProject(projectA, listener, RUN);
listener.awaitStopped(30, TimeUnit.SECONDS);
assertTrue(listener.getStreamedData().contains("It worked!"));
} finally {
listener.disconnect();
}
}
@Test
public void createAndDebugProject() throws Exception {
MoSyncProject project = createProjectWithFiles("debug",
new String[] { "/files/bp_test.c" },
new String[] { "bp_test.c" });
project.setProperty(MoSyncBuilder.DEAD_CODE_ELIMINATION, Boolean.TRUE
.toString());
defaultInit(project);
// Add breakpoints
BreakpointTestParser parser = new BreakpointTestParser();
parser.parse(getClass().getResourceAsStream("/files/bp_test.c"),
project.getWrappedProject().getFile(new Path("bp_test.c")));
MockEmulatorProcessListener listener = new MockEmulatorProcessListener();
listener.connect();
try {
botRunProject(project, listener, DEBUG);
listener.awaitBreakpointHit(30, TimeUnit.SECONDS);
okPerspectiveSwitch();
// TODO; activate this.
// assertFalse("Breakpoint should NOT contain this message yet!",
// listener.getStreamedData().contains("After breakpoint"));
debugContinue();
listener.awaitStopped(30, TimeUnit.SECONDS);
assertTrue("Breakpoint SHOULD contain this message at this point!",
listener.getStreamedData().contains("BEFORE"));
assertTrue(listener.getStreamedData().contains("It still works!"));
} finally {
listener.disconnect();
}
}
private void debugContinue() {
ui.menu("Run").menu("Resume").click();
}
private void okPerspectiveSwitch() {
try {
SWTBotShell confirmDialog = ui.shell("Confirm Perspective Switch");
confirmDialog.activate();
ui.button("Yes").click();
} catch (WidgetNotFoundException e) {
// So... there was no such dialog, right?
}
}
private void defaultInit(MoSyncProject project) {
project.setTargetProfile(MoSyncTool.getDefault()
.getDefaultEmulatorProfile());
setPerspective("MoSync");
}
private MoSyncProject createProjectWithFiles(String projectName,
String[] src, String[] dest) throws Exception {
MoSyncProject project = botCreateProject(projectName);
for (int i = 0; i < src.length; i++) {
addFile(project, src[i], dest[i]);
}
return project;
}
private void addFile(MoSyncProject project, String src, String dest)
throws CoreException {
IFile destFile = project.getWrappedProject().getFile(new Path(dest));
destFile.create(getClass().getResourceAsStream(src), true,
new NullProgressMonitor());
assertTrue(destFile.exists());
}
private void setPerspective(String perspectiveName) {
ui.perspectiveByLabel(perspectiveName).activate();
}
void botRunProject(MoSyncProject project,
IEmulatorProcessListener listener, int mode) {
CoreMoSyncPlugin.getDefault().getEmulatorProcessManager()
.addEmulatorProcessListener(listener);
SWTBotProjectExplorer explorer = new SWTBotProjectExplorer(ui);
explorer.select(project.getWrappedProject());
System.err.println(ui.activeShell().getText());
SWTBotMenu runMenu = ui.menu("Run");
SWTBotMenu runRunMenu = runMenu.menu(mode == RUN ? "Run" : "Debug");
runRunMenu.click();
String shellTitle = mode == RUN ? "Run As" : "Debug As";
if (ui.shells(shellTitle).size() > 0) {
ui.shell(shellTitle).activate();
ui.table().select("Run MoRE Emulator");
ui.button("OK").click();
}
}
MoSyncProject botCreateProject(String name) throws Exception {
ui.menu("File").menu("New").menu("Project...").click();
SWTBotShell shell = ui.activeShell();
shell.activate();
ui.tree().select("MoSync Project");
clickNext();
ui.textWithLabel("Project name:").setText(name);
clickNext();
ui.checkBox(0).click();
clickFinish();
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(
name);
assertTrue(project.exists());
assertTrue(MoSyncNature.hasNature(project));
return MoSyncProject.create(project);
}
private void clickFinish() {
ui.button("Finish").click();
}
private void clickNext() {
ui.button("Next >").click();
}
@AfterClass
public static void sleep() {
ui.sleep(2000);
}
}