端到端测试哪家强?不容错过的Cypress

1. 目前E2E测试工具有哪些? 项目 Web Star puppeteer Chromium (~170Mb Mac, ~282Mb Linux, ~280Mb Win) 31906 nightmare Electron 15502 nightwatch WebDriver 8135 protractor selenium 7532 casperjs PhantomJS 7180 cypress Electron 5303 Zombie 不需要 4880 testcafe 不需要 4645 CodeceptJS webdriverio 1665 端到端测试一般都需要一个Web容器,来运行前端应用。例如Chromium, Electron, PhantomJS, WebDriver等等。 从体积角度考虑,这些Web容器体积一般都很大。 从速度的角度考虑:PhantomJS, WebDriver < Electon, Chromium。 而且每个工具的侧重点也不同,建议按照需要去选择。 2. 优秀的端到端测试工具应该有哪些特点? 安装简易:我希望它非常容易安装,最好可以一行命令就可以安装完毕 依赖较少:我只想做个E2E测试,不想安装jdk, python之类的东西 速度很快:运行测试用例的速度要快 报错详细:详细的报错 API完备:鼠标键盘操作接口,DOM查询接口等 Debug方便:出错了可以很方便的调试,而不是去猜 3. 为什么要用Cypress? Cypress基本上拥有了上面的特点之外,还有以下特点。 时光穿梭 测试运行时,Cypress会自动截图,你可以轻易的查看每个时间的截图 Debug友好 不需要再去猜测为什么测试有失败了,Cypress提供Chrome DevTools, 所以Debug是非常方便的。 实时刷新 Cypress检测测试用例改变后,会自动刷新 自动等待 不需要在使用wait类似的方法等待某个DOM出现,Cypress会自动帮你做这些 Spies, stubs, and clocks Verify and control the behavior of functions, server responses, or timers. The same functionality you love from unit testing is right at your fingertips. 网络流量控制 在不涉及服务器的情况下轻松控制,存根和测试边缘案例。无论你喜欢,你都可以存储网络流量。 一致的结果 我们的架构不使用Selenium或WebDriver。向快速,一致和可靠的无剥落测试问好。 截图和视频 查看失败时自动截取的截图,或无条件运行时整个测试套件的视频。 4. 安装cypress 4.1. 使用npm方法安装 注意这个方法需要下载压缩过Electron, 所以可能会花费几分钟时间,请耐心等待。 ...

2018-05-14 10:43:02 · 1 min · Eddie Wang

掌握谷歌搜索高级指令

1. 谷歌搜索指令 2. 基本命令 3. 关键词使用 4. 特殊工具 4.1. define 快速返回关键词定义 4.2. 计算器 4.3. 单位转换 4.4. 时区查询 4.5. 地区查询 4.6. 天气查询 5. 参考 1. 谷歌搜索指令 2. 基本命令 符号 简介 语法 注意点 示例 | 包含A且必须包含B | A +B | A和+之间有空格 | Maxwell +wills | 包含A且不包含B | A -B | A和+之间有空格 | Maxwell -Absolom " " | 完整匹配AB | “AB” | | “Thomas Jefferson” OR | 包含A或者B | A OR B 或者 A | B | | nodejs OR webpack +-“OR | 指令可以组合,完成更复杂的查询 | | | beach -sandy +albert +nathaniel ~ | 包含A, 并且包含B的近义词 | A ~B | | github ~js .. | 区间查询 AB之间 | A..B | | china 1888..2000 | 匹配任意字符 | | | node* java site: | 站内搜索 | A site:B | | | DLL site:webpack.js.org filetype: | 按照文件类型搜索 | A filetype:B | | csta filetype:pdf 3. 关键词使用 方法 说明 示例 列举关键词 列举所有和搜索相关的关键词,并且尽量把重要的关键词排在前面。不同的关键词顺序会导致不同的返回不同的结果 书法 毛笔 绘画 不要使用某些词 如代词介词语气词,如i, the, of, it, 我,吗 搜索引擎一般会直接忽略这些信息含量少的词 大小写不敏感 大写字符和小写字符在搜索引擎看没有区别,尽量使用小写的就可以 4. 特殊工具 4.1. define 快速返回关键词定义 ...

2018-04-26 16:56:01 · 1 min · Eddie Wang

金钱游戏 - 银行造钱的秘密

1. 角色划分 名称 角色 账户 A 银行家 0 B 建筑商 100万 C 商人 0 2. 建筑商向银行存储100万 名称 角色 账户 A 银行家 100万 现金 B 建筑商 100万 支票 C 商人 0 2. 商人向银行贷款100万 此时银行的账户存款已经是0了,但是B还在银行存了100万。那银行究竟是还有100万呢, 还是一毛都没有了呢。 此时建筑商如果要取现金,那么银行马上就要破产。 名称 角色 账户 A 银行家 100现金 B 建筑商 100万 支票 C 商人 100万 支票 3. 商人需要建筑商来建造房子 商人需要建筑商来建筑房子,费用是100万,付给建筑商,建筑商又把100支票存到银行 名称 角色 账户 A 银行家 100万现金 B 建筑商 200万 支票 C 商人 0 商人又从银行借钱100万,来付给建筑商建房子,建筑商把钱存到银行 名称 角色 账户 A 银行家 100万现金 B 建筑商 300万 支票 C 商人 0 只要这个循环还在继续,你会发现,建筑商的账面上的支票越来越多,但是银行始终都是100万现金存在那里,从来都没动过。 ...

2018-04-25 13:33:52 · 1 min · Eddie Wang

Express静态文件浏览器缓存设置与缓存清除

1. Express设置缓存 Express设置静态文件的方法很简单,一行代码搞定。app.use(express.static(path.join(__dirname, 'public'), {maxAge: MAX_AGE})), 注意MAX_AGE的单位是毫秒。这句代码的含义是让pulic目录下的所有文件都可以在浏览器中缓存,过期时长为MAX_AGE毫秒。 app.use(express.static(path.join(__dirname, 'public'), {maxAge: config.get('maxAge')})) 2. Express让浏览器清除缓存 缓存的好处是可以更快的访问服务,但是缓存也有坏处。例如设置缓存为10天,第二天的时候服务更新了。如果客户端不强制刷新页面的话,浏览器会一致使用更新前的静态文件,这样会导致一些BUG。你总当每次出问题时,客户打电话给你后,你让他强制刷新浏览器吧? 所以,最好在服务重启后,重新让浏览器获取最新的静态文件。 设置的方式是给每一个静态文件设置一个时间戳。 例如:vendor/loadjs/load.js?_=123898923423"></script> 2.1. Express 路由 // /routes/index.js router.get('/home', function (req, res, next) { res.render('home', {config: config, serverStartTimestamp: new Date().getTime()}) }) 2.2. 视图文件 // views/home.html <script src="vendor/loadjs/load.js?_=<%= serverStartTimestamp %>"></script> 设置之后,每次服务更新或者重启,浏览器都会使用最新的时间戳serverStartTimestamp,去获取静态文件。 2.3. 动态加载JS文件 有时候js文件并不是直接在HTML中引入,可能是使用了一些js文件加载库,例如requirejs, LABjs等。这些情况下,可以在全局设置环境变量SERVER_START_TIMESTAMP,用来表示服务启动的时间戳,在获取js的时候,将该时间戳拼接在路径上。 注意:环境变量SERVER_START_TIMESTAMP,一定要在其他脚本使用前定义。 // views/home.html <script> var SERVER_START_TIMESTAMP = <%= serverStartTimestamp %> </script> // load.js 'vendor/contact-center/skill.js?_=' + SERVER_START_TIMESTAMP

2018-04-08 09:00:48 · 1 min · Eddie Wang

WebSocket断开原因分析

1. 把错误打印出来 WebSocket断开的原因有很多,最好在WebSocket断开时,将错误打印出来。 在线demo地址:https://wdd.js.org/websocket-demos/ ws.onerror = function (e) { console.log('WebSocket发生错误: ' + e.code) console.log(e) } 如果你想自己玩玩WebSocket, 但是你又不想自己部署一个WebSocket服务器,你可以使用ws = new WebSocket('wss://echo.websocket.org/'), 你向echo.websocket.org发送消息,它会回复你同样的消息。 2. 重要信息错误状态码 WebSocket断开时,会触发CloseEvent, CloseEvent会在连接关闭时发送给使用 WebSockets 的客户端. 它在 WebSocket 对象的 onclose 事件监听器中使用。CloseEvent的code字段表示了WebSocket断开的原因。可以从该字段中分析断开的原因。 3. 关闭状态码表 一般来说1006的错误码出现的情况比较常见,该错误码一般出现在断网时。 状态码 名称 描述 0–999 保留段, 未使用. 1000 CLOSE_NORMAL 正常关闭; 无论为何目的而创建, 该链接都已成功完成任务. 1001 CLOSE_GOING_AWAY 终端离开, 可能因为服务端错误, 也可能因为浏览器正从打开连接的页面跳转离开. 1002 CLOSE_PROTOCOL_ERROR 由于协议错误而中断连接. 1003 CLOSE_UNSUPPORTED 由于接收到不允许的数据类型而断开连接 (如仅接收文本数据的终端接收到了二进制数据). 1004 保留. 其意义可能会在未来定义. 1005 CLOSE_NO_STATUS 保留. 表示没有收到预期的状态码. 1006 CLOSE_ABNORMAL 保留. 用于期望收到状态码时连接非正常关闭 (也就是说, 没有发送关闭帧). 1007 Unsupported Data 由于收到了格式不符的数据而断开连接 (如文本消息中包含了非 UTF-8 数据). 1008 Policy Violation 由于收到不符合约定的数据而断开连接. 这是一个通用状态码, 用于不适合使用 1003 和 1009 状态码的场景. 1009 CLOSE_TOO_LARGE 由于收到过大的数据帧而断开连接. 1010 Missing Extension 客户端期望服务器商定一个或多个拓展, 但服务器没有处理, 因此客户端断开连接. 1011 Internal Error 客户端由于遇到没有预料的情况阻止其完成请求, 因此服务端断开连接. 1012 Service Restart 服务器由于重启而断开连接. 1013 Try Again Later 服务器由于临时原因断开连接, 如服务器过载因此断开一部分客户端连接. 1014 由 WebSocket标准保留以便未来使用. 1015 TLS Handshake 保留. 表示连接由于无法完成 TLS 握手而关闭 (例如无法验证服务器证书). 1016–1999 由 WebSocket标准保留以便未来使用. 2000–2999 由 WebSocket拓展保留使用. 3000–3999 可以由库或框架使用.? 不应由应用使用. 可以在 IANA 注册, 先到先得. 4000–4999 可以由应用使用. 4. 其他注意事项 如果你的服务所在的域是HTTPS的,那么使用的WebSocket协议也必须是wss, 而不能是ws ...

2018-03-29 20:35:38 · 1 min · Eddie Wang

js中的真值和假值

无论什么语言,都需要逻辑,而逻辑中,能否判断出真假,是最基本也是最重要技能之一。 JS中的假值有6个 false '' undefinded null 0, +0, -0 NaN 有点类似假值的真值有两个 {} [] 空对象和空数组,很多初学者都很用把这两个当做假值。但是实际上他们是真值,你只需要记住,除了null之外的所有对象类型的数据,都是真值。 typeof null // 'object' 据说:typeof null返回对象这是一个js语言中的bug。实际上typeof null应该返回null才比较准确,但是这个bug已经存来好久了。几乎所有的代码里都这样去判断。如果把typeof null给改成返回null, 那么这必定会导致JS世界末日。 我们承认JS并不完美,她有很多小缺点,但是这并不妨碍她吸引万千开发者拜倒在她的石榴裙下。 就像一首歌唱的:有些人说不清哪里好 但就是谁都替代不了

2018-03-27 14:31:01 · 1 min · Eddie Wang

在实践中我遇到stompjs, websocket和nginx的问题与总结

1. AWS EC2 不支持WebSocket 直达解决方案 英文版 简单说一下思路:WebSocket底层基于TCP协议的,如果你的服务器基于HTTP协议暴露80端口,那WebSocket肯定无法连接。你只要将HTTP协议修改成TCP协议就可以了。 然后是安全组的配置: 同样如果使用了NGINX作为反向代理,那么NGINX也需要做配置的。 // https://gist.githubusercontent.com/unshift/324be6a8dc9e880d4d670de0dc97a8ce/raw/29507ed6b3c9394ecd7842f9d3228827cffd1c58/elasticbeanstalk_websockets files: "/etc/nginx/conf.d/01_websockets.conf" : mode: "000644" owner: root group: root content : | upstream nodejs { server 127.0.0.1:8081; keepalive 256; } server { listen 8080; location / { proxy_pass http://nodejs; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } "/opt/elasticbeanstalk/hooks/appdeploy/enact/41_remove_eb_nginx_confg.sh": mode: "000755" owner: root group: root content : | mv /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf.old 2. NGINX做反向代理是需要注意的问题 如果排除所有问题后,那剩下的问题可以考虑出在反向代理上,一下有几点是可以考虑的。 ...

2018-03-20 22:09:34 · 1 min · Eddie Wang

状态码为200时 jQuery ajax报错

1. 问题现象 HTTP 状态码为 200 OK 时, jquery ajax报错 2. 问题原因 jquery ajax的dataType字段包含:json, 但是服务端返回的数据不是规范的json格式,导致jquery解析json字符串报错,最终导致ajax报错。 jQuery ajax 官方文档上说明: “json”: Evaluates the response as JSON and returns a JavaScript object. Cross-domain “json” requests are converted to “jsonp” unless the request includes jsonp: false in its request options. The JSON data is parsed in a strict manner; any malformed JSON is rejected and a parse error is thrown. As of jQuery 1.9, an empty response is also rejected; the server should return a response of null or {} instead. (See json.org for more information on proper JSON formatting.) ...

2018-03-15 14:17:59 · 1 min · Eddie Wang

前端剪贴板复制功能实现原理

1. 兼容情况 如果想浏览器支持粘贴功能,那么浏览器必须支持,document.execCommand(‘copy’)方法,也可以根据document.queryCommandEnabled(‘copy’),返回的true或者false判断浏览器是否支持copy命令。 从下表可以看出,主流的浏览器都支持execCommand命令 2. 复制的原理 查询元素 选中元素 执行复制命令 3. 代码展示 // html <input id="username" value="123456"> // 查询元素 var username = document.getElementById(‘username’) // 选中元素 username.select() // 执行复制 document.execCommand('copy') 注意: 以上代码只是简单示意,在实践过程中还有几个要判断的情况 首要要去检测浏览器execCommand能力检测 选取元素时,有可能选取元素为空,要考虑这种情况的处理 4. 第三方方案 clipboard.js是一个比较方便的剪贴板库,功能蛮多的。 <!-- Target --> <textarea id="bar">Mussum ipsum cacilds...</textarea> <!-- Trigger --> <button class="btn" data-clipboard-action="cut" data-clipboard-target="#bar"> Cut to clipboard </button> 官方给的代码里有上面的一个示例,如果你用了这个示例,但是不起作用,那你估计是没有初始化ClipboardJS示例的。 注意:下面的函数必须要主动调用,这样才能给响应的DOM元素注册事件。 ClipboardJS源代码压缩后大约有3kb,虽然很小了,但是如果你不需要它的这么多功能的话,其实你自己写几行代码就可以搞定复制功能。 new ClipboardJS('.btn');

2018-03-14 14:19:12 · 1 min · Eddie Wang

Chrome本地跨域origin-null-is-not-allowed问题分析与解决方案

1. 问题表现 以file:///xxx.html打开某个html文件,发送ajax请求时报错: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value 'null' that is not equal to the supplied origin. Origin 'null' is therefore not allowed access. 2. 问题原因 Origin null是本地文件系统,因此这表明您正在加载通过file:// URL进行加载调用的HTML页面(例如,只需在本地文件浏览器或类似文件中双击它)。不同的浏览器采用不同的方法将相同来源策略应用到本地文件。Chrome要求比较严格,不允许这种形势的跨域请求。而最好使用http:// 访问html. 3. 解决方案 以下给出三个解决方案,第一个最快,第三个作为彻底。 3.1. 方案1 给Chrome快捷方式中增加 –allow-file-access-from-files 打开Chrome快捷方式的属性中设置:右击Chrome浏览器快捷方式,选择“属性”,在“目标”中加"–allow-file-access-from-files",注意前面有个空格,重启Chrome浏览器便可。 3.2. 方案2 启动一个简单的静态文件服务器, 以http协议访问html 参见我的这篇文章: 一行命令搭建简易静态文件http服务器 3.3. 方案3 服务端响应修改Access-Control-Allow-Origin : * response.addHeader("Access-Control-Allow-Origin","*") 4. 参考文章 如何解决XMLHttpRequest cannot load file~~~~~~~Origin ’null’ is therefore not allowed access 让chrome支持本地Ajax请求,Ajax请求status cancel Origin null is not allowed by Access-Control-Allow-Origin Origin null is not allowed by Access-Control-Allow-Origin

2018-03-09 17:58:05 · 1 min · Eddie Wang