diff --git a/bundles/org.pitest.pitclipse.ui/src/org/pitest/pitclipse/ui/view/PitView.java b/bundles/org.pitest.pitclipse.ui/src/org/pitest/pitclipse/ui/view/PitView.java index d4b573a9..f706ab72 100644 --- a/bundles/org.pitest.pitclipse.ui/src/org/pitest/pitclipse/ui/view/PitView.java +++ b/bundles/org.pitest.pitclipse.ui/src/org/pitest/pitclipse/ui/view/PitView.java @@ -102,4 +102,15 @@ public synchronized void update(File result) { browser.setUrl(homeUrlString); } } + + @Override + public void dispose() { + // reset homeUrlString for tests in + // org.pitest.pitclipse.ui.tests.PitclipsePitSummaryViewTest + homeUrlString = null; + if (browser != null && !browser.isDisposed()) { + browser.dispose(); + } + super.dispose(); + } } diff --git a/tests/org.pitest.pitclipse.ui.tests/fragment.xml b/tests/org.pitest.pitclipse.ui.tests/fragment.xml index 72bc8bc9..69429f65 100644 --- a/tests/org.pitest.pitclipse.ui.tests/fragment.xml +++ b/tests/org.pitest.pitclipse.ui.tests/fragment.xml @@ -1,16 +1,16 @@ - - - - + + + + diff --git a/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/behaviours/pageobjects/PitSummaryView.java b/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/behaviours/pageobjects/PitSummaryView.java index e2d00732..589f2f56 100644 --- a/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/behaviours/pageobjects/PitSummaryView.java +++ b/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/behaviours/pageobjects/PitSummaryView.java @@ -18,16 +18,14 @@ import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; -import org.pitest.pitclipse.ui.behaviours.StepException; -import org.pitest.pitclipse.ui.swtbot.PitNotifier; -import org.pitest.pitclipse.ui.swtbot.PitResultsView; +import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; +import org.eclipse.swtbot.swt.finder.results.VoidResult; import static org.pitest.pitclipse.ui.view.PitView.BACK_BUTTON_TEXT; import static org.pitest.pitclipse.ui.view.PitView.FORWARD_BUTTON_TEXT; import static org.pitest.pitclipse.ui.view.PitView.HOME_BUTTON_TEXT; public class PitSummaryView { private static String SUMMARY_VIEW_TITLE = "PIT Summary"; - private PitResultsView lastResults = null; private SWTWorkbenchBot bot; private SWTBotView summaryView; @@ -35,26 +33,6 @@ public PitSummaryView(SWTWorkbenchBot bot) { this.bot = bot; } - public void waitForUpdate() { - try { - lastResults = PitNotifier.INSTANCE.getResults(); - } catch (InterruptedException e) { - throw new StepException(e); - } - } - - public int getClassesTested() { - return lastResults.getClassesTested(); - } - - public double getOverallCoverage() { - return lastResults.getTotalCoverage(); - } - - public double getMutationCoverage() { - return lastResults.getMutationCoverage(); - } - public void showViewIfNotOpen() { if (summaryView == null) { summaryView = bot.viewByTitle(SUMMARY_VIEW_TITLE); @@ -73,7 +51,6 @@ public String getCurrentBrowserUrl() { } public String clickBack() { - clickButtonWithText(BACK_BUTTON_TEXT); summaryView.bot().browser().waitForPageLoaded(); return getCurrentBrowserUrl(); @@ -91,9 +68,23 @@ public String clickForward() { return getCurrentBrowserUrl(); } + /** + * Sets the link in the browser via javaScript, because bot can't click links in + * browser + * @param hyperLinkText link which to set as url, can be relative + * @return new url of browser + */ public String setLink(String hyperLinkText) { showViewIfNotOpen(); - summaryView.bot().browser().setUrl(hyperLinkText); + // use this instead of the SWTBrowser.execute(), because we need syncExec + final String link = "window.location.href = '" + hyperLinkText + "'"; + summaryView.bot().browser().waitForPageLoaded(); + UIThreadRunnable.syncExec(new VoidResult() { + @Override + public void run() { + summaryView.bot().browser().widget.execute(link); + } + }); summaryView.bot().browser().waitForPageLoaded(); return getCurrentBrowserUrl(); } @@ -102,8 +93,8 @@ public String setLink(String hyperLinkText) { * Closes the view, if it is opened. */ public void closeView() { - showViewIfNotOpen(); if (summaryView != null) { + showViewIfNotOpen(); summaryView.close(); } } diff --git a/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/behaviours/pageobjects/RunMenu.java b/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/behaviours/pageobjects/RunMenu.java index a08a07d8..b226f7f0 100644 --- a/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/behaviours/pageobjects/RunMenu.java +++ b/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/behaviours/pageobjects/RunMenu.java @@ -47,6 +47,8 @@ public void runJUnit() { } public void runPit() { + // focus package explorer to ensure the menu is found + bot.viewByTitle("Package Explorer").setFocus(); SWTBotMenuHelper menuHelper = new SWTBotMenuHelper(); SWTBotMenu runAsMenu = bot.menu(RUN) .menu(RUN_AS); diff --git a/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/behaviours/steps/PitclipseSteps.java b/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/behaviours/steps/PitclipseSteps.java index 58a40ba2..f0d02542 100644 --- a/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/behaviours/steps/PitclipseSteps.java +++ b/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/behaviours/steps/PitclipseSteps.java @@ -47,8 +47,7 @@ import org.pitest.pitclipse.runner.PitOptions; import org.pitest.pitclipse.runner.results.DetectionStatus; import org.pitest.pitclipse.ui.behaviours.pageobjects.PackageContext; -import org.pitest.pitclipse.ui.behaviours.pageobjects.PitSummaryView; -import org.pitest.pitclipse.ui.swtbot.PitNotifier; +import org.pitest.pitclipse.ui.swtbot.PitResultNotifier.PitSummary; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableList; @@ -60,24 +59,24 @@ public class PitclipseSteps { @When("test {word} in package {word} is run for project {word}") - public void runTest(final String testClassName, final String packageName, final String projectName) throws CoreException { + public void runTest(final String testClassName, final String packageName, final String projectName) + throws CoreException { // No need to do a full build: we should be now synchronized with building // Build the whole workspace to prevent random compilation failures - // ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, new NullProgressMonitor()); - System.out.println - (String.format("Run PIT on: %s %s.%s", - projectName, packageName, testClassName)); + // ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, + // new NullProgressMonitor()); + System.out.println(String.format("Run PIT on: %s %s.%s", projectName, packageName, testClassName)); runPit(new SelectTestClass(testClassName, packageName, projectName)); } @Then("a coverage report is generated with {int} class/classes tested with overall coverage of {int}% and mutation coverage of {int}%") public void coverageReportGenerated(int classes, double totalCoverage, double mutationCoverage) { - PitSummaryView pitView = PAGES.getPitSummaryView(); - pitView.waitForUpdate(); + PAGES.views().waitForTestsAreRunOnConsole(); try { - assertEquals("Number of tested classes mismatch", classes, pitView.getClassesTested()); - assertDoubleEquals("Total coverage mismatch", totalCoverage, pitView.getOverallCoverage()); - assertDoubleEquals("Mutation coverage mismatch", mutationCoverage, pitView.getMutationCoverage()); + assertEquals("Number of tested classes mismatch", classes, PitSummary.INSTANCE.getClasses()); + assertDoubleEquals("Total coverage mismatch", totalCoverage, PitSummary.INSTANCE.getCodeCoverage()); + assertDoubleEquals("Mutation coverage mismatch", mutationCoverage, + PitSummary.INSTANCE.getMutationCoverage()); } catch (Error e) { e.printStackTrace(); throw e; @@ -161,8 +160,8 @@ private void runPit(Runnable runnable) { // make sure to clear the console to avoid interferences // with the output of previous runs PAGES.views().clearConsole(); - // make sure notifications not read are cleared - PitNotifier.INSTANCE.reset(); + // make sure summary is cleared + PitSummary.INSTANCE.reset(); int retryCount = 20; int counter = 0; while (counter < retryCount) { diff --git a/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/swtbot/PitNotifier.java b/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/swtbot/PitNotifier.java deleted file mode 100644 index a467182a..00000000 --- a/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/swtbot/PitNotifier.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * Copyright 2012-2019 Phil Glover and contributors - * - * 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 org.pitest.pitclipse.ui.swtbot; - -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.TimeUnit; - -import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences; - -public enum PitNotifier { - INSTANCE; - - private final BlockingQueue resultQueue = new ArrayBlockingQueue( - 1); - - public PitResultsView getResults() throws InterruptedException { - return resultQueue.poll(SWTBotPreferences.TIMEOUT, TimeUnit.MILLISECONDS); - } - - public void notifyResults(PitResultsView resultsView) - throws InterruptedException { - resultQueue.offer(resultsView, SWTBotPreferences.TIMEOUT, TimeUnit.MILLISECONDS); - } - - public void reset() { - resultQueue.clear(); - } -} diff --git a/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/swtbot/PitResultNotifier.java b/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/swtbot/PitResultNotifier.java index 2c015a91..ddc85f99 100644 --- a/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/swtbot/PitResultNotifier.java +++ b/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/swtbot/PitResultNotifier.java @@ -16,36 +16,66 @@ package org.pitest.pitclipse.ui.swtbot; +import java.io.IOException; + import org.pitest.pitclipse.core.extension.point.ResultNotifier; -import org.pitest.pitclipse.ui.extension.point.PitUiUpdate; +import org.pitest.pitclipse.runner.PitResults; import org.pitest.pitclipse.ui.swtbot.ResultsParser.Summary; -public class PitResultNotifier implements ResultNotifier { - @Override - public void handleResults(PitUiUpdate updateEvent) { - notifiyTestsOfHtmlResults(updateEvent); - } +public class PitResultNotifier implements ResultNotifier { + public enum PitSummary { + INSTANCE; - private void notifiyTestsOfHtmlResults(PitUiUpdate updateEvent) { - PitResultsView view = buildResultsView(updateEvent); - tryNotifyResults(view); - } + private Summary summary; + + /** + * @return covered classes or 0 if no summary is present + */ + public int getClasses() { + if (summary != null) { + return summary.getClasses(); + } + return 0; + } + + /** + * @return code coverage or 100 if no summary is present + */ + public double getCodeCoverage() { + if (summary != null) { + return summary.getCodeCoverage(); + } + return 100; + } - private PitResultsView buildResultsView(PitUiUpdate results) { - ResultsParser parser = new ResultsParser(results.getHtml()); - Summary summary = parser.getSummary(); - PitResultsView view = PitResultsView.builder().withClassesTested(summary.getClasses()) - .withTotalCoverage(summary.getCodeCoverage()).withMutationCoverage(summary.getMutationCoverage()) - .build(); - return view; + /** + * @return mutation coverage or 100 if no summary is present + */ + public double getMutationCoverage() { + if (summary != null) { + return summary.getMutationCoverage(); + } + return 100; + } + + public void reset() { + summary = null; + } + + void setSummary(Summary summary) { + this.summary = summary; + } } - private void tryNotifyResults(PitResultsView view) { + @Override + public void handleResults(PitResults results) { try { - PitNotifier.INSTANCE.notifyResults(view); - } catch (InterruptedException e) { - throw new RuntimeException(e); + // file only exists, if mutations were done + if (results.getHtmlResultFile() != null) { + PitSummary.INSTANCE.setSummary(new ResultsParser(results.getHtmlResultFile()).getSummary()); + } + } catch (IOException e) { + e.printStackTrace(); } } - } diff --git a/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/swtbot/ResultsParser.java b/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/swtbot/ResultsParser.java index 5980ffb4..ce20665d 100644 --- a/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/swtbot/ResultsParser.java +++ b/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/swtbot/ResultsParser.java @@ -22,6 +22,11 @@ import static java.lang.Double.parseDouble; import static java.lang.Integer.parseInt; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + public class ResultsParser { public static final class Summary { @@ -56,8 +61,8 @@ public double getMutationCoverage() { private final String html; - public ResultsParser(String html) { - this.html = html; + public ResultsParser(File file) throws IOException { + this.html = new String(Files.readAllBytes(Paths.get(file.getAbsolutePath()))); } private String getProjectSummary() { diff --git a/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/tests/AbstractPitclipseSWTBotTest.java b/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/tests/AbstractPitclipseSWTBotTest.java index ae96015c..d5621fbf 100644 --- a/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/tests/AbstractPitclipseSWTBotTest.java +++ b/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/tests/AbstractPitclipseSWTBotTest.java @@ -298,8 +298,6 @@ protected static void runTest(final String testClassName, final String packageNa } protected static void runPackageTest(final String packageName, final String projectName) throws CoreException { - // package explorer needs focus, otherwise will not run - bot.viewByTitle("Package Explorer").setFocus(); new PitclipseSteps().runPackageTest(packageName, projectName); } diff --git a/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/tests/PitclipsePitSummaryViewTest.java b/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/tests/PitclipsePitSummaryViewTest.java index a524098d..5efa8f29 100644 --- a/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/tests/PitclipsePitSummaryViewTest.java +++ b/tests/org.pitest.pitclipse.ui.tests/src/org/pitest/pitclipse/ui/tests/PitclipsePitSummaryViewTest.java @@ -1,11 +1,12 @@ package org.pitest.pitclipse.ui.tests; import org.eclipse.core.runtime.CoreException; +import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences; -import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.junit.runner.RunWith; import org.pitest.pitclipse.ui.behaviours.pageobjects.PitSummaryView; import org.pitest.pitclipse.ui.view.PitView; @@ -14,11 +15,13 @@ import static org.hamcrest.Matchers.equalTo; import static org.pitest.pitclipse.ui.behaviours.pageobjects.PageObjects.PAGES; +@RunWith(SWTBotJunit4ClassRunner.class) public class PitclipsePitSummaryViewTest extends AbstractPitclipseSWTBotTest { private static final String TEST_PROJECT = "org.pitest.pitclipse.testprojects.twoclasses"; private static final String FOO_BAR_PACKAGE = "foo.bar"; - private static final String EXAMPLE_URL = "https://www.example.com/"; private static final String BLANK_URL = "about:blank"; + private String FOO_BAR_PACKAGE_RESULT = "./foo.bar/"; + private String FOO_CLASS_RESULT = "Foo.java.html"; private static PitSummaryView summaryView; @@ -29,14 +32,9 @@ public static void setupJavaProject() throws CoreException { } @Before - public void openView() throws InterruptedException { - openViewById(PitView.VIEW_ID); - } - - @After - public void resetView() { + public void resetView() throws InterruptedException { summaryView.closeView(); - bot.closeAllEditors(); + openViewById(PitView.VIEW_ID); } @Test @@ -46,21 +44,22 @@ public void navigateWithButtons() throws CoreException { // set timeout to small time, because offline page loads should be quick and // some pages are expected to not change and need timeout SWTBotPreferences.TIMEOUT = 2; - // should not change page, because no page was opened before - assertThat(summaryView.clickHome(), equalTo(BLANK_URL)); - assertThat(summaryView.clickBack(), equalTo(BLANK_URL)); - assertThat(summaryView.clickForward(), equalTo(BLANK_URL)); + // should not change page + String lastUrl = summaryView.getCurrentBrowserUrl(); + assertThat(summaryView.clickHome(), equalTo(lastUrl)); // coverageReportGenerated needs normal timeout - runPackageTest(FOO_BAR_PACKAGE, TEST_PROJECT); SWTBotPreferences.TIMEOUT = timeout; + runPackageTest(FOO_BAR_PACKAGE, TEST_PROJECT); coverageReportGenerated(2, 80, 0); SWTBotPreferences.TIMEOUT = 2; - assertThat(summaryView.setLink(EXAMPLE_URL), equalTo(EXAMPLE_URL)); - assertThat(summaryView.clickForward(), equalTo(EXAMPLE_URL)); + assertThat(summaryView.getCurrentBrowserUrl(), endsWith("index.html")); + assertThat(summaryView.setLink(FOO_BAR_PACKAGE_RESULT + FOO_CLASS_RESULT), endsWith(FOO_CLASS_RESULT)); + assertThat(summaryView.setLink(FOO_BAR_PACKAGE_RESULT), endsWith("foo.bar/")); + assertThat(summaryView.clickBack(), endsWith(FOO_CLASS_RESULT)); assertThat(summaryView.clickBack(), endsWith("index.html")); - assertThat(summaryView.clickForward(), equalTo(EXAMPLE_URL)); + assertThat(summaryView.clickForward(), endsWith(FOO_CLASS_RESULT)); assertThat(summaryView.clickHome(), endsWith("index.html")); } finally { // reset SWTBotPreferences.TIMEOUT