selenium-ide拥有代码转换功能,可以将录制的脚本转换为各个语言的selenium版本。
image.png
对应的界面实现在packages\selenium-ide\src\neo\components\Dialogs\Export\index.jsx
界面使用react编写,支持导出的脚本类型数组,是由browser.storage 并非写死的。
当选择完毕后会通过selectExportLanguage 设置当前选择的语言。
selectExportLanguage(language) {
this.selectedExportLanguage = language
storage.set({
selectedExportLanguage: language,
})
}
数据通过uiStorage进行共享,因此他可以设置之前选则的导出类型为默认类型。
选择完成后导出时会调用this.props.completeSelection方法传递数据。
image.png
然后根据调用位置,可以看到具体实现函数exportCodeToFile
其中可以看到函数实现是将字符串 写入 emittedCode中来实现导出文件
image.png
emittedCode 在这里有两种转换方式
image.png
首先看一下PluginManager的实现方式
其中核心逻辑为sendMessage
具体实现形式为
browser.runtime.sendMessage(id,JSON.parse(JSON.stringify(payload)))
第二个参数即为原始脚本。可以看到进行了json操作,说明它应该是按照Json Wire Protocol 进行的组装。
这里的id为插件的id。
最后我们记录发送人也就是这个插件id和插件返回来转换完成的代码。
可以看到插件注册逻辑
插件注册.png
可以简单的看到注册调用的方式为
image.png
根据找的的文档描述,我们可以得住调用注册的形式
image.png
这里不太方便查看。
接下来再看第二种方式exporter
import exporter from '@seleniumhq/code-export'
可以看到引用自code-export
下面是code-export的具体实现
code-export.png
在这里可以看到实际上导出成不同的语言依靠不同的插件来完成,这是很大的工作量。
因此后续的工作转移到具体的插件上,以python语言为例
python-pytest.png
项目整体目录结构是这样的。
Command.js : 对应基础命令解析,这里存储了大量的命令进行转换,例如assert,click,mouseDown等。
hook.js : 这里对应的则是一下hook事件,贯穿命令执行的生命周期。
index.js : 入口文件.这里核心逻辑下面再说。
location.js : 存储的是定位特征,比如根据那些定位元素之类的id,name,xpah 。
selection.js : 和上面类似,不过这里是存储css selector定位的。
核心内容都在index.js文件当中,如下图。
index.js.png
在这里还能看到两个比较熟悉的函数
export async function emitTest({})
export async function emitSuite({})
这就是我们上面看到的转换时调用的。
以 emitSuite 为例子 详细代码如下。
export async function emitSuite({
baseUrl,
suite,
tests,
project,
enableOriginTracing,
beforeEachOptions,
enableDescriptionAsComment,
}) {
global.baseUrl = baseUrl
const result = await exporter.emit.testsFromSuite(tests, suite, opts, {
enableOriginTracing,
enableDescriptionAsComment,
generateTestDeclaration,
project,
})
const suiteDeclaration = generateSuiteDeclaration(suite.name)
const _suite = await exporter.emit.suite(result, tests, {
...opts,
suiteDeclaration,
suite,
project,
beforeEachOptions,
})
return {
filename: generateFilename(suite.name),
body: exporter.emit.orderedSuite(_suite),
}
}
看到这里应该就是解析发送过来的json数据,返回的body内容则是对应转换完成的脚本。
转换的所有核心逻辑均是通过 exporter 来完成的
从之前的图片可以看到 这里的exporter 来自于 @seleniumhq/side-utils 这个项目
side-utils.png
通过这个简介可以看到,它是作为代码转换套件来使用的,所有selenium的脚本转换都由他来完成中间解释
到这里我们可以了解到。
如果需要让我们的自动化代码,提供多语言转换,我们可以选择直接使用import exporter from '@seleniumhq/code-export' 模块来同时翻译为多种语言脚本。
那么转换前的原始数据是什么样的?
怎么自动生成原生数据然后通过插件转换?
原始数据生成有哪些规则限制?
后续内容随缘更新~











网友评论