Skip to content
This repository has been archived by the owner on Jan 28, 2023. It is now read-only.

Commit

Permalink
Support for running a test fixture + test + simplified the setup + re…
Browse files Browse the repository at this point in the history
…adme
  • Loading branch information
lilbaek committed Oct 6, 2019
1 parent 89e4110 commit 69a1187
Show file tree
Hide file tree
Showing 13 changed files with 123 additions and 108 deletions.
37 changes: 35 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,35 @@
# webstorm-testcafe
Plugin for webstorm to integrate with TestCafe
# TestCafe runner for Webstorm

Integration with[TestCafe](https://devexpress.github.io/testcafe/) TestCafe A node.js tool to automate end-to-end web testing.
This plugin allows you to run TestCafe tests directly from Webstorm.

* Run a particular test, fixture, all tests in a file or directory via the context menu
* View test results in the 'Run Console'

![Demo](./images/demo.gif)

## Requirements

TestCafe should be installed in your project as a local package. To install it, use the npm install testcafe command or add TestCafe to dependencies in your package.json file. Your project should contain TestCafe modules in node_modules\testcafe\....

### Running a specific test

To run a specific test, invoke the context menu when the cursor is placed on the test name.

![Target] (./images/specific.png)

### Running all tests in a fixture

To run all tests in a test fixture, invoke the context menu when the cursor is placed on the fixture name.

![Target] (./images/fixture.png)

### Running all tests in a file

To run all tests in the current file, invoke the context menu for this file.

### Running all tests in a folder

To run all test files in a folder, invoke the context menu for this folder.

![Target] (./images/alltests.png)
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
}

group 'com.lilbaek'
version '0.2'
version '0.3'

sourceCompatibility = 1.8

Expand All @@ -30,6 +30,7 @@ patchPluginXml {
Early DRAFT<br>
<em>Feedback welcome.</em>
<ul>
<li><b>0.3.0</b> - Support for targeting a specific fixture
<li><b>0.2.0</b> - First version with support for running TestCafe tests
</li>
</ul>"""
Expand Down
Binary file added images/alltests.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/fixture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/specific.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.lilbaek.webstorm.testcafe.run;

public class TestCafeCurrentSetup {
public static String Folder;
public static String TestName;
public static String FixtureName;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.lilbaek.webstorm.testcafe.run;

import com.intellij.execution.CommandLineUtil;
import com.intellij.execution.Platform;
import com.intellij.execution.configurations.GeneralCommandLine;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;

public class TestCafeGeneralCommandLine extends GeneralCommandLine {

@NotNull
@Override
protected List<String> prepareCommandLine(@NotNull String command, @NotNull List<String> parameters, @NotNull Platform platform) {
return super.prepareCommandLine(command, parameters, platform);
//Don't do all kinds of Windows magic woodo. Just accept what is send in
/*List<String> commandLine = new ArrayList<>(parameters.size() + 1);
commandLine.addAll(parameters);
return commandLine;*/
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ public TestCafeRunProfileState getState(@NotNull Executor executor, @NotNull Exe
}

static class Options {
String testCafeFolder;
String testCafeTestName;
String browser;
}

Expand All @@ -57,12 +55,6 @@ public Icon getIcon() {

static void writeOptions(Options options, Element element) {
Element e = new Element(TestCafeRunConfiguration.class.getSimpleName());
if (options.testCafeFolder != null) {
e.setAttribute("testcafe-folder", options.testCafeFolder);
}
if (options.testCafeTestName != null) {
e.setAttribute("testcafe-testname", options.testCafeTestName);
}
if(options.browser != null) {
e.setAttribute("testcafe-browser", options.browser);
}
Expand All @@ -76,21 +68,11 @@ static Options readOptions(Element element) {
Element optionsElement = element.getChild(name);

if (optionsElement != null) {
Attribute folder = optionsElement.getAttribute("testcafe-folder");
Attribute browser = optionsElement.getAttribute("testcafe-browser");
Attribute testName = optionsElement.getAttribute("testcafe-testname");
result.testCafeFolder = null;
result.browser = null;
result.testCafeTestName = null;
if (folder != null) {
result.testCafeFolder = folder.getValue();
}
if(browser != null) {
result.browser = browser.getValue();
}
if(testName != null) {
result.testCafeTestName = testName.getValue();
}
}
return result;
}
Expand All @@ -108,9 +90,6 @@ public void writeExternal(@NotNull Element element) throws WriteExternalExceptio
@Nullable
@Override
public String suggestedName() {
if (options.testCafeFolder == null) {
return null;
}
return "TestCafe";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;

Expand All @@ -31,31 +32,14 @@ protected boolean setupConfigurationFromContext(TestCafeRunConfiguration configu
Location location = context.getLocation();
if(location.getVirtualFile() != null) {
VirtualFile file = location.getVirtualFile();
TestCafeCurrentSetup.TestName = null;
TestCafeCurrentSetup.FixtureName = null;
TestCafeCurrentSetup.Folder = null;
if(file.isDirectory()) {
configuration.options.testCafeFolder = file.getPath();
configuration.options.testCafeTestName = null;
TestCafeCurrentSetup.Folder = file.getPath();
configuration.setGeneratedName();
} else {
//TODO: Use PsiElement to target a specific test instead of the entire fixture.
String content = new String(file.contentsToByteArray());
if (content.toLowerCase().contains("fixture")) {
PsiElement element = sourceElement.get();
if(element.getNode() != null) {
IElementType type = element.getNode().getElementType();
String typeAsString = type.toString();
if (typeAsString.equals("JS:STRING_LITERAL")) {
configuration.options.testCafeTestName = element.getText().replace("'", "").replace("\"", "");
} else {
configuration.options.testCafeTestName = null;
}
} else {
configuration.options.testCafeTestName = null;
}
configuration.options.testCafeFolder = file.getPath();
configuration.setGeneratedName();
return true;

}
return CheckIfFileIsTestCafe(configuration, sourceElement, file);
}
}
}
Expand All @@ -65,8 +49,44 @@ protected boolean setupConfigurationFromContext(TestCafeRunConfiguration configu
return false;
}

private boolean CheckIfFileIsTestCafe(TestCafeRunConfiguration configuration, Ref<PsiElement> sourceElement, VirtualFile file) throws IOException {
//File should contain a fixture or we are not interested
String content = new String(file.contentsToByteArray());
if (content.toLowerCase().contains("fixture")) {
PsiElement element = sourceElement.get();
if(element.getNode() != null) {
IElementType type = element.getNode().getElementType();
String typeAsString = type.toString();
//Potential specific test
if (typeAsString.equals("JS:STRING_LITERAL")) {
PsiElement testElement = PsiTreeUtil.findFirstParent(element, psiElement -> psiElement.getText().toLowerCase().startsWith("test"));
if(testElement != null) {
TestCafeCurrentSetup.TestName = removeIllegalChars(element.getText());
}
}
//Potential test fixture
if (typeAsString.equals("JS:STRING_TEMPLATE_PART")) {
//Check if we can get a fixture name instead
PsiElement fixtureElement = PsiTreeUtil.findFirstParent(element, psiElement -> psiElement.getText().toLowerCase().startsWith("fixture"));
if(fixtureElement != null) {
TestCafeCurrentSetup.FixtureName = removeIllegalChars(element.getText());
}
}
}
TestCafeCurrentSetup.Folder = file.getPath();
configuration.setGeneratedName();
return true;
}
return false;
}

private String removeIllegalChars(String str) {
return str.replace("'", "").replace("\"", "").replace("`", "");
}

@Override
public boolean isConfigurationFromContext(TestCafeRunConfiguration configuration, ConfigurationContext context) {
//TODO: Change the method to actually look at the config + context. This way we could have one config pr. type - fixture, tests file/folder.
return true;
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
package org.lilbaek.webstorm.testcafe.run;

import com.intellij.execution.DefaultExecutionResult;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionResult;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.CommandLineState;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.process.ColoredProcessHandler;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.testframework.TestConsoleProperties;
import com.intellij.execution.testframework.autotest.AbstractAutoTestManager;
import com.intellij.execution.testframework.autotest.ToggleAutoTestAction;
import com.intellij.execution.testframework.sm.SMCustomMessagesParsing;
import com.intellij.execution.testframework.sm.SMTestRunnerConnectionUtil;
import com.intellij.execution.testframework.sm.runner.OutputToGeneralTestEventsConverter;
Expand All @@ -24,14 +19,11 @@
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import jetbrains.buildServer.messages.serviceMessages.ServiceMessageVisitor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.SystemIndependent;

import java.util.List;

public class TestCafeRunProfileState extends CommandLineState {

private final TestCafeRunConfiguration configuration;
Expand All @@ -48,7 +40,7 @@ protected ProcessHandler startProcess() throws ExecutionException {
Project project = getEnvironment().getProject();
String basePath = project.getBasePath();

GeneralCommandLine commandLine = new GeneralCommandLine();
TestCafeGeneralCommandLine commandLine = new TestCafeGeneralCommandLine();
commandLine.setExePath("node.exe");

@SystemIndependent
Expand All @@ -61,20 +53,29 @@ protected ProcessHandler startProcess() throws ExecutionException {
commandLine.addParameter(configuration.options.browser);
}
commandLine.addParameter(testFolder);
if(configuration.options.testCafeTestName != null && !configuration.options.testCafeTestName.isEmpty()) {
if(TestCafeCurrentSetup.TestName != null && !TestCafeCurrentSetup.TestName.isEmpty()) {
commandLine.addParameter("-t");
String testName = configuration.options.testCafeTestName.replace("'", "").replace("\"", "");
String testName = removeIllegalChars(TestCafeCurrentSetup.TestName);
commandLine.addParameter(testName);
}
if(TestCafeCurrentSetup.FixtureName != null && !TestCafeCurrentSetup.FixtureName.isEmpty()) {
commandLine.addParameter("-f");
String fixtureName = removeIllegalChars(TestCafeCurrentSetup.FixtureName);
commandLine.addParameter(fixtureName);
}
commandLine.withParentEnvironmentType(GeneralCommandLine.ParentEnvironmentType.CONSOLE);
return new ColoredProcessHandler(commandLine);
}

private String removeIllegalChars(String str) {
return str.replace("'", "").replace("\"", "").replace("`", "");
}

@SystemIndependent
private String getTestFolder() {
return configuration.options.testCafeFolder == null || configuration.options.testCafeFolder.isEmpty()
return TestCafeCurrentSetup.Folder == null || TestCafeCurrentSetup.Folder.isEmpty()
? this.getEnvironment().getProject().getBasePath()
: configuration.options.testCafeFolder;
: TestCafeCurrentSetup.Folder;
}

@Nullable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.lilbaek.webstorm.testcafe.run.TestCafeSettingsEditor">
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="5" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="517" height="400"/>
Expand All @@ -22,38 +22,6 @@
</constraints>
<properties/>
</component>
<component id="8ebca" class="javax.swing.JLabel">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="File"/>
</properties>
</component>
<component id="37a57" class="javax.swing.JTextField" binding="testCafeFolder">
<constraints>
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
<component id="754c7" class="javax.swing.JLabel">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Test name"/>
</properties>
</component>
<component id="92937" class="javax.swing.JTextField" binding="testCafeTestName">
<constraints>
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
</children>
</grid>
</form>
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ public class TestCafeSettingsEditor extends SettingsEditor<TestCafeRunConfigurat

private JPanel myPanel;
private ComboBox<String> browserChooser;
private JTextField testCafeFolder;
private JTextField testCafeTestName;

TestCafeSettingsEditor(Project project) {
browserChooser.addItem("chrome");
Expand All @@ -44,23 +42,13 @@ protected JComponent createEditor() {
@Override
protected void resetEditorFrom(@NotNull TestCafeRunConfiguration configuration) {
browserChooser.setSelectedItem(configuration.options.browser);
testCafeFolder.setText(configuration.options.testCafeFolder);
testCafeTestName.setText(configuration.options.testCafeTestName);
}

@Override
protected void applyEditorTo(@NotNull TestCafeRunConfiguration configuration) {
String browser = (String) browserChooser.getSelectedItem();
String folder = (String) testCafeFolder.getText();
String testName = (String) testCafeTestName.getText();
if (folder != null) {
configuration.options.testCafeFolder = folder;
}
if(browser != null) {
configuration.options.browser = browser;
}
if(testName != null) {
configuration.options.testCafeTestName = testName;
}
}
}

0 comments on commit 69a1187

Please sign in to comment.