Skip to content

Commit 1c1e69d

Browse files
committed
1263: Added UI tests for MarkDirectoryAsMagentoContentRoot
Added a null project check in `MarkDirectoryAsMagentoContentRoot` to prevent potential NPEs. Replaced `ServiceManager` with the modern `project.getService` for retrieving `Settings` instances. Additionally, updated workflows to run tests via a script and introduced new test fixtures for UI testing.
1 parent 5bd9238 commit 1c1e69d

File tree

20 files changed

+29519
-9
lines changed

20 files changed

+29519
-9
lines changed

.github/workflows/gradle.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
- name: Grant execute permission for gradlew
3333
run: chmod +x gradlew
3434
- name: Run automated tests
35-
run: ./gradlew test --no-daemon
35+
run: sh runTests.sh
3636

3737
build-windows:
3838
runs-on: windows-latest
@@ -58,7 +58,7 @@ jobs:
5858
- name: Grant execute permission for gradlew
5959
run: chmod +x gradlew
6060
- name: Run automated tests
61-
run: ./gradlew test --no-daemon
61+
run: sh runTests.sh
6262

6363
build-macos:
6464
runs-on: macos-latest
@@ -84,7 +84,7 @@ jobs:
8484
- name: Grant execute permission for gradlew
8585
run: chmod +x gradlew
8686
- name: Run automated tests
87-
run: ./gradlew test --no-daemon
87+
run: sh runTests.sh
8888

8989
static-tests:
9090
runs-on: ubuntu-latest

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,5 @@ out
3636
.gradle
3737
.idea-sandbox
3838
build
39-
.intellijPlatform/*
39+
.intellijPlatform/*
40+
video/*

build.gradle.kts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ dependencies {
4242

4343
implementation("com.googlecode.json-simple:json-simple:1.1.1")
4444
implementation("org.codehaus.plexus:plexus-utils:3.4.0")
45+
testImplementation("com.automation-remarks:video-recorder-junit5:2.0")
46+
testImplementation("com.intellij.remoterobot:remote-robot:0.11.23")
47+
testImplementation("com.intellij.remoterobot:remote-fixtures:0.11.23")
48+
testImplementation("com.squareup.okhttp3:logging-interceptor:4.12.0")
4549

4650
intellijPlatform {
4751
create(providers.gradleProperty("platformType"), providers.gradleProperty("platformVersion"))

runTests.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/bin/bash
2+
3+
./gradlew clean
4+
./gradlew runIdeForUiTests &
5+
RUN_IDE_PID=$!
6+
7+
sleep 10
8+
9+
./gradlew test --no-daemon
10+
11+
# run certain test
12+
#./gradlew test --tests "com.magento.idea.magento2plugin.actions.content.MarkDirectoryAsMagentoRootTest.testMarkDirectoryAsMagentoRoot" --scan
13+
14+
kill $RUN_IDE_PID
15+
16+
wait $RUN_IDE_PID 2>/dev/null

src/main/java/com/magento/idea/magento2plugin/actions/content/root/MarkDirectoryAsMagentoContentRot.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public void update(@NotNull final AnActionEvent event) {
6161
project = module.getProject();
6262
}
6363

64-
if (targetElement instanceof PsiDirectory) {
64+
if (targetElement instanceof PsiDirectory && project != null) {
6565
final Settings settings = Settings.getInstance(project);
6666
final String magentoPathUrl = MagentoPathUrlUtil.execute(project);
6767
final String directoryUrl = ((PsiDirectory) targetElement).getVirtualFile().getUrl();

src/main/java/com/magento/idea/magento2plugin/actions/content/root/UnmarkDirectoryAsMagentoContentRot.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public void update(@NotNull AnActionEvent event) {
5858
project = module.getProject();
5959
}
6060

61-
if (targetElement instanceof PsiDirectory) {
61+
if (targetElement instanceof PsiDirectory && project != null) {
6262
Settings settings = Settings.getInstance(project);
6363
String magentoPathUrl = MagentoPathUrlUtil.execute(project);
6464
String directoryUrl = ((PsiDirectory) targetElement).getVirtualFile().getUrl();

src/main/java/com/magento/idea/magento2plugin/actions/generation/dialog/CreateAPluginDialog.form

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@
6565
<preferred-size width="150" height="-1"/>
6666
</grid>
6767
</constraints>
68-
<properties/>
68+
<properties>
69+
<name value="Class Name"/>
70+
</properties>
6971
<clientProperties>
7072
<html.disable class="java.lang.Boolean" value="true"/>
7173
</clientProperties>

src/main/java/com/magento/idea/magento2plugin/project/Settings.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
import com.intellij.ide.util.PropertiesComponent;
99
import com.intellij.openapi.components.PersistentStateComponent;
10-
import com.intellij.openapi.components.ServiceManager;
1110
import com.intellij.openapi.components.State;
1211
import com.intellij.openapi.components.Storage;
1312
import com.intellij.openapi.project.Project;
@@ -153,7 +152,7 @@ public interface MagentoModuleDataListener extends EventListener {
153152
}
154153

155154
public static Settings getInstance(final Project project) {
156-
return ServiceManager.getService(project, Settings.class);
155+
return project.getService(Settings.class);
157156
}
158157

159158
public static boolean isEnabled(final @NotNull Project project) {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.magento.idea.magento2plugin.pages;
2+
3+
import com.intellij.remoterobot.RemoteRobot;
4+
import com.intellij.remoterobot.data.RemoteComponent;
5+
import com.intellij.remoterobot.fixtures.*;
6+
import org.jetbrains.annotations.NotNull;
7+
8+
import static com.intellij.remoterobot.search.locators.Locators.byXpath;
9+
import static com.intellij.remoterobot.utils.UtilsKt.hasAnyComponent;
10+
11+
12+
@DefaultXpath(by = "FlatWelcomeFrame type", xpath = "//div[@class='FlatWelcomeFrame']")
13+
@FixtureName(name = "Welcome Frame")
14+
public class WelcomeFrameFixture extends CommonContainerFixture {
15+
public WelcomeFrameFixture(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) {
16+
super(remoteRobot, remoteComponent);
17+
}
18+
19+
public ComponentFixture createNewProjectLink() {
20+
return welcomeFrameLink("New Project");
21+
}
22+
23+
public ComponentFixture importProjectLink() {
24+
return welcomeFrameLink("Get from VCS");
25+
}
26+
27+
private ComponentFixture welcomeFrameLink(String text) {
28+
if (hasAnyComponent(this, byXpath("//div[@class='NewRecentProjectPanel']"))) {
29+
return find(ComponentFixture.class, byXpath("//div[@class='JBOptionButton' and @text='" + text + "']"));
30+
}
31+
return find(
32+
ComponentFixture.class,
33+
byXpath("//div[(@class='MainButton' and @text='"+ text +"') or (@accessiblename='"+ text +"' and @class='JButton')]")
34+
);
35+
}
36+
}
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
/*
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
package com.magento.idea.magento2plugin.actions.content
7+
8+
import com.automation.remarks.junit5.Video
9+
import org.assertj.swing.core.MouseButton
10+
import com.intellij.remoterobot.RemoteRobot
11+
import com.intellij.remoterobot.fixtures.ContainerFixture
12+
import com.intellij.remoterobot.search.locators.byXpath
13+
import com.intellij.remoterobot.steps.CommonSteps
14+
import com.intellij.remoterobot.stepsProcessing.step
15+
import com.intellij.remoterobot.utils.keyboard
16+
import com.intellij.remoterobot.utils.waitFor
17+
import com.intellij.remoterobot.utils.waitForIgnoringError
18+
import com.magento.idea.magento2plugin.pages.*
19+
import com.magento.idea.magento2plugin.utils.RemoteRobotExtension
20+
import com.magento.idea.magento2plugin.utils.StepsLogger
21+
import org.junit.jupiter.api.AfterEach
22+
import org.junit.jupiter.api.BeforeEach
23+
import org.junit.jupiter.api.Test
24+
import org.junit.jupiter.api.extension.ExtendWith
25+
import java.awt.event.KeyEvent.*
26+
import java.io.File
27+
import java.time.Duration.ofMinutes
28+
import kotlin.io.path.createTempDirectory
29+
30+
@ExtendWith(RemoteRobotExtension::class)
31+
class MarkDirectoryAsMagentoRootTest {
32+
private lateinit var tempProjectDir: File
33+
34+
init {
35+
StepsLogger.init()
36+
}
37+
38+
@BeforeEach
39+
fun setup() {
40+
// Create a temporary directory
41+
val sourceDir = File("testData/project/magento2")
42+
tempProjectDir = createTempDirectory("intellij-test-project").toFile()
43+
44+
// Copy the test data to the temporary directory
45+
sourceDir.copyRecursively(
46+
target = tempProjectDir,
47+
overwrite = true
48+
)
49+
}
50+
51+
52+
@BeforeEach
53+
fun waitForIde(remoteRobot: RemoteRobot) {
54+
waitForIgnoringError(ofMinutes(3)) { remoteRobot.callJs("true") }
55+
}
56+
57+
@AfterEach
58+
fun closeProject(remoteRobot: RemoteRobot) = with(remoteRobot) {
59+
CommonSteps(remoteRobot).closeProject()
60+
}
61+
62+
@Test
63+
@Video
64+
fun testMarkDirectoryAsMagentoRoot(remoteRobot: RemoteRobot) = with(remoteRobot) {
65+
66+
welcomeFrame {
67+
createNewProjectFromExistingFilesLink.click()
68+
dialog("Open File or Project") {
69+
// Set the path for the copied test data
70+
val comboBox = find<ContainerFixture>(byXpath("//div[@class='BorderlessTextField']"))
71+
comboBox.click() // Focus on the comboBox
72+
comboBox.keyboard {
73+
hotKey(VK_CONTROL, VK_A) // Select all text
74+
key(VK_DELETE) // Delete selected text
75+
enterText(tempProjectDir.path)
76+
}
77+
78+
button("OK").click()
79+
trustProjectLink.click()
80+
}
81+
}
82+
idea {
83+
step("Enable Magento Integration") {
84+
waitFor(ofMinutes(1)) { isDumbMode().not() }
85+
enableSupportLink.click(java.awt.Point(1, 1))
86+
waitFor(ofMinutes(1)) { isDumbMode().not() }
87+
88+
with(projectViewTree) {
89+
if (hasText("vendor").not()) {
90+
findText(projectName).doubleClick()
91+
waitFor { hasText("src") }
92+
}
93+
findText("vendor").doubleClick()
94+
findText("module-catalog").doubleClick()
95+
findText("Block").doubleClick()
96+
findText("Navigation.php").doubleClick()
97+
}
98+
99+
createAPluginWithoutMagentoRootInVendor(this@idea, remoteRobot)
100+
101+
with(projectViewTree) {
102+
//add magento code to project
103+
findText("magento").click(MouseButton.RIGHT_BUTTON)
104+
contextMenu("Mark Directory as").click()
105+
contextMenuItem("Sources Root").click()
106+
107+
findText("module-catalog").click(MouseButton.RIGHT_BUTTON)
108+
contextMenu("Mark Directory as").click()
109+
contextMenuItem("Mark Directory As Magento Code Root").click()
110+
}
111+
112+
with(textEditor()) {
113+
step("Create a new Plugin with marking as code root") {
114+
Thread.sleep(1_000)
115+
editor.findText("someMethod").click(MouseButton.RIGHT_BUTTON)
116+
contextMenuItem("Create a new Plugin").click()
117+
118+
createAPluginDialog {
119+
step("Ensure target module includes 'Magento_Catalog'") {
120+
pluginName.click()
121+
pluginName.keyboard {
122+
enterText("test_plugin")
123+
}
124+
className.click()
125+
className.keyboard {
126+
enterText("TestPlugin")
127+
}
128+
129+
targetModule.click()
130+
targetModule.keyboard {
131+
hotKey(VK_CONTROL, VK_A) // Select all text
132+
key(VK_DELETE) // Delete selected text
133+
enterText("Magento_Catalog")
134+
button("OK").click()
135+
}
136+
}
137+
}
138+
}
139+
}
140+
141+
with(projectViewTree) {
142+
findText("Plugin").doubleClick()
143+
findText("TestPlugin.php").doubleClick()
144+
}
145+
146+
with(textEditor()) {
147+
step("Check created files") {
148+
editor.findText("beforeSomeMethod")
149+
}
150+
}
151+
152+
with(projectViewTree) {
153+
findText("module-catalog").click(MouseButton.RIGHT_BUTTON)
154+
contextMenu("Mark Directory as").click()
155+
contextMenuItem("Unmark Directory As Magento Code Root").click()
156+
findText("Navigation.php").doubleClick()
157+
}
158+
159+
createAPluginWithoutMagentoRootInVendor(this@idea, remoteRobot)
160+
}
161+
}
162+
}
163+
164+
private fun createAPluginWithoutMagentoRootInVendor(
165+
ideaFrame: IdeaFrame,
166+
remoteRobot1: RemoteRobot
167+
) {
168+
with(ideaFrame.textEditor()) {
169+
step("Create a new Plugin without marking as code root") {
170+
Thread.sleep(1_000)
171+
editor.findText("someMethod").click(MouseButton.RIGHT_BUTTON)
172+
remoteRobot1.contextMenuItem("Create a new Plugin").click()
173+
174+
remoteRobot1.createAPluginDialog {
175+
step("Ensure target module does not include 'Magento_Catalog'") {
176+
pluginName.click()
177+
pluginName.keyboard {
178+
enterText("test_plugin")
179+
}
180+
className.click()
181+
className.keyboard {
182+
enterText("TestPlugin")
183+
}
184+
185+
targetModule.click()
186+
targetModule.keyboard {
187+
hotKey(VK_CONTROL, VK_A) // Select all text
188+
key(VK_DELETE) // Delete selected text
189+
enterText("Magento_Catalog")
190+
button("OK").click()
191+
192+
errorDialog {
193+
button("OK").click()
194+
}
195+
196+
button("Cancel").click()
197+
}
198+
}
199+
}
200+
}
201+
}
202+
}
203+
}

0 commit comments

Comments
 (0)