selenium ide 模拟原始代码转换

在试用selenium-ide 插件录制页面时,我们可以得到这样的界面。

image.png

上图的例子就是执行百度,搜索 nihao

可以发现生成的命令还是比较通俗易懂的。

那么我们如何获取到当前的脚本的的原始代码呢。

经过研究调试,发现可以通过_state.project.toJS() 的形式获取到。

例如在这个项目当中,我获取到的数据就是这样

image.png

在这里可以看到每个命令里面的细节,当然这个我也不是很关注。

下面我先尝试将这数据转换成py的可执行代码试试。

通过前一章节讲到的内容

我们可以在exportCodeToFile 函数中找到转换的方式。直接调用即可。

export async function exportCodeToFile(
  selectedLanguages,
  { test, suite },
  { enableOriginTracing, beforeEachOptions, enableDescriptionAsComment }
) {
  const project = UiState.project.toJS()
  const { url, tests } = project
  for (const language of selectedLanguages) {
    let emittedCode
    let options = {
      url,
      tests,
      project,
      enableOriginTracing,
      beforeEachOptions: {
        browserName: userAgent.browserName,
        ...beforeEachOptions,
      },
      enableDescriptionAsComment,
    }
    options.test = test ? test : undefined
    options.suite = suite
      ? projectProcessor.normalizeTestsInSuite({ suite, tests })
      : undefined
    if (vendorLanguages.hasOwnProperty(language)) {
      const result = await PluginManager.emitMessage({
        action: 'export',
        entity: 'vendor',
        language,
        options,
      })
      emittedCode = result[0].response
    } else if (test) {
      emittedCode = await exporter.emit.test(language, options)

下面我们新建一个简单的项目进行测试

var project = `{"id":"f82b2216-7207-4952-8339-019abfebfde3","version":"2.0","name":"test","url":"https://baidu.com","tests":[{"id":"706b803d-b284-4a34-8102-7975b67306eb","name":"baidu","commands":[{"id":"a95c059d-6185-4d0e-9088-19f1a9b24dcd","comment":"","command":"open","target":"https://www.baidu.com/","targets":[],"value":""},{"id":"c2afbb00-c6f2-4a3d-af92-61f975eb383e","comment":"","command":"setWindowSize","target":"1050x567","targets":[],"value":""},{"id":"286f42e7-da80-444c-a308-7c5eaaab0eba","comment":"","command":"click","target":"id=kw","targets":[["id=kw","id"],["name=wd","name"],["css=#kw","css:finder"],["xpath=//input[@id='kw']","xpath:attributes"],["xpath=//span[@id='s_kw_wrap']/input","xpath:idRelative"],["xpath=//input","xpath:position"]],"value":""},{"id":"e3e75ce9-1220-4fb6-98cc-61cc806dbfc8","comment":"","command":"type","target":"id=kw","targets":[["id=kw","id"],["name=wd","name"],["css=#kw","css:finder"],["xpath=//input[@id='kw']","xpath:attributes"],["xpath=//span[@id='s_kw_wrap']/input","xpath:idRelative"],["xpath=//input","xpath:position"]],"value":"nihao"},{"id":"42be1ed9-d4c3-4696-b242-131bbc5e3741","comment":"","command":"click","target":"id=su","targets":[["id=su","id"],["css=#su","css:finder"],["xpath=//input[@id='su']","xpath:attributes"],["xpath=//span[@id='s_btn_wr']/input","xpath:idRelative"],["xpath=//span[2]/input","xpath:position"]],"value":""},{"id":"d9e54ccb-b849-4eba-8ebc-9f45768f758e","comment":"","command":"close","target":"","targets":[],"value":""}]}],"suites":[{"id":"656f702c-9973-4ec2-a3c8-def3ba081212","name":"Default Suite","persistSession":false,"parallel":false,"timeout":300,"tests":[]}],"urls":["https://element.eleme.io/"],"plugins":[]}`
project = JSON.parse(project)
const { url, tests } = project
for (const language of selectedLanguages) {
  let emittedCode
  let options = {
    url,
    tests,
    project,
    enableOriginTracing, // 是否导入注释
    beforeEachOptions: {
      browserName: userAgent.browserName, // 浏览器名称
      ...beforeEachOptions,
    },
    enableDescriptionAsComment, // 使用描述作为注释
  }
  options.test = test ? test : undefined
  options.suite = suite
    ? projectProcessor.normalizeTestsInSuite({ suite, tests })
    : undefined
  if (vendorLanguages.hasOwnProperty(language)) {
    const result = await PluginManager.emitMessage({
      action: 'export',
      entity: 'vendor',
      language,
      options,
    })
    emittedCode = result[0].response
  } else if (test) {
    emittedCode = await exporter.emit.test(language, options)

可以看到代码里面还有一些我们当前没有获取到的数据options.test以及 options.suite

这里我也简单看了下源码,可以在导出时通过 _modalState.exportPayload 来获取到内容

比如在当前代码片段这里的内容为


image.png

因此我们可以断定,正常导出代码逻辑时,这里的逻辑判断将会走test的分支来运行

通过前一节的内容也可以指定,上面一段转换PluginManager.emitMessage 是没必要的
因此精简下我们的代码逻辑,给能确定后的代码块赋值

// project  原始数据太长就不贴了
project = JSON.parse(project)
const { url, tests } = project
let emittedCode
let options = {
  url,
  tests,
  project,
  enableOriginTracing: true, // 是否导入注释
  beforeEachOptions: {
    browserName: userAgent.browserName, // 浏览器名称
    ...beforeEachOptions,
  },
  enableDescriptionAsComment:true, // 使用描述作为注释
}
options.test = test ? test : undefined
options.suite = undefined

emittedCode = await exporter.emit.test(language, options)

好了,现在仅仅缺少 userAgent.browserNamebeforeEachOptions 当中的数据了

从源码可得知,引用自@seleniumhq/side-utils

import { userAgent, project as projectProcessor } from '@seleniumhq/side-utils'
image.png

这里就可以很清晰的看到,获取方式其实就是通过window.navigator.userAgent 来判断当前浏览器环境。

并且browserName 也可以清楚的看到是在Chrome当中Firefox 二选一

现在还剩下最后一个beforeEachOptions 通过它使用解构赋值的方式,我们知道它一定是object

这里的传递比较复杂, 加上我对react了解不是特别深入。因此切换下查找方案。
通过在测试代码中可以找到它是个配置项,并且通常只用于配置selenium-grid 的地址
因此很明显我们可以忽略它。

image.png

好了,现在我们的代码是这样

import exporter from '@seleniumhq/code-export'

project = JSON.parse(project)
const { url, tests } = project
let emittedCode
let options = {
  url,
  tests,
  project,
  enableOriginTracing: true, // 是否导入注释
  beforeEachOptions: {
    browserName: 'Chrome', // 浏览器名称
  },
  enableDescriptionAsComment:true, // 使用描述作为注释
}
options.test = test ? test : undefined
options.suite = undefined

emittedCode = await exporter.emit.test(language, options)
console.log(emittedCode)

因为我是用node环境调试,所以代码引入需要做一些转换。
await 也需要使用异步方案来包含。

const exporter = require('@seleniumhq/code-export').default;

(async ()=>{
  project = JSON.parse(project)
  const { url, tests } = project
  let emittedCode
  let options = {
    url,
    tests,
    project,
    enableOriginTracing: true, // 是否导入注释
    beforeEachOptions: {
      browserName: 'Chrome', // 浏览器名称
    },
    enableDescriptionAsComment:true, // 使用描述作为注释
  }
  options.test = tests[0]
  emittedCode = await exporter.emit.test('python-pytest', options)
})()

现在万事俱备,之差转换代码了
让我们运行一下

image.png

ok,可以看到我们成功完成了代码转换。

下一篇讲下,转换时注意事项,以及原始字符串的拼接。

你可能感兴趣的:(selenium ide 模拟原始代码转换)