Browse Source

chore: refactor webContents module isCurrentlyAudible api spec (#14410)

Robo 6 years ago
parent
commit
8441d09a18

+ 5 - 0
atom/browser/api/atom_api_web_contents.cc

@@ -754,6 +754,11 @@ content::JavaScriptDialogManager* WebContents::GetJavaScriptDialogManager(
   return dialog_manager_.get();
 }
 
+void WebContents::OnAudioStateChanged(content::WebContents* web_contents,
+                                      bool audible) {
+  Emit("-audio-state-changed", audible);
+}
+
 void WebContents::BeforeUnloadFired(const base::TimeTicks& proceed_time) {
   // Do nothing, we override this method just to avoid compilation error since
   // there are two virtual functions named BeforeUnloadFired.

+ 2 - 0
atom/browser/api/atom_api_web_contents.h

@@ -345,6 +345,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
       const content::BluetoothChooser::EventHandler& handler) override;
   content::JavaScriptDialogManager* GetJavaScriptDialogManager(
       content::WebContents* source) override;
+  void OnAudioStateChanged(content::WebContents* web_contents,
+                           bool audible) override;
 
   // content::WebContentsObserver:
   void BeforeUnloadFired(const base::TimeTicks& proceed_time) override;

+ 18 - 12
spec/api-web-contents-spec.js

@@ -122,19 +122,25 @@ describe('webContents module', () => {
     })
   })
 
-  // Disabled because flaky. See #13969
-  xdescribe('isCurrentlyAudible() API', () => {
+  describe('isCurrentlyAudible() API', () => {
     it('returns whether audio is playing', async () => {
-      w.loadFile(path.join(fixtures, 'api', 'is-currently-audible.html'))
-      w.show()
-      await emittedOnce(w.webContents, 'did-finish-load')
-
-      expect(w.webContents.isCurrentlyAudible()).to.be.false()
-
-      w.webContents.send('play')
-      await emittedOnce(ipcMain, 'playing')
-
-      expect(w.webContents.isCurrentlyAudible()).to.be.true()
+      const webContents = remote.getCurrentWebContents()
+      const context = new window.AudioContext()
+      // Start in suspended state, because of the
+      // new web audio api policy.
+      context.suspend()
+      const oscillator = context.createOscillator()
+      oscillator.connect(context.destination)
+      oscillator.start()
+      await context.resume()
+      const [, audible] = await emittedOnce(webContents, '-audio-state-changed')
+      assert(webContents.isCurrentlyAudible() === audible)
+      expect(webContents.isCurrentlyAudible()).to.be.true()
+      oscillator.stop()
+      await emittedOnce(webContents, '-audio-state-changed')
+      expect(webContents.isCurrentlyAudible()).to.be.false()
+      oscillator.disconnect()
+      context.close()
     })
   })
 

+ 0 - 21
spec/fixtures/api/is-currently-audible.html

@@ -1,21 +0,0 @@
-<html>
-<body>
-<div id="video"></div>
-<script type="text/javascript" charset="utf-8">
-  const {ipcRenderer} = window.top != null ? window.top.require('electron') : require('electron')
-  ipcRenderer.on('play', (event) => {
-    const context = new window.AudioContext();
-    const oscillator = context.createOscillator();
-
-    // A beep
-    oscillator.type = 'sine';
-    oscillator.frequency.value = 440
-    oscillator.connect(context.destination)
-    oscillator.start()
-
-    // It'll take a few ms before the beep shows up
-    setTimeout(() => event.sender.send('playing'), 100)
-  })
-</script>
-</body>
-</html>