From b6db9917e348a7d46e4b2cbaeb3db47bc090b2ec Mon Sep 17 00:00:00 2001 From: Anton Tarasov Date: Thu, 21 Jan 2021 17:12:55 +0300 Subject: [PATCH] IDEA-259096 JCEF: window.cefQuery_XXXXXX_XX is not a function for query created after the browser is shown GitOrigin-RevId: 2768a97de972b76e92511e08b54bfcc469b2c090 --- .../src/com/intellij/ui/jcef/JBCefClient.java | 12 +- .../com/intellij/ui/jcef/IDEA232594Test.java | 6 +- .../com/intellij/ui/jcef/IDEA246306Test.java | 8 +- .../com/intellij/ui/jcef/IDEA259472Test.java | 4 +- .../ui/jcef/JBCefJSQueryPoolSizeKeyTest.java | 39 +++++ .../ui/jcef/JBCefJSQueryPoolSizePropTest.java | 87 +++++++++++ .../intellij/ui/jcef/JBCefJSQueryTest.java | 138 ------------------ .../intellij/ui/jcef/JBCefLoadHtmlTest.java | 4 +- .../com/intellij/ui/jcef/JBCefTestHelper.java | 11 +- 9 files changed, 155 insertions(+), 154 deletions(-) create mode 100644 platform/platform-tests/testSrc/com/intellij/ui/jcef/JBCefJSQueryPoolSizeKeyTest.java create mode 100644 platform/platform-tests/testSrc/com/intellij/ui/jcef/JBCefJSQueryPoolSizePropTest.java delete mode 100644 platform/platform-tests/testSrc/com/intellij/ui/jcef/JBCefJSQueryTest.java diff --git a/platform/platform-api/src/com/intellij/ui/jcef/JBCefClient.java b/platform/platform-api/src/com/intellij/ui/jcef/JBCefClient.java index 8d108422f4f3..c83a1ce1228c 100644 --- a/platform/platform-api/src/com/intellij/ui/jcef/JBCefClient.java +++ b/platform/platform-api/src/com/intellij/ui/jcef/JBCefClient.java @@ -81,11 +81,21 @@ public final class JBCefClient implements JBCefDisposable { myCefClient = client; Disposer.register(JBCefApp.getInstance().getDisposable(), this); + Runnable createPool = () -> { + if (myJSQueryPool != null) { + LOG.warn("JSQueryPool has already been created, this request will be ignored"); + return; + } + myJSQueryPool = JSQueryPool.create(this); + }; addPropertyChangeListener(JBCEFCLIENT_JSQUERY_POOL_SIZE_PROP, evt -> { if (evt.getNewValue() != null) { - myJSQueryPool = JSQueryPool.create(this); + createPool.run(); } }); + if (JS_QUERY_SLOT_POOL_DEF_SIZE > 0) { + createPool.run(); + } } @NotNull diff --git a/platform/platform-tests/testSrc/com/intellij/ui/jcef/IDEA232594Test.java b/platform/platform-tests/testSrc/com/intellij/ui/jcef/IDEA232594Test.java index ffae2ed83e88..fb7ad6508204 100644 --- a/platform/platform-tests/testSrc/com/intellij/ui/jcef/IDEA232594Test.java +++ b/platform/platform-tests/testSrc/com/intellij/ui/jcef/IDEA232594Test.java @@ -12,7 +12,7 @@ import javax.swing.*; import java.awt.*; import java.util.concurrent.atomic.AtomicInteger; -import static com.intellij.ui.jcef.JBCefTestHelper.loadAndWait; +import static com.intellij.ui.jcef.JBCefTestHelper.invokeAndWaitForLoad; /** * Tests https://youtrack.jetbrains.com/issue/IDEA-232594 @@ -49,7 +49,7 @@ public class IDEA232594Test { return null; }); - loadAndWait(browser, () -> SwingUtilities.invokeLater(() -> { + invokeAndWaitForLoad(browser, () -> SwingUtilities.invokeLater(() -> { JFrame frame = new JFrame(JBCefLoadHtmlTest.class.getName()); frame.setSize(640, 480); frame.setLocationRelativeTo(null); @@ -57,7 +57,7 @@ public class IDEA232594Test { frame.setVisible(true); })); - loadAndWait(browser, () -> SwingUtilities.invokeLater(() -> { + invokeAndWaitForLoad(browser, () -> SwingUtilities.invokeLater(() -> { browser.getCefBrowser().executeJavaScript(jsQuery.inject("'hello'"), "about:blank", 0); })); diff --git a/platform/platform-tests/testSrc/com/intellij/ui/jcef/IDEA246306Test.java b/platform/platform-tests/testSrc/com/intellij/ui/jcef/IDEA246306Test.java index 403c48e340e2..bede1e4ba7fb 100644 --- a/platform/platform-tests/testSrc/com/intellij/ui/jcef/IDEA246306Test.java +++ b/platform/platform-tests/testSrc/com/intellij/ui/jcef/IDEA246306Test.java @@ -4,7 +4,6 @@ package com.intellij.ui.jcef; import com.intellij.testFramework.ApplicationRule; import com.intellij.ui.scale.TestScaleHelper; import org.junit.After; -import org.junit.Before; import org.junit.ClassRule; import org.junit.Test; @@ -12,7 +11,8 @@ import javax.swing.*; import java.awt.*; import java.util.concurrent.CountDownLatch; -import static com.intellij.ui.jcef.JBCefTestHelper.loadAndWait; +import static com.intellij.ui.jcef.JBCefTestHelper.invokeAndWaitForLatch; +import static com.intellij.ui.jcef.JBCefTestHelper.invokeAndWaitForLoad; /** * Tests https://youtrack.jetbrains.com/issue/IDEA-246306 @@ -58,7 +58,7 @@ public class IDEA246306Test { return null; }); - loadAndWait(this, () -> SwingUtilities.invokeLater(() -> { + invokeAndWaitForLoad(this, () -> SwingUtilities.invokeLater(() -> { JFrame frame = new JFrame(JBCefLoadHtmlTest.class.getName()); frame.setSize(640, 480); frame.setLocationRelativeTo(null); @@ -66,7 +66,7 @@ public class IDEA246306Test { frame.setVisible(true); })); - loadAndWait(latch, () -> SwingUtilities.invokeLater(() -> { + invokeAndWaitForLatch(latch, () -> SwingUtilities.invokeLater(() -> { getCefBrowser().executeJavaScript(myQuery.inject("'" + this + "'"), getCefBrowser().getURL(), 0); })); } diff --git a/platform/platform-tests/testSrc/com/intellij/ui/jcef/IDEA259472Test.java b/platform/platform-tests/testSrc/com/intellij/ui/jcef/IDEA259472Test.java index 93362c1b513e..531b1bf634e8 100644 --- a/platform/platform-tests/testSrc/com/intellij/ui/jcef/IDEA259472Test.java +++ b/platform/platform-tests/testSrc/com/intellij/ui/jcef/IDEA259472Test.java @@ -16,8 +16,8 @@ import org.junit.Test; import javax.swing.*; import java.util.concurrent.CountDownLatch; -import static com.intellij.ui.jcef.JBCefTestHelper.loadAndWait; import static com.intellij.ui.jcef.JBCefTestHelper.await; +import static com.intellij.ui.jcef.JBCefTestHelper.invokeAndWaitForLoad; /** * Tests https://youtrack.jetbrains.com/issue/IDEA-259472 @@ -79,7 +79,7 @@ public class IDEA259472Test { } }, jbCefBrowser.getCefBrowser()); - loadAndWait(jbCefBrowser, () -> { + invokeAndWaitForLoad(jbCefBrowser, () -> { JFrame frame = new JFrame(JBCefLoadHtmlTest.class.getName()); frame.setSize(640, 480); frame.setLocationRelativeTo(null); diff --git a/platform/platform-tests/testSrc/com/intellij/ui/jcef/JBCefJSQueryPoolSizeKeyTest.java b/platform/platform-tests/testSrc/com/intellij/ui/jcef/JBCefJSQueryPoolSizeKeyTest.java new file mode 100644 index 000000000000..13be4df896f0 --- /dev/null +++ b/platform/platform-tests/testSrc/com/intellij/ui/jcef/JBCefJSQueryPoolSizeKeyTest.java @@ -0,0 +1,39 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.ui.jcef; + +import com.intellij.testFramework.ApplicationRule; +import com.intellij.ui.scale.TestScaleHelper; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; + +/** + * Tests "ide.browser.jcef.jsQueryPoolSize" reg key. + * + * @author tav + */ +public class JBCefJSQueryPoolSizeKeyTest { + static { + TestScaleHelper.setSystemProperty("java.awt.headless", "false"); + } + + @ClassRule public static final ApplicationRule appRule = new ApplicationRule(); + + @Before + public void before() { + TestScaleHelper.setSystemProperty("ide.browser.jcef.jsQueryPoolSize", "1"); + } + + @After + public void after() { + TestScaleHelper.restoreProperties(); + } + + @Test + public void test1() { + TestScaleHelper.assumeStandalone(); + + JBCefJSQueryPoolSizePropTest.test(b -> null); + } +} diff --git a/platform/platform-tests/testSrc/com/intellij/ui/jcef/JBCefJSQueryPoolSizePropTest.java b/platform/platform-tests/testSrc/com/intellij/ui/jcef/JBCefJSQueryPoolSizePropTest.java new file mode 100644 index 000000000000..06681836384b --- /dev/null +++ b/platform/platform-tests/testSrc/com/intellij/ui/jcef/JBCefJSQueryPoolSizePropTest.java @@ -0,0 +1,87 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.ui.jcef; + +import com.intellij.testFramework.ApplicationRule; +import com.intellij.ui.scale.TestScaleHelper; +import org.jetbrains.annotations.NotNull; +import org.junit.ClassRule; +import org.junit.Test; + +import javax.swing.*; +import java.awt.*; +import java.util.concurrent.CountDownLatch; +import java.util.function.Function; + +import static com.intellij.ui.jcef.JBCefTestHelper.invokeAndWaitForLatch; +import static com.intellij.ui.jcef.JBCefTestHelper.invokeAndWaitForLoad; + +/** + * Tests {@link JBCefClient#JBCEFCLIENT_JSQUERY_POOL_SIZE_PROP}. + * + * @author tav + */ +public class JBCefJSQueryPoolSizePropTest { + static { + TestScaleHelper.setSystemProperty("java.awt.headless", "false"); + } + + @ClassRule public static final ApplicationRule appRule = new ApplicationRule(); + + @Test + public void test1() { + TestScaleHelper.assumeStandalone(); + + test(client -> { + client.setProperty(JBCefClient.JBCEFCLIENT_JSQUERY_POOL_SIZE_PROP, 1); + return null; + }); + } + + @Test + public void test2() { + TestScaleHelper.assumeStandalone(); + + JBCefJSQueryPoolSizePropTest.test(client -> { + client.setProperty(JBCefClient.JBCEFCLIENT_JSQUERY_POOL_SIZE_PROP, Integer.MAX_VALUE); // stress test + return null; + }); + } + + public static void test(@NotNull Function setProperty) { + CountDownLatch latchBefore = new CountDownLatch(1); + CountDownLatch latchAfter = new CountDownLatch(1); + + JBCefBrowser browser = new JBCefBrowser("chrome:version"); + setProperty.apply(browser.getJBCefClient()); + + JBCefJSQuery jsQuery_before = JBCefJSQuery.create(browser); + jsQuery_before.addHandler(result -> { + System.out.println("JBCefJSQuery [before] result: " + result); + latchBefore.countDown(); + return null; + }); + + invokeAndWaitForLoad(browser, () -> { + JFrame frame = new JFrame(JBCefLoadHtmlTest.class.getName()); + frame.setSize(640, 480); + frame.setLocationRelativeTo(null); + frame.add(browser.getComponent(), BorderLayout.CENTER); + frame.setVisible(true); + }); + + JBCefJSQuery jsQuery_after = JBCefJSQuery.create((JBCefBrowserBase)browser); + jsQuery_after.addHandler(result -> { + System.out.println("JBCefJSQuery [after] result: " + result); + latchAfter.countDown(); + return null; + }); + + invokeAndWaitForLatch(latchBefore, () -> { + browser.getCefBrowser().executeJavaScript(jsQuery_before.inject("'query_before'"), "about:blank", 0); + }); + + invokeAndWaitForLatch(latchAfter, () -> { + browser.getCefBrowser().executeJavaScript(jsQuery_after.inject("'query_after'"), "about:blank", 0); + }); + } +} diff --git a/platform/platform-tests/testSrc/com/intellij/ui/jcef/JBCefJSQueryTest.java b/platform/platform-tests/testSrc/com/intellij/ui/jcef/JBCefJSQueryTest.java deleted file mode 100644 index bbc1df2f47a3..000000000000 --- a/platform/platform-tests/testSrc/com/intellij/ui/jcef/JBCefJSQueryTest.java +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package com.intellij.ui.jcef; - -import com.intellij.testFramework.ApplicationRule; -import com.intellij.ui.scale.TestScaleHelper; -import junit.framework.TestCase; -import org.cef.browser.CefBrowser; -import org.cef.browser.CefFrame; -import org.cef.handler.CefLoadHandler; -import org.cef.network.CefRequest; -import org.jetbrains.annotations.NotNull; -import org.junit.After; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; - -import javax.swing.*; -import java.awt.*; -import java.util.concurrent.CountDownLatch; -import java.util.function.Function; - -import static com.intellij.ui.jcef.JBCefTestHelper.await; - -/** - * Tests {@link JBCefClient#JBCEFCLIENT_JSQUERY_POOL_SIZE_PROP} and "ide.browser.jcef.jsQueryPoolSize" (used for testing purposes). - * - * @author tav - */ -public class JBCefJSQueryTest { - static { - TestScaleHelper.setSystemProperty("java.awt.headless", "false"); - } - - @ClassRule public static final ApplicationRule appRule = new ApplicationRule(); - - static final CountDownLatch LATCH_JS_BEFORE = new CountDownLatch(1); - static final CountDownLatch LATCH_JS_AFTER = new CountDownLatch(1); - static final CountDownLatch LATCH_LOAD = new CountDownLatch(1); - - @Before - public void before() { - TestScaleHelper.setSystemProperty("ide.browser.jcef.jsQueryPoolSize", "0"); - } - - @After - public void after() { - TestScaleHelper.restoreProperties(); - } - - @Test - public void test1() { - TestScaleHelper.assumeStandalone(); - - test(client -> { - client.setProperty(JBCefClient.JBCEFCLIENT_JSQUERY_POOL_SIZE_PROP, 1); - return null; - }); - } - - @Test - public void test2() { - TestScaleHelper.assumeStandalone(); - - System.setProperty("ide.browser.jcef.jsQueryPoolSize", "1"); - test(b -> null); - } - - @Test - public void test3() { - TestScaleHelper.assumeStandalone(); - - test(client -> { - client.setProperty(JBCefClient.JBCEFCLIENT_JSQUERY_POOL_SIZE_PROP, Integer.MAX_VALUE); // stress test - return null; - }); - } - - public void test(@NotNull Function setProperty) { - JBCefBrowser browser = new JBCefBrowser("chrome:version"); - setProperty.apply(browser.getJBCefClient()); - - browser.getJBCefClient().addLoadHandler(new CefLoadHandler() { - @Override - public void onLoadingStateChange(CefBrowser browser, boolean isLoading, boolean canGoBack, boolean canGoForward) { - System.out.println("JBCefLoadHtmlTest.onLoadingStateChange"); - } - @Override - public void onLoadStart(CefBrowser browser, CefFrame frame, CefRequest.TransitionType transitionType) { - System.out.println("JBCefLoadHtmlTest.onLoadStart"); - } - @Override - public void onLoadEnd(CefBrowser browser, CefFrame frame, int httpStatusCode) { - System.out.println("JBCefLoadHtmlTest.onLoadEnd"); - LATCH_LOAD.countDown(); - } - @Override - public void onLoadError(CefBrowser browser, CefFrame frame, ErrorCode errorCode, String errorText, String failedUrl) { - System.out.println("JBCefLoadHtmlTest.onLoadError"); - } - }, browser.getCefBrowser()); - - JBCefJSQuery jsQuery_before = JBCefJSQuery.create(browser); - jsQuery_before.addHandler(result -> { - System.out.println("JBCefJSQuery [before] result: " + result); - LATCH_JS_BEFORE.countDown(); - return null; - }); - - SwingUtilities.invokeLater(() -> { - JFrame frame = new JFrame(JBCefLoadHtmlTest.class.getName()); - frame.setSize(640, 480); - frame.setLocationRelativeTo(null); - frame.add(browser.getComponent(), BorderLayout.CENTER); - frame.setVisible(true); - }); - - TestCase.assertTrue(await(LATCH_LOAD)); - - JBCefJSQuery jsQuery_after = JBCefJSQuery.create(browser); - jsQuery_after.addHandler(result -> { - System.out.println("JBCefJSQuery [after] result: " + result); - LATCH_JS_AFTER.countDown(); - return null; - }); - - SwingUtilities.invokeLater(() -> { - browser.getCefBrowser().executeJavaScript(jsQuery_before.inject("'query_before'"), "about:blank", 0); - }); - - TestCase.assertTrue(await(LATCH_JS_BEFORE)); - - SwingUtilities.invokeLater(() -> { - browser.getCefBrowser().executeJavaScript(jsQuery_after.inject("'query_after'"), "about:blank", 0); - }); - - TestCase.assertTrue(await(LATCH_JS_AFTER)); - } -} diff --git a/platform/platform-tests/testSrc/com/intellij/ui/jcef/JBCefLoadHtmlTest.java b/platform/platform-tests/testSrc/com/intellij/ui/jcef/JBCefLoadHtmlTest.java index 2f7388c8dcf4..e9eae698c54b 100644 --- a/platform/platform-tests/testSrc/com/intellij/ui/jcef/JBCefLoadHtmlTest.java +++ b/platform/platform-tests/testSrc/com/intellij/ui/jcef/JBCefLoadHtmlTest.java @@ -22,6 +22,8 @@ import java.io.FileWriter; import java.io.IOException; import java.util.concurrent.CountDownLatch; +import static com.intellij.ui.jcef.JBCefTestHelper.invokeAndWaitForLatch; + /** * Tests that {@link JBCefBrowser#loadHTML(String, String)} can load html that references JS via "file://" * and the JS is uploaded from disk and executed. @@ -90,7 +92,7 @@ public class JBCefLoadHtmlTest { writeJS(jsQuery.inject("'hello'")); - JBCefTestHelper.loadAndWait(LATCH, () -> { + invokeAndWaitForLatch(LATCH, () -> { JFrame frame = new JFrame(JBCefLoadHtmlTest.class.getName()); frame.setSize(640, 480); frame.setLocationRelativeTo(null); diff --git a/platform/platform-tests/testSrc/com/intellij/ui/jcef/JBCefTestHelper.java b/platform/platform-tests/testSrc/com/intellij/ui/jcef/JBCefTestHelper.java index 0aa49b483423..a16350859e73 100644 --- a/platform/platform-tests/testSrc/com/intellij/ui/jcef/JBCefTestHelper.java +++ b/platform/platform-tests/testSrc/com/intellij/ui/jcef/JBCefTestHelper.java @@ -1,6 +1,7 @@ // Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ui.jcef; +import com.intellij.util.ui.UIUtil; import junit.framework.TestCase; import org.cef.browser.CefBrowser; import org.cef.browser.CefFrame; @@ -11,7 +12,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; public class JBCefTestHelper { - public static void loadAndWait(@NotNull JBCefBrowser browser, @NotNull Runnable loadAction) { + public static void invokeAndWaitForLoad(@NotNull JBCefBrowser browser, @NotNull Runnable runnable) { CountDownLatch latch = new CountDownLatch(1); browser.getJBCefClient().addLoadHandler(new CefLoadHandlerAdapter() { @@ -23,18 +24,18 @@ public class JBCefTestHelper { } }, browser.getCefBrowser()); - loadAndWait(latch, loadAction); + invokeAndWaitForLatch(latch, runnable); } - public static void loadAndWait(@NotNull CountDownLatch latch, @NotNull Runnable loadAction) { - loadAction.run(); + public static void invokeAndWaitForLatch(@NotNull CountDownLatch latch, @NotNull Runnable runnable) { + UIUtil.invokeLaterIfNeeded(runnable); TestCase.assertTrue(await(latch)); } public static boolean await(@NotNull CountDownLatch latch) { try { - return latch.await(2000, TimeUnit.SECONDS); + return latch.await(5, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace();