Kotlin Ultimate: Support Protractor run configurations for module directory
This commit is contained in:
@@ -37,7 +37,7 @@ dependencies {
|
|||||||
|
|
||||||
compile(ideaUltimatePreloadedDeps("*.jar", subdir = "nodejs_plugin/NodeJS/lib"))
|
compile(ideaUltimatePreloadedDeps("*.jar", subdir = "nodejs_plugin/NodeJS/lib"))
|
||||||
compile(ideaUltimateSdkCoreDeps("annotations", "trove4j", "intellij-core"))
|
compile(ideaUltimateSdkCoreDeps("annotations", "trove4j", "intellij-core"))
|
||||||
compile(ideaUltimateSdkDeps("openapi", "idea", "util"))
|
compile(ideaUltimateSdkDeps("openapi", "idea", "util", "jdom"))
|
||||||
compile(ideaUltimatePluginDeps("*.jar", plugin = "CSS"))
|
compile(ideaUltimatePluginDeps("*.jar", plugin = "CSS"))
|
||||||
compile(ideaUltimatePluginDeps("*.jar", plugin = "DatabaseTools"))
|
compile(ideaUltimatePluginDeps("*.jar", plugin = "DatabaseTools"))
|
||||||
compile(ideaUltimatePluginDeps("*.jar", plugin = "JavaEE"))
|
compile(ideaUltimatePluginDeps("*.jar", plugin = "JavaEE"))
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
<idea-plugin>
|
<idea-plugin>
|
||||||
<extensions defaultExtensionNs="com.intellij">
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.nodejs.KotlinMochaRunConfigurationProducer"/>
|
<configurationType implementation="org.jetbrains.kotlin.idea.nodejs.protractor.KotlinProtractorConfigurationType"/>
|
||||||
|
|
||||||
|
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.nodejs.mocha.KotlinMochaRunConfigurationProducer"/>
|
||||||
|
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.nodejs.protractor.KotlinProtractorRunConfigurationProducer"/>
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
||||||
|
|||||||
@@ -35,4 +35,4 @@ fun getJsClasspath(module: Module): List<String> {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-11
@@ -1,8 +1,23 @@
|
|||||||
package org.jetbrains.kotlin.idea.nodejs
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* 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.jetbrains.kotlin.idea.nodejs.mocha
|
||||||
|
|
||||||
import com.intellij.execution.RunManager
|
import com.intellij.execution.RunManager
|
||||||
import com.intellij.execution.actions.ConfigurationContext
|
import com.intellij.execution.actions.ConfigurationContext
|
||||||
import com.intellij.execution.configuration.EnvironmentVariablesData
|
|
||||||
import com.intellij.openapi.module.Module
|
import com.intellij.openapi.module.Module
|
||||||
import com.intellij.openapi.module.ModuleUtilCore
|
import com.intellij.openapi.module.ModuleUtilCore
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
@@ -13,14 +28,13 @@ import com.intellij.openapi.vfs.VfsUtilCore
|
|||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.PsiDirectory
|
import com.intellij.psi.PsiDirectory
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.impl.file.PsiJavaDirectoryImpl
|
|
||||||
import com.intellij.psi.util.PsiUtilCore
|
import com.intellij.psi.util.PsiUtilCore
|
||||||
import com.intellij.util.SmartList
|
import com.intellij.util.SmartList
|
||||||
import com.intellij.util.containers.SmartHashSet
|
import com.intellij.util.containers.SmartHashSet
|
||||||
import com.jetbrains.nodejs.mocha.MochaUtil
|
import com.jetbrains.nodejs.mocha.MochaUtil
|
||||||
import com.jetbrains.nodejs.mocha.execution.*
|
import com.jetbrains.nodejs.mocha.execution.*
|
||||||
import org.jetbrains.kotlin.idea.js.getJsClasspath
|
|
||||||
import org.jetbrains.kotlin.idea.js.getJsOutputFilePath
|
import org.jetbrains.kotlin.idea.js.getJsOutputFilePath
|
||||||
|
import org.jetbrains.kotlin.idea.nodejs.getNodeJsEnvironmentVars
|
||||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||||
import org.jetbrains.kotlin.idea.util.projectStructure.getModuleDir
|
import org.jetbrains.kotlin.idea.util.projectStructure.getModuleDir
|
||||||
import org.jetbrains.kotlin.js.resolve.JsPlatform
|
import org.jetbrains.kotlin.js.resolve.JsPlatform
|
||||||
@@ -30,7 +44,6 @@ import org.jetbrains.kotlin.psi.KtNamedFunction
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class KotlinMochaRunConfigurationProducer : MochaRunConfigurationProducer() {
|
class KotlinMochaRunConfigurationProducer : MochaRunConfigurationProducer() {
|
||||||
private data class TestElementInfo(val runSettings: MochaRunSettings, val enclosingTestElement: PsiElement)
|
private data class TestElementInfo(val runSettings: MochaRunSettings, val enclosingTestElement: PsiElement)
|
||||||
@@ -80,7 +93,7 @@ class KotlinMochaRunConfigurationProducer : MochaRunConfigurationProducer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createSuiteOrTestData(element: PsiElement, module: Module): TestElementPath? {
|
private fun createSuiteOrTestData(element: PsiElement, module: Module): TestElementPath? {
|
||||||
if (element is PsiDirectory && module.getModuleDir() == (element as PsiJavaDirectoryImpl).virtualFile.path) {
|
if (element is PsiDirectory && module.getModuleDir() == element.virtualFile.path) {
|
||||||
return TestElementPath.BySingleFile
|
return TestElementPath.BySingleFile
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,11 +146,7 @@ class KotlinMochaRunConfigurationProducer : MochaRunConfigurationProducer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val nodeJsClasspath = getJsClasspath(module).joinToString(File.pathSeparator) {
|
builder.setEnvData(module.getNodeJsEnvironmentVars())
|
||||||
val basePath = project.basePath ?: return@joinToString it
|
|
||||||
FileUtil.getRelativePath(basePath, it, '/') ?: it
|
|
||||||
}
|
|
||||||
builder.setEnvData(EnvironmentVariablesData.create(mapOf("NODE_PATH" to nodeJsClasspath), true))
|
|
||||||
|
|
||||||
return TestElementInfo(builder.build(), element)
|
return TestElementInfo(builder.build(), element)
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* 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.jetbrains.kotlin.idea.nodejs
|
||||||
|
|
||||||
|
import com.intellij.execution.configuration.EnvironmentVariablesData
|
||||||
|
import com.intellij.openapi.module.Module
|
||||||
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
|
import org.jetbrains.kotlin.idea.js.getJsClasspath
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
const val NODE_PATH_VAR = "NODE_PATH"
|
||||||
|
|
||||||
|
fun Module.getNodeJsEnvironmentVars(): EnvironmentVariablesData {
|
||||||
|
val nodeJsClasspath = getJsClasspath(this).joinToString(File.pathSeparator) {
|
||||||
|
val basePath = project.basePath ?: return@joinToString it
|
||||||
|
FileUtil.getRelativePath(basePath, it, '/') ?: it
|
||||||
|
}
|
||||||
|
return EnvironmentVariablesData.create(mapOf(NODE_PATH_VAR to nodeJsClasspath), true)
|
||||||
|
}
|
||||||
+52
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* 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.jetbrains.kotlin.idea.nodejs.protractor
|
||||||
|
|
||||||
|
import com.intellij.execution.configuration.ConfigurationFactoryEx
|
||||||
|
import com.intellij.execution.configurations.ConfigurationFactory
|
||||||
|
import com.intellij.execution.configurations.ConfigurationTypeBase
|
||||||
|
import com.intellij.execution.configurations.ConfigurationTypeUtil
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import icons.JavaScriptLanguageIcons
|
||||||
|
|
||||||
|
class KotlinProtractorConfigurationType : ConfigurationTypeBase(
|
||||||
|
"KotlinJavaScriptTestRunnerProtractor",
|
||||||
|
"Protractor",
|
||||||
|
NAME,
|
||||||
|
JavaScriptLanguageIcons.Protractor.Protractor
|
||||||
|
) {
|
||||||
|
init {
|
||||||
|
addFactory(object : ConfigurationFactoryEx<KotlinProtractorRunConfiguration>(this) {
|
||||||
|
override fun createTemplateConfiguration(project: Project) = KotlinProtractorRunConfiguration(project, this, NAME)
|
||||||
|
|
||||||
|
override fun isConfigurationSingletonByDefault() = true
|
||||||
|
|
||||||
|
override fun canConfigurationBeSingleton() = false
|
||||||
|
|
||||||
|
override fun onNewConfigurationCreated(configuration: KotlinProtractorRunConfiguration) = configuration.initialize()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val NAME = "Protractor"
|
||||||
|
|
||||||
|
fun getInstance() = ConfigurationTypeUtil.findConfigurationType(KotlinProtractorConfigurationType::class.java)
|
||||||
|
|
||||||
|
val factory: ConfigurationFactory
|
||||||
|
get() = getInstance().configurationFactories.first()
|
||||||
|
}
|
||||||
|
}
|
||||||
+103
@@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* 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.jetbrains.kotlin.idea.nodejs.protractor
|
||||||
|
|
||||||
|
import com.intellij.execution.Executor
|
||||||
|
import com.intellij.execution.configurations.ConfigurationFactory
|
||||||
|
import com.intellij.execution.configurations.LocatableConfigurationBase
|
||||||
|
import com.intellij.execution.configurations.RuntimeConfigurationError
|
||||||
|
import com.intellij.execution.runners.ExecutionEnvironment
|
||||||
|
import com.intellij.javascript.nodejs.interpreter.local.NodeJsLocalInterpreter
|
||||||
|
import com.intellij.javascript.nodejs.util.NodePackage
|
||||||
|
import com.intellij.javascript.protractor.ProtractorUtil
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.util.PathUtil
|
||||||
|
import org.jdom.Element
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
// Based on com.intellij.javascript.protractor.ProtractorRunConfiguration
|
||||||
|
class KotlinProtractorRunConfiguration(
|
||||||
|
project: Project,
|
||||||
|
factory: ConfigurationFactory,
|
||||||
|
name: String
|
||||||
|
) : LocatableConfigurationBase(project, factory, name) {
|
||||||
|
var runSettings = KotlinProtractorRunSettings()
|
||||||
|
|
||||||
|
val protractorPackage: NodePackage
|
||||||
|
get() {
|
||||||
|
val project = project
|
||||||
|
val interpreter = runSettings.interpreterRef.resolve(project)
|
||||||
|
return ProtractorUtil.getProtractorPackage(project, null, interpreter, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getState(executor: Executor, environment: ExecutionEnvironment) =
|
||||||
|
KotlinProtractorRunState(this, environment, protractorPackage)
|
||||||
|
|
||||||
|
override fun getConfigurationEditor() = KotlinProtractorRunConfigurationEditor(project)
|
||||||
|
|
||||||
|
override fun readExternal(element: Element) {
|
||||||
|
super.readExternal(element)
|
||||||
|
runSettings = KotlinProtractorRunSettings.readFromXML(element)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun writeExternal(element: Element) {
|
||||||
|
super.writeExternal(element)
|
||||||
|
runSettings.writeToXML(element)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun initialize() {
|
||||||
|
setNameChangedByUser(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun checkConfiguration() {
|
||||||
|
val isOptionalConfig = runSettings.testFileSystemDependentPath.isNotBlank() || runSettings.seleniumAddress.isNotBlank()
|
||||||
|
if (isOptionalConfig) {
|
||||||
|
validatePath("test file", runSettings.testFileSystemDependentPath, true, false)
|
||||||
|
if (runSettings.seleniumAddress.isBlank()) {
|
||||||
|
throw RuntimeConfigurationError("Unspecified Selenium address")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isOptionalConfig || runSettings.configFileSystemDependentPath.isNotBlank()) {
|
||||||
|
validatePath("configuration file", runSettings.configFileSystemDependentPath, true, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
val interpreter = runSettings.interpreterRef.resolve(project)
|
||||||
|
NodeJsLocalInterpreter.checkForRunConfiguration(interpreter)
|
||||||
|
|
||||||
|
validatePath("protractor package", protractorPackage.systemDependentPath, true, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun suggestedName(): String? {
|
||||||
|
val name = PathUtil.getFileName(runSettings.testFileSystemDependentPath)
|
||||||
|
return if (name.isNotBlank()) name else null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun validatePath(name: String,
|
||||||
|
path: String?,
|
||||||
|
shouldBeAbsolute: Boolean,
|
||||||
|
shouldBeDirectory: Boolean
|
||||||
|
) {
|
||||||
|
if (path.isNullOrBlank()) throw RuntimeConfigurationError("Unspecified " + name)
|
||||||
|
|
||||||
|
val file = File(path!!)
|
||||||
|
|
||||||
|
if (shouldBeAbsolute && !file.isAbsolute) throw RuntimeConfigurationError("No such " + name)
|
||||||
|
|
||||||
|
val exists = if (shouldBeDirectory) file.isDirectory else file.isFile
|
||||||
|
if (!exists) throw RuntimeConfigurationError("No such " + name)
|
||||||
|
}
|
||||||
|
}
|
||||||
+144
@@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* 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.jetbrains.kotlin.idea.nodejs.protractor
|
||||||
|
|
||||||
|
import com.intellij.execution.configuration.EnvironmentVariablesTextFieldWithBrowseButton
|
||||||
|
import com.intellij.javascript.nodejs.interpreter.NodeJsInterpreterField
|
||||||
|
import com.intellij.javascript.nodejs.util.NodePackageField
|
||||||
|
import com.intellij.javascript.protractor.ProtractorUtil
|
||||||
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
|
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
|
||||||
|
import com.intellij.openapi.options.SettingsEditor
|
||||||
|
import com.intellij.openapi.options.ex.SingleConfigurableEditor
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.ui.DialogWrapper
|
||||||
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
|
import com.intellij.ui.RawCommandLineEditor
|
||||||
|
import com.intellij.ui.TextFieldWithHistoryWithBrowseButton
|
||||||
|
import com.intellij.util.containers.ContainerUtil
|
||||||
|
import com.intellij.util.ui.FormBuilder
|
||||||
|
import com.intellij.util.ui.JBUI
|
||||||
|
import com.intellij.util.ui.SwingHelper
|
||||||
|
|
||||||
|
import javax.swing.*
|
||||||
|
import java.util.Collections
|
||||||
|
|
||||||
|
// Based com.intellij.javascript.protractor.ProtractorRunConfigurationEditor
|
||||||
|
class KotlinProtractorRunConfigurationEditor(private val myProject: Project) : SettingsEditor<KotlinProtractorRunConfiguration>() {
|
||||||
|
private val testFilePathTextFieldWithBrowseButton: TextFieldWithHistoryWithBrowseButton
|
||||||
|
private val seleniumAddressTextField: JTextField
|
||||||
|
private val extraOptionsEditor: RawCommandLineEditor
|
||||||
|
private val configPathTextFieldWithBrowseButton: TextFieldWithHistoryWithBrowseButton
|
||||||
|
private val interpreterField: NodeJsInterpreterField
|
||||||
|
private val protractorPackageField: NodePackageField
|
||||||
|
private val envVarsComponent: EnvironmentVariablesTextFieldWithBrowseButton
|
||||||
|
private val panel: JPanel
|
||||||
|
|
||||||
|
init {
|
||||||
|
testFilePathTextFieldWithBrowseButton = createTestFileTextField(myProject)
|
||||||
|
seleniumAddressTextField = JTextField()
|
||||||
|
extraOptionsEditor = RawCommandLineEditor().apply { dialogCaption = "Extra Protractor Options" }
|
||||||
|
configPathTextFieldWithBrowseButton = createConfigurationFileTextField(myProject)
|
||||||
|
interpreterField = NodeJsInterpreterField(myProject, false)
|
||||||
|
protractorPackageField = NodePackageField(myProject, ProtractorUtil.PACKAGE_NAME) { interpreterField.interpreter }
|
||||||
|
envVarsComponent = EnvironmentVariablesTextFieldWithBrowseButton()
|
||||||
|
panel = FormBuilder()
|
||||||
|
.setAlignLabelOnRight(false)
|
||||||
|
.addLabeledComponent("&Test file:", testFilePathTextFieldWithBrowseButton)
|
||||||
|
.addLabeledComponent("&Selenium address:", seleniumAddressTextField)
|
||||||
|
.addLabeledComponent("E&xtra Protractor options:", extraOptionsEditor)
|
||||||
|
.addComponent(JSeparator(), JBUI.scale(8))
|
||||||
|
.addLabeledComponent("&Configuration file:", configPathTextFieldWithBrowseButton)
|
||||||
|
.addComponent(JSeparator(), JBUI.scale(8))
|
||||||
|
.addLabeledComponent("Node &interpreter:", interpreterField, JBUI.scale(8))
|
||||||
|
.addLabeledComponent("&Protractor package:", protractorPackageField)
|
||||||
|
.addLabeledComponent("&Environment variables:", envVarsComponent)
|
||||||
|
.panel
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createConfigurationFileTextField(project: Project) = TextFieldWithHistoryWithBrowseButton().apply {
|
||||||
|
val textFieldWithHistory = childComponent
|
||||||
|
textFieldWithHistory.setHistorySize(-1)
|
||||||
|
textFieldWithHistory.setMinimumAndPreferredWidth(0)
|
||||||
|
SwingHelper.addHistoryOnExpansion(textFieldWithHistory) {
|
||||||
|
val newFiles = ProtractorUtil.listPossibleConfigFilesInProject(project)
|
||||||
|
val newFilePaths = ContainerUtil.map(newFiles) { file -> FileUtil.toSystemDependentName(file.path) }
|
||||||
|
Collections.sort(newFilePaths)
|
||||||
|
newFilePaths
|
||||||
|
}
|
||||||
|
|
||||||
|
SwingHelper.installFileCompletionAndBrowseDialog(
|
||||||
|
project,
|
||||||
|
this,
|
||||||
|
"Select Protractor Configuration File",
|
||||||
|
FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createTestFileTextField(project: Project) = TextFieldWithHistoryWithBrowseButton().apply {
|
||||||
|
val textFieldWithHistory = childComponent
|
||||||
|
textFieldWithHistory.setHistorySize(-1)
|
||||||
|
textFieldWithHistory.setMinimumAndPreferredWidth(0)
|
||||||
|
|
||||||
|
SwingHelper.installFileCompletionAndBrowseDialog(
|
||||||
|
project,
|
||||||
|
this,
|
||||||
|
"Select Protractor Configuration File",
|
||||||
|
FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun resetEditorFrom(runConfiguration: KotlinProtractorRunConfiguration) {
|
||||||
|
with(runConfiguration.runSettings) {
|
||||||
|
testFilePathTextFieldWithBrowseButton.setTextAndAddToHistory(testFileSystemDependentPath)
|
||||||
|
seleniumAddressTextField.text = seleniumAddress
|
||||||
|
extraOptionsEditor.text = extraOptions
|
||||||
|
configPathTextFieldWithBrowseButton.setTextAndAddToHistory(configFileSystemDependentPath)
|
||||||
|
interpreterField.interpreterRef = interpreterRef
|
||||||
|
protractorPackageField.selected = runConfiguration.protractorPackage
|
||||||
|
envVarsComponent.data = envData
|
||||||
|
}
|
||||||
|
updatePreferredWidth()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updatePreferredWidth() {
|
||||||
|
val dialogWrapper = DialogWrapper.findInstance(panel)
|
||||||
|
if (dialogWrapper is SingleConfigurableEditor) {
|
||||||
|
// dialog for single run configuration
|
||||||
|
interpreterField.setPreferredWidthToFitText()
|
||||||
|
protractorPackageField.setPreferredWidthToFitText()
|
||||||
|
SwingHelper.setPreferredWidthToFitText(testFilePathTextFieldWithBrowseButton)
|
||||||
|
SwingHelper.setPreferredWidthToFitText(seleniumAddressTextField)
|
||||||
|
SwingHelper.setPreferredWidthToFitText(configPathTextFieldWithBrowseButton)
|
||||||
|
ApplicationManager.getApplication().invokeLater { SwingHelper.adjustDialogSizeToFitPreferredSize(dialogWrapper) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun applyEditorTo(runConfiguration: KotlinProtractorRunConfiguration) {
|
||||||
|
ProtractorUtil.setProtractorPackage(myProject, protractorPackageField.selected)
|
||||||
|
runConfiguration.runSettings = runConfiguration.runSettings.copy(
|
||||||
|
interpreterRef = interpreterField.interpreterRef,
|
||||||
|
configFilePath = configPathTextFieldWithBrowseButton.text,
|
||||||
|
testFilePath = testFilePathTextFieldWithBrowseButton.text,
|
||||||
|
seleniumAddress = seleniumAddressTextField.text,
|
||||||
|
extraOptions = extraOptionsEditor.text,
|
||||||
|
envData = envVarsComponent.data
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createEditor() = panel
|
||||||
|
}
|
||||||
+64
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* 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.jetbrains.kotlin.idea.nodejs.protractor
|
||||||
|
|
||||||
|
import com.intellij.execution.actions.CompatibleRunConfigurationProducer
|
||||||
|
import com.intellij.execution.actions.ConfigurationContext
|
||||||
|
import com.intellij.openapi.module.ModuleUtilCore
|
||||||
|
import com.intellij.openapi.util.Ref
|
||||||
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
|
import com.intellij.psi.PsiDirectory
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.kotlin.idea.js.getJsOutputFilePath
|
||||||
|
import org.jetbrains.kotlin.idea.nodejs.getNodeJsEnvironmentVars
|
||||||
|
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||||
|
import org.jetbrains.kotlin.idea.util.projectStructure.getModuleDir
|
||||||
|
import org.jetbrains.kotlin.idea.util.projectStructure.module
|
||||||
|
import org.jetbrains.kotlin.js.resolve.JsPlatform
|
||||||
|
|
||||||
|
class KotlinProtractorRunConfigurationProducer :
|
||||||
|
CompatibleRunConfigurationProducer<KotlinProtractorRunConfiguration>(KotlinProtractorConfigurationType.getInstance()) {
|
||||||
|
override fun isConfigurationFromCompatibleContext(
|
||||||
|
configuration: KotlinProtractorRunConfiguration,
|
||||||
|
context: ConfigurationContext
|
||||||
|
): Boolean {
|
||||||
|
val contextPsi = context.psiLocation ?: return false
|
||||||
|
val module = contextPsi.module ?: return false
|
||||||
|
val testFilePath = getJsOutputFilePath(module, isTests = true, isMeta = false) ?: return false
|
||||||
|
return configuration.runSettings.testFileSystemDependentPath == FileUtil.toSystemDependentName(testFilePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setupConfigurationFromCompatibleContext(
|
||||||
|
configuration: KotlinProtractorRunConfiguration,
|
||||||
|
context: ConfigurationContext,
|
||||||
|
sourceElement: Ref<PsiElement>
|
||||||
|
): Boolean {
|
||||||
|
val element = context.psiLocation ?: return false
|
||||||
|
val module = ModuleUtilCore.findModuleForPsiElement(element) ?: return false
|
||||||
|
if (element !is PsiDirectory || module.getModuleDir() != element.virtualFile.path) return false
|
||||||
|
if (TargetPlatformDetector.getPlatform(module) !is JsPlatform) return false
|
||||||
|
val testFilePath = getJsOutputFilePath(module, true, false) ?: return false
|
||||||
|
|
||||||
|
sourceElement.set(element)
|
||||||
|
configuration.runSettings = configuration.runSettings.copy(
|
||||||
|
testFilePath = testFilePath,
|
||||||
|
envData = module.getNodeJsEnvironmentVars()
|
||||||
|
)
|
||||||
|
configuration.name = configuration.suggestedName()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
+63
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* 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.jetbrains.kotlin.idea.nodejs.protractor
|
||||||
|
|
||||||
|
import com.intellij.execution.configuration.EnvironmentVariablesData
|
||||||
|
import com.intellij.javascript.nodejs.interpreter.NodeJsInterpreterRef
|
||||||
|
import com.intellij.openapi.util.JDOMExternalizerUtil.*
|
||||||
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
|
import org.jdom.Element
|
||||||
|
|
||||||
|
data class KotlinProtractorRunSettings(
|
||||||
|
val interpreterRef: NodeJsInterpreterRef = NodeJsInterpreterRef.createProjectRef(),
|
||||||
|
private val configFilePath: String = "",
|
||||||
|
private val testFilePath: String = "",
|
||||||
|
val seleniumAddress: String = "",
|
||||||
|
val extraOptions: String = "",
|
||||||
|
val envData: EnvironmentVariablesData = EnvironmentVariablesData.DEFAULT
|
||||||
|
) {
|
||||||
|
val configFileSystemDependentPath get() = FileUtil.toSystemDependentName(configFilePath)
|
||||||
|
val testFileSystemDependentPath get() = FileUtil.toSystemDependentName(testFilePath)
|
||||||
|
|
||||||
|
fun writeToXML(element: Element) {
|
||||||
|
addElementWithValueAttribute(element, "config-file", FileUtil.toSystemIndependentName(configFileSystemDependentPath))
|
||||||
|
addElementWithValueAttribute(element, "test-file", FileUtil.toSystemIndependentName(testFileSystemDependentPath))
|
||||||
|
addElementWithValueAttribute(element, "selenium-address", seleniumAddress)
|
||||||
|
addElementWithValueAttribute(element, "extra-protractor-options", extraOptions)
|
||||||
|
addElementWithValueAttribute(element, "node-interpreter", interpreterRef.referenceName)
|
||||||
|
envData.writeExternal(element)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun readFromXML(element: Element): KotlinProtractorRunSettings {
|
||||||
|
val configFilePath = getFirstChildValueAttribute(element, "config-file")
|
||||||
|
val testFilePath = getFirstChildValueAttribute(element, "test-file")
|
||||||
|
val seleniumAddress = getFirstChildValueAttribute(element, "selenium-address")
|
||||||
|
val extraOptions = getFirstChildValueAttribute(element, "extra-protractor-options")
|
||||||
|
val interpreterRefName = getFirstChildValueAttribute(element, "node-interpreter")
|
||||||
|
val envData = EnvironmentVariablesData.readExternal(element)
|
||||||
|
return KotlinProtractorRunSettings(
|
||||||
|
NodeJsInterpreterRef.create(interpreterRefName ?: "project"),
|
||||||
|
configFilePath ?: "",
|
||||||
|
testFilePath ?: "",
|
||||||
|
seleniumAddress ?: "",
|
||||||
|
extraOptions ?: "",
|
||||||
|
envData
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* 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.jetbrains.kotlin.idea.nodejs.protractor
|
||||||
|
|
||||||
|
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.GeneralCommandLine
|
||||||
|
import com.intellij.execution.configurations.RunProfileState
|
||||||
|
import com.intellij.execution.process.ProcessHandler
|
||||||
|
import com.intellij.execution.process.ProcessTerminatedListener
|
||||||
|
import com.intellij.execution.runners.ExecutionEnvironment
|
||||||
|
import com.intellij.execution.testframework.TestConsoleProperties
|
||||||
|
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.SMTRunnerConsoleProperties
|
||||||
|
import com.intellij.execution.testframework.sm.runner.SMTestLocator
|
||||||
|
import com.intellij.execution.ui.ConsoleView
|
||||||
|
import com.intellij.javascript.HelperFilesLocator
|
||||||
|
import com.intellij.javascript.nodejs.NodeCommandLineUtil
|
||||||
|
import com.intellij.javascript.nodejs.debug.NodeLocalDebugRunProfileState
|
||||||
|
import com.intellij.javascript.nodejs.interpreter.local.NodeJsLocalInterpreter
|
||||||
|
import com.intellij.javascript.nodejs.util.NodePackage
|
||||||
|
import com.intellij.javascript.protractor.ProtractorConsoleFilter
|
||||||
|
import com.intellij.javascript.protractor.ProtractorOutputToGeneralTestEventsConverter
|
||||||
|
import com.intellij.javascript.protractor.ProtractorUtil
|
||||||
|
import com.intellij.javascript.testFramework.navigation.JSTestLocationProvider
|
||||||
|
import com.intellij.lang.javascript.buildTools.base.JsbtUtil
|
||||||
|
import com.intellij.openapi.util.Disposer
|
||||||
|
import com.intellij.util.PathUtil
|
||||||
|
import com.intellij.util.execution.ParametersListUtil
|
||||||
|
import java.io.File
|
||||||
|
import java.io.IOException
|
||||||
|
import java.nio.charset.StandardCharsets
|
||||||
|
|
||||||
|
class KotlinProtractorRunState(
|
||||||
|
private val runConfiguration: KotlinProtractorRunConfiguration,
|
||||||
|
private val environment: ExecutionEnvironment,
|
||||||
|
private val protractorPackage: NodePackage
|
||||||
|
) : RunProfileState, NodeLocalDebugRunProfileState {
|
||||||
|
companion object {
|
||||||
|
val FRAMEWORK_NAME = "KotlinProtractorJavaScriptTestRunner"
|
||||||
|
private val INTELLIJ_CONFIG_FILE_PATH = "protractor-intellij/lib/protractor-intellij-config.js"
|
||||||
|
}
|
||||||
|
|
||||||
|
private val project = runConfiguration.project
|
||||||
|
private val runSettings = runConfiguration.runSettings
|
||||||
|
|
||||||
|
override fun execute(debugPort: Int): ExecutionResult {
|
||||||
|
val interpreter = runSettings.interpreterRef.resolveAsLocal(project)
|
||||||
|
val commandLine = createCommandLine(interpreter, debugPort)
|
||||||
|
val processHandler = NodeCommandLineUtil.createProcessHandler(commandLine, false)
|
||||||
|
val consoleView = createSmtRunnerConsoleView(commandLine.workDirectory)
|
||||||
|
ProcessTerminatedListener.attach(processHandler)
|
||||||
|
consoleView.attachToProcess(processHandler)
|
||||||
|
foldCommandLine(consoleView, processHandler)
|
||||||
|
val executionResult = DefaultExecutionResult(consoleView, processHandler)
|
||||||
|
executionResult.setRestartActions(ToggleAutoTestAction())
|
||||||
|
return executionResult
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createSmtRunnerConsoleView(workingDirectory: File?): ConsoleView {
|
||||||
|
val testConsoleProperties = ProtractorConsoleProperties(runConfiguration, environment.executor, JSTestLocationProvider())
|
||||||
|
val consoleView = SMTestRunnerConnectionUtil.createConsole(FRAMEWORK_NAME, testConsoleProperties)
|
||||||
|
consoleView.addMessageFilter(ProtractorConsoleFilter(project, workingDirectory))
|
||||||
|
Disposer.register(environment, consoleView)
|
||||||
|
return consoleView
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun foldCommandLine(consoleView: ConsoleView, processHandler: ProcessHandler) {
|
||||||
|
val configFileName = PathUtil.getFileName(runSettings.configFileSystemDependentPath)
|
||||||
|
val testFileName = PathUtil.getFileName(runSettings.testFileSystemDependentPath)
|
||||||
|
val seleniumAddress = runSettings.seleniumAddress
|
||||||
|
val parameters = ArrayList<String>().apply {
|
||||||
|
add("protractor")
|
||||||
|
if (configFileName.isNotBlank()) {
|
||||||
|
add(configFileName)
|
||||||
|
}
|
||||||
|
if (testFileName.isNotBlank()) {
|
||||||
|
add("--specs=$testFileName")
|
||||||
|
}
|
||||||
|
if (seleniumAddress.isNotBlank()) {
|
||||||
|
add("--seleniumAddress=$seleniumAddress")
|
||||||
|
}
|
||||||
|
addAll(ParametersListUtil.parse(runSettings.extraOptions.trim()))
|
||||||
|
}
|
||||||
|
val foldedCommandLine = ParametersListUtil.join(parameters)
|
||||||
|
JsbtUtil.foldCommandLine(consoleView, processHandler, foldedCommandLine)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createCommandLine(interpreter: NodeJsLocalInterpreter, debugPort: Int): GeneralCommandLine {
|
||||||
|
val commandLine = GeneralCommandLine().apply { charset = StandardCharsets.UTF_8 }
|
||||||
|
|
||||||
|
runSettings.envData.configureCommandLine(commandLine, true)
|
||||||
|
|
||||||
|
val originalConfigFilePath = runSettings.configFileSystemDependentPath
|
||||||
|
val testFilePath = runSettings.testFileSystemDependentPath
|
||||||
|
val seleniumAddress = runSettings.seleniumAddress
|
||||||
|
val withConfigFile = originalConfigFilePath.isNotBlank()
|
||||||
|
commandLine.setWorkDirectory(project.basePath)
|
||||||
|
|
||||||
|
commandLine.exePath = interpreter.interpreterSystemDependentPath
|
||||||
|
NodeCommandLineUtil.addNodeOptionsForDebugging(commandLine, emptyList(), debugPort, true, interpreter, true)
|
||||||
|
NodeCommandLineUtil.configureUsefulEnvironment(commandLine)
|
||||||
|
commandLine.addParameter(ProtractorUtil.getProtractorMainJsFile(protractorPackage).absolutePath)
|
||||||
|
|
||||||
|
val intellijConfigFile = try {
|
||||||
|
HelperFilesLocator.getFileRelativeToHelpersDir(INTELLIJ_CONFIG_FILE_PATH)
|
||||||
|
}
|
||||||
|
catch (e: IOException) {
|
||||||
|
throw ExecutionException("Cannot locate wrapper config file", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
commandLine.addParameter(intellijConfigFile.absolutePath)
|
||||||
|
|
||||||
|
val actualConfigFilePath = if (withConfigFile) {
|
||||||
|
originalConfigFilePath
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val tempConfigFile = File.createTempFile("protractor", "conf.js")
|
||||||
|
tempConfigFile.writeText("exports.config = {}")
|
||||||
|
tempConfigFile.absolutePath
|
||||||
|
}
|
||||||
|
|
||||||
|
commandLine.addParameter("--intellijOriginalConfigFile=$actualConfigFilePath")
|
||||||
|
|
||||||
|
if (testFilePath.isNotBlank()) {
|
||||||
|
commandLine.addParameter("--specs=$testFilePath")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seleniumAddress.isNotBlank()) {
|
||||||
|
commandLine.addParameter("--seleniumAddress=$seleniumAddress")
|
||||||
|
}
|
||||||
|
|
||||||
|
commandLine.addParameters(ParametersListUtil.parse(runSettings.extraOptions.trim()))
|
||||||
|
|
||||||
|
commandLine.addParameter("--disableChecks")
|
||||||
|
|
||||||
|
return commandLine
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ProtractorConsoleProperties(
|
||||||
|
configuration: KotlinProtractorRunConfiguration,
|
||||||
|
executor: Executor,
|
||||||
|
private val myLocator: SMTestLocator
|
||||||
|
) : SMTRunnerConsoleProperties(configuration, FRAMEWORK_NAME, executor), SMCustomMessagesParsing {
|
||||||
|
init {
|
||||||
|
isUsePredefinedMessageFilter = false
|
||||||
|
setIfUndefined(TestConsoleProperties.HIDE_PASSED_TESTS, false)
|
||||||
|
setIfUndefined(TestConsoleProperties.HIDE_IGNORED_TEST, true)
|
||||||
|
setIfUndefined(TestConsoleProperties.SCROLL_TO_SOURCE, true)
|
||||||
|
setIfUndefined(TestConsoleProperties.SELECT_FIRST_DEFECT, true)
|
||||||
|
isIdBasedTestTree = true
|
||||||
|
isPrintTestingStartedTime = false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getTestLocator() = myLocator
|
||||||
|
|
||||||
|
override fun createTestEventsConverter(testFrameworkName: String, consoleProperties: TestConsoleProperties) =
|
||||||
|
ProtractorOutputToGeneralTestEventsConverter(testFrameworkName, consoleProperties.isEditable)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user