如何在基于Chromium的功能测试中使用导航器媒体设备? TestCafe

如何解决如何在基于Chromium的功能测试中使用导航器媒体设备? TestCafe

TL; DR 如何运行将navigator.mediaDevices及其方法testcafe和Chromium一起使用的功能测试?

我正在尝试使用testcafe编写功能测试以测试一些WebRTC代码。我正在使用React。我有一个枚举设备的自定义钩子:

function useUpdateDeviceList() {
  const dispatch = usedispatch();

  useEffect(() => {
    async function updateDeviceList() {
      const { audioInputs,videoInputs } = await getInputDeviceInfos();

      dispatch(setAudioInputs(audioInputs));
      dispatch(setVideoInputs(videoInputs));
    }

    updateDeviceList();

    console.log('navigator',navigator);

    navigator.mediaDevices.ondevicechange = updateDeviceList;

    return () => {
      navigator.mediaDevices.ondevicechange = null;
    };
  },[dispatch]);
}

其中getInputDeviceInfosnavigator.mediaDevices.enumerateDevices

当我在浏览器中运行此代码时,它可以完美运行。当它在testcafe功能测试中运行时,它会抛出。

TypeError: Cannot set property 'ondevicechange' of undefined

全面的Google搜索仅给出了将标记--use-fake-ui-for-media-stream--use-fake-device-for-media-stream添加到开始命令的答案(前者避免了授予摄像头/麦克风许可的需要,而梯形图则提供了测试模式到getUserMedia(),而不是根据docs的实时摄像机输入),

"functional-tests:chrome-desktop":"testcafe 'chrome --use-fake-ui-for-media-stream --use-fake-device-for-media-stream' src/**/*.functional-test.js --app 'yarn dev' --app-init-delay 2000",

仍然发生相同的错误。上方挂钩中的console.log显示一个navigator对象,没有mediaDevices

Navigator {vendorSub: "",productSub: "20030107",vendor: "Google Inc.",maxTouchPoints: 0,sendbeacon: ƒ,…}
appCodeName: "Mozilla"
appName: "netscape"
appVersion: "5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/86.0.4240.111 Safari/537.36"
connection: networkinformation {onchange: null,effectiveType: "4g",rtt: 100,downlink: 1.55,saveData: false}
cookieEnabled: true
doNottrack: null
geolocation: Geolocation {}
hardwareConcurrency: 16
language: "en-GB"
languages: (3) ["en-GB","en-US","en"]
maxTouchPoints: 0
mediaCapabilities: MediaCapabilities {}
mediaSession: MediaSession {Metadata: null,playbackState: "none"}
mimeTypes: MimeTypeArray {0: MimeType,1: MimeType,application/x-nacl: MimeType,application/x-pnacl: MimeType,length: 2}
onLine: true
permissions: Permissions {}
platform: "MacIntel"
plugins: PluginArray {0: Plugin,Native Client: Plugin,length: 1}
product: "Gecko"
productSub: "20030107"
sendbeacon: ƒ ()
userActivation: UserActivation {hasBeenActive: false,isActive: false}
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/86.0.4240.111 Safari/537.36"
vendor: "Google Inc."
vendorSub: ""
webkitPersistentStorage: DeprecatedStorageQuota {}
webkitTemporaryStorage: DeprecatedStorageQuota {}
__proto__: Navigator

我要怎么做才能使这些测试通过?

PS::如果重要,这是应该通过的简单测试:

import { Selector } from 'testcafe';

const {
  FUNCTIONAL_TESTS_MEETINGS_APP_PROTOCOL: protocol = 'http',FUNCTIONAL_TESTS_MEETINGS_APP_HOST: host = 'localhost',FUNCTIONAL_TESTS_MEETINGS_APP_PORT: port = 3000,FUNCTIONAL_TESTS_MEETINGS_APP_MEETING_ID: meetingId = '327fa7b0-0605-4595-b066-819f201ce593',} = process.env;

fixture`Meetings page`.page(`${protocol}://${host}:${port}/${meetingId}`);

test.only('page should load and display the correct title',async t => {
  await t.debug();
  const actual = Selector('title').innerText;
  const expected = `Meetings - ${meetingId}`;

  await t.expect(actual).eql(expected);
});

解决方法

Chrome浏览器不允许从不安全的来源调用getUserMedia API。因此,您可以使用以下两种方式之一:

  1. 通过添加以下选项来指定“ localhost”作为主机名:--hostname
testcafe --hostname localhost ...
  1. 通过添加以下选项来使用SSL证书:--ssl
testcafe --ssl pfx=/path/to/cert.pfx ...

有关更多信息,请参见以下示例:Mock Camera/Microphone Access

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?