Best JavaScript code snippet using devicefarmer-stf
socket.io.js
Source:socket.io.js
1'use strict';2var http = require('http').Server;3var io = require('../lib');4var fs = require('fs');5var join = require('path').join;6var exec = require('child_process').exec;7var ioc = require('socket.io-client');8var request = require('supertest');9var expect = require('expect.js');10// Creates a socket.io client for the given server11function client(srv, nsp, opts){12 if ('object' == typeof nsp) {13 opts = nsp;14 nsp = null;15 }16 var addr = srv.address();17 if (!addr) addr = srv.listen().address();18 var url = 'ws://localhost:' + addr.port + (nsp || '');19 return ioc(url, opts);20}21describe('socket.io', function(){22 it('should be the same version as client', function(){23 var version = require('../package').version;24 expect(version).to.be(require('socket.io-client/package').version);25 });26 describe('set', function() {27 it('should be able to set ping timeout to engine.io', function() {28 var srv = io(http());29 srv.set('heartbeat timeout', 10);30 expect(srv.eio.pingTimeout).to.be(10);31 });32 it('should be able to set ping interval to engine.io', function() {33 var srv = io(http());34 srv.set('heartbeat interval', 10);35 expect(srv.eio.pingInterval).to.be(10);36 });37 it('should be able to set transports to engine.io', function() {38 var srv = io(http());39 srv.set('transports', ['polling']);40 expect(srv.eio.transports).to.eql(['polling']);41 });42 it('should be able to set maxHttpBufferSize to engine.io', function() {43 var srv = io(http());44 srv.set('destroy buffer size', 10);45 expect(srv.eio.maxHttpBufferSize).to.eql(10);46 });47 it('should be able to set path with setting resource', function(done) {48 var eio = io();49 var srv = http();50 eio.set('resource', '/random');51 eio.attach(srv);52 // Check that the server is accessible through the specified path53 request(srv)54 .get('/random/socket.io.js')55 .buffer(true)56 .end(function(err, res){57 if (err) return done(err);58 done();59 });60 });61 it('should be able to set origins to engine.io', function() {62 var srv = io(http());63 srv.set('origins', 'http://hostname.com:*');64 expect(srv.origins()).to.be('http://hostname.com:*');65 });66 it('should be able to set authorization and send error packet', function(done) {67 var httpSrv = http();68 var srv = io(httpSrv);69 srv.set('authorization', function(o, f) { f(null, false); });70 var socket = client(httpSrv);71 socket.on('connect', function(){72 expect().fail();73 });74 socket.on('error', function(err) {75 expect(err).to.be('Not authorized');76 done();77 });78 });79 it('should be able to set authorization and succeed', function(done) {80 var httpSrv = http();81 var srv = io(httpSrv);82 srv.set('authorization', function(o, f) { f(null, true); });83 srv.on('connection', function(s) {84 s.on('yoyo', function(data) {85 expect(data).to.be('data');86 done();87 });88 });89 var socket = client(httpSrv);90 socket.on('connect', function(){91 socket.emit('yoyo', 'data');92 });93 socket.on('error', function(err) {94 expect().fail();95 });96 });97 it('should set the handshake BC object', function(done){98 var httpSrv = http();99 var srv = io(httpSrv);100 srv.on('connection', function(s) {101 expect(s.handshake).to.not.be(undefined);102 // Headers set and has some valid properties103 expect(s.handshake.headers).to.be.an('object');104 expect(s.handshake.headers['user-agent']).to.be('node-XMLHttpRequest');105 // Time set and is valid looking string106 expect(s.handshake.time).to.be.a('string');107 expect(s.handshake.time.split(' ').length > 0); // Is "multipart" string representation108 // Address, xdomain, secure, issued and url set109 expect(s.handshake.address).to.contain('127.0.0.1');110 expect(s.handshake.xdomain).to.be.a('boolean');111 expect(s.handshake.secure).to.be.a('boolean');112 expect(s.handshake.issued).to.be.a('number');113 expect(s.handshake.url).to.be.a('string');114 // Query set and has some right properties115 expect(s.handshake.query).to.be.an('object');116 expect(s.handshake.query.EIO).to.not.be(undefined);117 expect(s.handshake.query.transport).to.not.be(undefined);118 expect(s.handshake.query.t).to.not.be(undefined);119 done();120 });121 var socket = client(httpSrv);122 });123 });124 describe('server attachment', function(){125 describe('http.Server', function(){126 var clientVersion = require('socket.io-client/package').version;127 it('should serve static files', function(done){128 var srv = http();129 io(srv);130 request(srv)131 .get('/socket.io/socket.io.js')132 .buffer(true)133 .end(function(err, res){134 if (err) return done(err);135 var ctype = res.headers['content-type'];136 expect(ctype).to.be('application/javascript');137 expect(res.headers.etag).to.be('"' + clientVersion + '"');138 expect(res.text).to.match(/engine\.io/);139 expect(res.status).to.be(200);140 done();141 });142 });143 it('should handle 304', function(done){144 var srv = http();145 io(srv);146 request(srv)147 .get('/socket.io/socket.io.js')148 .set('If-None-Match', '"' + clientVersion + '"')149 .end(function(err, res){150 if (err) return done(err);151 expect(res.statusCode).to.be(304);152 done();153 });154 });155 it('should not serve static files', function(done){156 var srv = http();157 io(srv, { serveClient: false });158 request(srv)159 .get('/socket.io/socket.io.js')160 .expect(400, done);161 });162 it('should work with #attach', function(done){163 var srv = http(function(req, res){164 res.writeHead(404);165 res.end();166 });167 var sockets = io();168 sockets.attach(srv);169 request(srv)170 .get('/socket.io/socket.io.js')171 .end(function(err, res){172 if (err) return done(err);173 expect(res.status).to.be(200);174 done();175 });176 });177 });178 describe('port', function(done){179 it('should be bound', function(done){180 var sockets = io(54010);181 request('http://localhost:54010')182 .get('/socket.io/socket.io.js')183 .expect(200, done);184 });185 it('should be bound as a string', function(done) {186 var sockets = io('54020');187 request('http://localhost:54020')188 .get('/socket.io/socket.io.js')189 .expect(200, done);190 });191 it('with listen', function(done){192 var sockets = io().listen(54011);193 request('http://localhost:54011')194 .get('/socket.io/socket.io.js')195 .expect(200, done);196 });197 it('as a string', function(done){198 var sockets = io().listen('54012');199 request('http://localhost:54012')200 .get('/socket.io/socket.io.js')201 .expect(200, done);202 });203 });204 });205 describe('handshake', function(){206 var request = require('superagent');207 it('should disallow request when origin defined and none specified', function(done) {208 var sockets = io({ origins: 'http://foo.example:*' }).listen('54013');209 request.get('http://localhost:54013/socket.io/default/')210 .query({ transport: 'polling' })211 .end(function (err, res) {212 expect(res.status).to.be(403);213 done();214 });215 });216 it('should disallow request when origin defined and a different one specified', function(done) {217 var sockets = io({ origins: 'http://foo.example:*' }).listen('54014');218 request.get('http://localhost:54014/socket.io/default/')219 .query({ transport: 'polling' })220 .set('origin', 'http://herp.derp')221 .end(function (err, res) {222 expect(res.status).to.be(403);223 done();224 });225 });226 it('should allow request when origin defined an the same is specified', function(done) {227 var sockets = io({ origins: 'http://foo.example:*' }).listen('54015');228 request.get('http://localhost:54015/socket.io/default/')229 .set('origin', 'http://foo.example')230 .query({ transport: 'polling' })231 .end(function (err, res) {232 expect(res.status).to.be(200);233 done();234 });235 });236 it('should allow request when origin defined as function and same is supplied', function(done) {237 var sockets = io({ origins: function(origin,callback){238 if (origin == 'http://foo.example') {239 return callback(null, true);240 }241 return callback(null, false);242 } }).listen('54016');243 request.get('http://localhost:54016/socket.io/default/')244 .set('origin', 'http://foo.example')245 .query({ transport: 'polling' })246 .end(function (err, res) {247 expect(res.status).to.be(200);248 done();249 });250 });251 it('should allow request when origin defined as function and different is supplied', function(done) {252 var sockets = io({ origins: function(origin,callback){253 if (origin == 'http://foo.example') {254 return callback(null, true);255 }256 return callback(null, false);257 } }).listen('54017');258 request.get('http://localhost:54017/socket.io/default/')259 .set('origin', 'http://herp.derp')260 .query({ transport: 'polling' })261 .end(function (err, res) {262 expect(res.status).to.be(403);263 done();264 });265 });266 it('should allow request when origin defined as function and no origin is supplied', function(done) {267 var sockets = io({ origins: function(origin,callback){268 if (origin == '*') {269 return callback(null, true);270 }271 return callback(null, false);272 } }).listen('54021');273 request.get('http://localhost:54021/socket.io/default/')274 .query({ transport: 'polling' })275 .end(function (err, res) {276 expect(res.status).to.be(200);277 done();278 });279 });280 it('should default to port 443 when protocol is https', function(done) {281 var sockets = io({ origins: 'https://foo.example:443' }).listen('54036');282 request.get('http://localhost:54036/socket.io/default/')283 .set('origin', 'https://foo.example')284 .query({ transport: 'polling' })285 .end(function (err, res) {286 expect(res.status).to.be(200);287 done();288 });289 });290 it('should allow request if custom function in opts.allowRequest returns true', function(done){291 var sockets = io(http().listen(54022), { allowRequest: function (req, callback) {292 return callback(null, true);293 }, origins: 'http://foo.example:*' });294 request.get('http://localhost:54022/socket.io/default/')295 .query({ transport: 'polling' })296 .end(function (err, res) {297 expect(res.status).to.be(200);298 done();299 });300 });301 it('should disallow request if custom function in opts.allowRequest returns false', function(done){302 var sockets = io(http().listen(54023), { allowRequest: function (req, callback) {303 return callback(null, false);304 } });305 request.get('http://localhost:54023/socket.io/default/')306 .set('origin', 'http://foo.example')307 .query({ transport: 'polling' })308 .end(function (err, res) {309 expect(res.status).to.be(403);310 done();311 });312 });313 it('should allow request when using an array of origins', function(done) {314 io({ origins: [ 'http://foo.example:54024' ] }).listen('54024');315 request.get('http://localhost:54024/socket.io/default/')316 .set('origin', 'http://foo.example:54024')317 .query({ transport: 'polling' })318 .end(function (err, res) {319 expect(res.status).to.be(200);320 done();321 });322 });323 });324 describe('close', function(){325 it('should be able to close sio sending a srv', function(){326 var PORT = 54018;327 var srv = http().listen(PORT);328 var sio = io(srv);329 var net = require('net');330 var server = net.createServer();331 var clientSocket = client(srv, { reconnection: false });332 clientSocket.on('disconnect', function init() {333 expect(Object.keys(sio.nsps['/'].sockets).length).to.equal(0);334 server.listen(PORT);335 });336 clientSocket.on('connect', function init() {337 expect(Object.keys(sio.nsps['/'].sockets).length).to.equal(1);338 sio.close();339 });340 server.once('listening', function() {341 // PORT should be free342 server.close(function(error){343 expect(error).to.be(undefined);344 });345 });346 });347 it('should be able to close sio sending a port', function(){348 var PORT = 54019;349 var sio = io(PORT);350 var net = require('net');351 var server = net.createServer();352 var clientSocket = ioc('ws://0.0.0.0:' + PORT, { reconnection: false });353 clientSocket.on('disconnect', function init() {354 expect(Object.keys(sio.nsps['/'].sockets).length).to.equal(0);355 server.listen(PORT);356 });357 clientSocket.on('connect', function init() {358 expect(Object.keys(sio.nsps['/'].sockets).length).to.equal(1);359 sio.close();360 });361 server.once('listening', function() {362 // PORT should be free363 server.close(function(error){364 expect(error).to.be(undefined);365 });366 });367 });368 describe('graceful close', function(){369 function fixture(filename) {370 return '"' + process.execPath + '" "' +371 join(__dirname, 'fixtures', filename) + '"';372 }373 it('should stop socket and timers', function(done){374 exec(fixture('server-close.js'), done);375 });376 });377 });378 describe('namespaces', function(){379 var Socket = require('../lib/socket');380 var Namespace = require('../lib/namespace');381 it('should be accessible through .sockets', function(){382 var sio = io();383 expect(sio.sockets).to.be.a(Namespace);384 });385 it('should be aliased', function(){386 var sio = io();387 expect(sio.use).to.be.a('function');388 expect(sio.to).to.be.a('function');389 expect(sio['in']).to.be.a('function');390 expect(sio.emit).to.be.a('function');391 expect(sio.send).to.be.a('function');392 expect(sio.write).to.be.a('function');393 expect(sio.clients).to.be.a('function');394 expect(sio.compress).to.be.a('function');395 expect(sio.json).to.be(sio);396 expect(sio.volatile).to.be(sio);397 expect(sio.sockets.flags).to.eql({ json: true, volatile: true });398 delete sio.sockets.flags;399 });400 it('should automatically connect', function(done){401 var srv = http();402 var sio = io(srv);403 srv.listen(function(){404 var socket = client(srv);405 socket.on('connect', function(){406 done();407 });408 });409 });410 it('should fire a `connection` event', function(done){411 var srv = http();412 var sio = io(srv);413 srv.listen(function(){414 var socket = client(srv);415 sio.on('connection', function(socket){416 expect(socket).to.be.a(Socket);417 done();418 });419 });420 });421 it('should fire a `connect` event', function(done){422 var srv = http();423 var sio = io(srv);424 srv.listen(function(){425 var socket = client(srv);426 sio.on('connect', function(socket){427 expect(socket).to.be.a(Socket);428 done();429 });430 });431 });432 it('should work with many sockets', function(done){433 var srv = http();434 var sio = io(srv);435 srv.listen(function(){436 sio.of('/chat');437 sio.of('/news');438 var chat = client(srv, '/chat');439 var news = client(srv, '/news');440 var total = 2;441 chat.on('connect', function(){442 --total || done();443 });444 news.on('connect', function(){445 --total || done();446 });447 });448 });449 it('should be able to equivalently start with "" or "/" on server', function(done){450 var srv = http();451 var sio = io(srv);452 var total = 2;453 sio.of('').on('connection', function(){454 --total || done();455 });456 sio.of('abc').on('connection', function(){457 --total || done();458 });459 var c1 = client(srv, '/');460 var c2 = client(srv, '/abc');461 });462 it('should be equivalent for "" and "/" on client', function(done){463 var srv = http();464 var sio = io(srv);465 sio.of('/').on('connection', function(){466 done();467 });468 var c1 = client(srv, '');469 });470 it('should work with `of` and many sockets', function(done){471 var srv = http();472 var sio = io(srv);473 srv.listen(function(){474 var chat = client(srv, '/chat');475 var news = client(srv, '/news');476 var total = 2;477 sio.of('/news').on('connection', function(socket){478 expect(socket).to.be.a(Socket);479 --total || done();480 });481 sio.of('/news').on('connection', function(socket){482 expect(socket).to.be.a(Socket);483 --total || done();484 });485 });486 });487 it('should work with `of` second param', function(done){488 var srv = http();489 var sio = io(srv);490 srv.listen(function(){491 var chat = client(srv, '/chat');492 var news = client(srv, '/news');493 var total = 2;494 sio.of('/news', function(socket){495 expect(socket).to.be.a(Socket);496 --total || done();497 });498 sio.of('/news', function(socket){499 expect(socket).to.be.a(Socket);500 --total || done();501 });502 });503 });504 it('should disconnect upon transport disconnection', function(done){505 var srv = http();506 var sio = io(srv);507 srv.listen(function(){508 var chat = client(srv, '/chat');509 var news = client(srv, '/news');510 var total = 2;511 var totald = 2;512 var s;513 sio.of('/news', function(socket){514 socket.on('disconnect', function(reason){515 --totald || done();516 });517 --total || close();518 });519 sio.of('/chat', function(socket){520 s = socket;521 socket.on('disconnect', function(reason){522 --totald || done();523 });524 --total || close();525 });526 function close(){527 s.disconnect(true);528 }529 });530 });531 it('should disconnect both default and custom namespace upon disconnect', function(done){532 var srv = http();533 var sio = io(srv);534 srv.listen(function(){535 var lolcats = client(srv, '/lolcats');536 var total = 2;537 var totald = 2;538 var s;539 sio.of('/', function(socket){540 socket.on('disconnect', function(reason){541 --totald || done();542 });543 --total || close();544 });545 sio.of('/lolcats', function(socket){546 s = socket;547 socket.on('disconnect', function(reason){548 --totald || done();549 });550 --total || close();551 });552 function close(){553 s.disconnect(true);554 }555 });556 });557 it('should not crash while disconnecting socket', function(done){558 var srv = http();559 var sio = io(srv);560 srv.listen(function(){561 var socket = client(srv,'/ns');562 sio.on('connection', function(socket){563 socket.disconnect();564 done();565 });566 });567 });568 it('should fire a `disconnecting` event just before leaving all rooms', function(done){569 var srv = http();570 var sio = io(srv);571 srv.listen(function(){572 var socket = client(srv);573 sio.on('connection', function(s){574 s.join('a', function(){575 s.disconnect();576 });577 var total = 2;578 s.on('disconnecting', function(reason){579 expect(Object.keys(s.rooms)).to.eql([s.id, 'a']);580 total--;581 });582 s.on('disconnect', function(reason){583 expect(Object.keys(s.rooms)).to.eql([]);584 --total || done();585 });586 });587 });588 });589 it('should return error connecting to non-existent namespace', function(done){590 var srv = http();591 var sio = io(srv);592 srv.listen(function(){593 var socket = client(srv,'/doesnotexist');594 socket.on('error', function(err) {595 expect(err).to.be('Invalid namespace');596 done();597 });598 });599 });600 601 it('should not reuse same-namespace connections', function(done){602 var srv = http();603 var sio = io(srv);604 var connections = 0;605 srv.listen(function() {606 var clientSocket1 = client(srv);607 var clientSocket2 = client(srv);608 sio.on('connection', function() {609 connections++;610 if (connections === 2) {611 done();612 }613 });614 });615 });616 it('should find all clients in a namespace', function(done){617 var srv = http();618 var sio = io(srv);619 var chatSids = [];620 var otherSid = null;621 srv.listen(function(){622 var c1 = client(srv, '/chat');623 var c2 = client(srv, '/chat', {forceNew: true});624 var c3 = client(srv, '/other', {forceNew: true});625 var total = 3;626 sio.of('/chat').on('connection', function(socket){627 chatSids.push(socket.id);628 --total || getClients();629 });630 sio.of('/other').on('connection', function(socket){631 otherSid = socket.id;632 --total || getClients();633 });634 });635 function getClients() {636 sio.of('/chat').clients(function(error, sids) {637 expect(error).to.not.be.ok();638 expect(sids).to.contain(chatSids[0]);639 expect(sids).to.contain(chatSids[1]);640 expect(sids).to.not.contain(otherSid);641 done();642 });643 }644 });645 it('should find all clients in a namespace room', function(done){646 var srv = http();647 var sio = io(srv);648 var chatFooSid = null;649 var chatBarSid = null;650 var otherSid = null;651 srv.listen(function(){652 var c1 = client(srv, '/chat');653 var c2 = client(srv, '/chat', {forceNew: true});654 var c3 = client(srv, '/other', {forceNew: true});655 var chatIndex = 0;656 var total = 3;657 sio.of('/chat').on('connection', function(socket){658 if (chatIndex++) {659 socket.join('foo', function() {660 chatFooSid = socket.id;661 --total || getClients();662 });663 } else {664 socket.join('bar', function() {665 chatBarSid = socket.id;666 --total || getClients();667 });668 }669 });670 sio.of('/other').on('connection', function(socket){671 socket.join('foo', function() {672 otherSid = socket.id;673 --total || getClients();674 });675 });676 });677 function getClients() {678 sio.of('/chat').in('foo').clients(function(error, sids) {679 expect(error).to.not.be.ok();680 expect(sids).to.contain(chatFooSid);681 expect(sids).to.not.contain(chatBarSid);682 expect(sids).to.not.contain(otherSid);683 done();684 });685 }686 });687 it('should find all clients across namespace rooms', function(done){688 var srv = http();689 var sio = io(srv);690 var chatFooSid = null;691 var chatBarSid = null;692 var otherSid = null;693 srv.listen(function(){694 var c1 = client(srv, '/chat');695 var c2 = client(srv, '/chat', {forceNew: true});696 var c3 = client(srv, '/other', {forceNew: true});697 var chatIndex = 0;698 var total = 3;699 sio.of('/chat').on('connection', function(socket){700 if (chatIndex++) {701 socket.join('foo', function() {702 chatFooSid = socket.id;703 --total || getClients();704 });705 } else {706 socket.join('bar', function() {707 chatBarSid = socket.id;708 --total || getClients();709 });710 }711 });712 sio.of('/other').on('connection', function(socket){713 socket.join('foo', function() {714 otherSid = socket.id;715 --total || getClients();716 });717 });718 });719 function getClients() {720 sio.of('/chat').clients(function(error, sids) {721 expect(error).to.not.be.ok();722 expect(sids).to.contain(chatFooSid);723 expect(sids).to.contain(chatBarSid);724 expect(sids).to.not.contain(otherSid);725 done();726 });727 }728 });729 it('should not emit volatile event after regular event', function(done) {730 var srv = http();731 var sio = io(srv);732 var counter = 0;733 srv.listen(function(){734 sio.of('/chat').on('connection', function(s){735 // Wait to make sure there are no packets being sent for opening the connection736 setTimeout(function() {737 sio.of('/chat').emit('ev', 'data');738 sio.of('/chat').volatile.emit('ev', 'data');739 }, 50);740 });741 var socket = client(srv, '/chat');742 socket.on('ev', function() {743 counter++;744 });745 });746 setTimeout(function() {747 expect(counter).to.be(1);748 done();749 }, 500);750 });751 it('should emit volatile event', function(done) {752 var srv = http();753 var sio = io(srv);754 var counter = 0;755 srv.listen(function(){756 sio.of('/chat').on('connection', function(s){757 // Wait to make sure there are no packets being sent for opening the connection758 setTimeout(function() {759 sio.of('/chat').volatile.emit('ev', 'data');760 }, 100);761 });762 var socket = client(srv, '/chat');763 socket.on('ev', function() {764 counter++;765 });766 });767 setTimeout(function() {768 expect(counter).to.be(1);769 done();770 }, 500);771 });772 it('should enable compression by default', function(done){773 var srv = http();774 var sio = io(srv);775 srv.listen(function(){776 var socket = client(srv, '/chat');777 sio.of('/chat').on('connection', function(s){778 s.conn.once('packetCreate', function(packet) {779 expect(packet.options.compress).to.be(true);780 done();781 });782 sio.of('/chat').emit('woot', 'hi');783 });784 });785 });786 it('should disable compression', function(done){787 var srv = http();788 var sio = io(srv);789 srv.listen(function(){790 var socket = client(srv, '/chat');791 sio.of('/chat').on('connection', function(s){792 s.conn.once('packetCreate', function(packet) {793 expect(packet.options.compress).to.be(false);794 done();795 });796 sio.of('/chat').compress(false).emit('woot', 'hi');797 });798 });799 });800 describe('dynamic namespaces', function () {801 it('should allow connections to dynamic namespaces with a regex', function(done){802 const srv = http();803 const sio = io(srv);804 let count = 0;805 srv.listen(function(){806 const socket = client(srv, '/dynamic-101');807 let dynamicNsp = sio.of(/^\/dynamic-\d+$/).on('connect', (socket) => {808 expect(socket.nsp.name).to.be('/dynamic-101');809 dynamicNsp.emit('hello', 1, '2', { 3: '4'});810 if (++count === 4) done();811 }).use((socket, next) => {812 next();813 if (++count === 4) done();814 });815 socket.on('error', function(err) {816 expect().fail();817 });818 socket.on('connect', () => {819 if (++count === 4) done();820 });821 socket.on('hello', (a, b, c) => {822 expect(a).to.eql(1);823 expect(b).to.eql('2');824 expect(c).to.eql({ 3: '4' });825 if (++count === 4) done();826 });827 });828 });829 it('should allow connections to dynamic namespaces with a function', function(done){830 const srv = http();831 const sio = io(srv);832 srv.listen(function(){833 const socket = client(srv, '/dynamic-101');834 sio.of((name, query, next) => next(null, '/dynamic-101' === name));835 socket.on('connect', done);836 });837 });838 it('should disallow connections when no dynamic namespace matches', function(done){839 const srv = http();840 const sio = io(srv);841 srv.listen(function(){842 const socket = client(srv, '/abc');843 sio.of(/^\/dynamic-\d+$/);844 sio.of((name, query, next) => next(null, '/dynamic-101' === name));845 socket.on('error', (err) => {846 expect(err).to.be('Invalid namespace');847 done();848 });849 });850 });851 });852 });853 describe('socket', function(){854 it('should not fire events more than once after manually reconnecting', function(done) {855 var srv = http();856 var sio = io(srv);857 srv.listen(function(){858 var clientSocket = client(srv, { reconnection: false });859 clientSocket.on('connect', function init() {860 clientSocket.removeListener('connect', init);861 clientSocket.io.engine.close();862 clientSocket.connect();863 clientSocket.on('connect', function() {864 done();865 });866 });867 });868 });869 it('should not fire reconnect_failed event more than once when server closed', function(done) {870 var srv = http();871 var sio = io(srv);872 srv.listen(function(){873 var clientSocket = client(srv, { reconnectionAttempts: 3, reconnectionDelay: 10 });874 clientSocket.on('connect', function() {875 srv.close();876 });877 clientSocket.on('reconnect_failed', function() {878 done();879 });880 });881 });882 it('should receive events', function(done){883 var srv = http();884 var sio = io(srv);885 srv.listen(function(){886 var socket = client(srv);887 sio.on('connection', function(s){888 s.on('random', function(a, b, c){889 expect(a).to.be(1);890 expect(b).to.be('2');891 expect(c).to.eql([3]);892 done();893 });894 socket.emit('random', 1, '2', [3]);895 });896 });897 });898 it('should receive message events through `send`', function(done){899 var srv = http();900 var sio = io(srv);901 srv.listen(function(){902 var socket = client(srv);903 sio.on('connection', function(s){904 s.on('message', function(a){905 expect(a).to.be(1337);906 done();907 });908 socket.send(1337);909 });910 });911 });912 it('should error with null messages', function(done){913 var srv = http();914 var sio = io(srv);915 srv.listen(function(){916 var socket = client(srv);917 sio.on('connection', function(s){918 s.on('message', function(a){919 expect(a).to.be(null);920 done();921 });922 socket.send(null);923 });924 });925 });926 it('should handle transport null messages', function(done){927 var srv = http();928 var sio = io(srv);929 srv.listen(function(){930 var socket = client(srv, { reconnection: false });931 sio.on('connection', function(s){932 s.on('error', function(err){933 expect(err).to.be.an(Error);934 s.on('disconnect', function(reason){935 expect(reason).to.be('forced close');936 done();937 });938 });939 s.client.ondata(null);940 });941 });942 });943 it('should emit events', function(done){944 var srv = http();945 var sio = io(srv);946 srv.listen(function(){947 var socket = client(srv);948 socket.on('woot', function(a){949 expect(a).to.be('tobi');950 done();951 });952 sio.on('connection', function(s){953 s.emit('woot', 'tobi');954 });955 });956 });957 it('should emit events with utf8 multibyte character', function(done) {958 var srv = http();959 var sio = io(srv);960 srv.listen(function(){961 var socket = client(srv);962 var i = 0;963 socket.on('hoot', function(a){964 expect(a).to.be('utf8 â string');965 i++;966 if (3 == i) {967 done();968 }969 });970 sio.on('connection', function(s){971 s.emit('hoot', 'utf8 â string');972 s.emit('hoot', 'utf8 â string');973 s.emit('hoot', 'utf8 â string');974 });975 });976 });977 it('should emit events with binary data', function(done){978 var srv = http();979 var sio = io(srv);980 srv.listen(function(){981 var socket = client(srv);982 var imageData;983 socket.on('doge', function(a){984 expect(Buffer.isBuffer(a)).to.be(true);985 expect(imageData.length).to.equal(a.length);986 expect(imageData[0]).to.equal(a[0]);987 expect(imageData[imageData.length - 1]).to.equal(a[a.length - 1]);988 done();989 });990 sio.on('connection', function(s){991 fs.readFile(join(__dirname, 'support', 'doge.jpg'), function(err, data){992 if (err) return done(err);993 imageData = data;994 s.emit('doge', data);995 });996 });997 });998 });999 it('should emit events with several types of data (including binary)', function(done){1000 var srv = http();1001 var sio = io(srv);1002 srv.listen(function(){1003 var socket = client(srv);1004 socket.on('multiple', function(a, b, c, d, e, f){1005 expect(a).to.be(1);1006 expect(Buffer.isBuffer(b)).to.be(true);1007 expect(c).to.be('3');1008 expect(d).to.eql([4]);1009 expect(Buffer.isBuffer(e)).to.be(true);1010 expect(Buffer.isBuffer(f[0])).to.be(true);1011 expect(f[1]).to.be('swag');1012 expect(Buffer.isBuffer(f[2])).to.be(true);1013 done();1014 });1015 sio.on('connection', function(s){1016 fs.readFile(join(__dirname, 'support', 'doge.jpg'), function(err, data){1017 if (err) return done(err);1018 var buf = new Buffer('asdfasdf', 'utf8');1019 s.emit('multiple', 1, data, '3', [4], buf, [data, 'swag', buf]);1020 });1021 });1022 });1023 });1024 it('should receive events with binary data', function(done){1025 var srv = http();1026 var sio = io(srv);1027 srv.listen(function(){1028 var socket = client(srv);1029 sio.on('connection', function(s){1030 s.on('buff', function(a){1031 expect(Buffer.isBuffer(a)).to.be(true);1032 done();1033 });1034 var buf = new Buffer('abcdefg', 'utf8');1035 socket.emit('buff', buf);1036 });1037 });1038 });1039 it('should receive events with several types of data (including binary)', function(done){1040 var srv = http();1041 var sio = io(srv);1042 srv.listen(function(){1043 var socket = client(srv);1044 sio.on('connection', function(s){1045 s.on('multiple', function(a, b, c, d, e, f){1046 expect(a).to.be(1);1047 expect(Buffer.isBuffer(b)).to.be(true);1048 expect(c).to.be('3');1049 expect(d).to.eql([4]);1050 expect(Buffer.isBuffer(e)).to.be(true);1051 expect(Buffer.isBuffer(f[0])).to.be(true);1052 expect(f[1]).to.be('swag');1053 expect(Buffer.isBuffer(f[2])).to.be(true);1054 done();1055 });1056 fs.readFile(join(__dirname, 'support', 'doge.jpg'), function(err, data){1057 if (err) return done(err);1058 var buf = new Buffer('asdfasdf', 'utf8');1059 socket.emit('multiple', 1, data, '3', [4], buf, [data, 'swag', buf]);1060 });1061 });1062 });1063 });1064 it('should not emit volatile event after regular event (polling)', function(done) {1065 var srv = http();1066 var sio = io(srv, { transports: ['polling'] });1067 var counter = 0;1068 srv.listen(function(){1069 sio.on('connection', function(s){1070 s.emit('ev', 'data');1071 s.volatile.emit('ev', 'data');1072 });1073 var socket = client(srv, { transports: ['polling'] });1074 socket.on('ev', function() {1075 counter++;1076 });1077 });1078 setTimeout(function() {1079 expect(counter).to.be(1);1080 done();1081 }, 200);1082 });1083 it('should not emit volatile event after regular event (ws)', function(done) {1084 var srv = http();1085 var sio = io(srv, { transports: ['websocket'] });1086 var counter = 0;1087 srv.listen(function(){1088 sio.on('connection', function(s){1089 s.emit('ev', 'data');1090 s.volatile.emit('ev', 'data');1091 });1092 var socket = client(srv, { transports: ['websocket'] });1093 socket.on('ev', function() {1094 counter++;1095 });1096 });1097 setTimeout(function() {1098 expect(counter).to.be(1);1099 done();1100 }, 200);1101 });1102 it('should emit volatile event (polling)', function(done) {1103 var srv = http();1104 var sio = io(srv, { transports: ['polling'] });1105 var counter = 0;1106 srv.listen(function(){1107 sio.on('connection', function(s){1108 // Wait to make sure there are no packets being sent for opening the connection1109 setTimeout(function() {1110 s.volatile.emit('ev', 'data');1111 }, 100);1112 });1113 var socket = client(srv, { transports: ['polling'] });1114 socket.on('ev', function() {1115 counter++;1116 });1117 });1118 setTimeout(function() {1119 expect(counter).to.be(1);1120 done();1121 }, 500);1122 });1123 it('should emit volatile event (ws)', function(done) {1124 var srv = http();1125 var sio = io(srv, { transports: ['websocket'] });1126 var counter = 0;1127 srv.listen(function(){1128 sio.on('connection', function(s){1129 // Wait to make sure there are no packets being sent for opening the connection1130 setTimeout(function() {1131 s.volatile.emit('ev', 'data');1132 }, 20);1133 });1134 var socket = client(srv, { transports: ['websocket'] });1135 socket.on('ev', function() {1136 counter++;1137 });1138 });1139 setTimeout(function() {1140 expect(counter).to.be(1);1141 done();1142 }, 200);1143 });1144 it('should emit only one consecutive volatile event (polling)', function(done) {1145 var srv = http();1146 var sio = io(srv, { transports: ['polling'] });1147 var counter = 0;1148 srv.listen(function(){1149 sio.on('connection', function(s){1150 // Wait to make sure there are no packets being sent for opening the connection1151 setTimeout(function() {1152 s.volatile.emit('ev', 'data');1153 s.volatile.emit('ev', 'data');1154 }, 100);1155 });1156 var socket = client(srv, { transports: ['polling'] });1157 socket.on('ev', function() {1158 counter++;1159 });1160 });1161 setTimeout(function() {1162 expect(counter).to.be(1);1163 done();1164 }, 500);1165 });1166 it('should emit only one consecutive volatile event (ws)', function(done) {1167 var srv = http();1168 var sio = io(srv, { transports: ['websocket'] });1169 var counter = 0;1170 srv.listen(function(){1171 sio.on('connection', function(s){1172 // Wait to make sure there are no packets being sent for opening the connection1173 setTimeout(function() {1174 s.volatile.emit('ev', 'data');1175 s.volatile.emit('ev', 'data');1176 }, 20);1177 });1178 var socket = client(srv, { transports: ['websocket'] });1179 socket.on('ev', function() {1180 counter++;1181 });1182 });1183 setTimeout(function() {1184 expect(counter).to.be(1);1185 done();1186 }, 200);1187 });1188 it('should emit regular events after trying a failed volatile event (polling)', function(done) {1189 var srv = http();1190 var sio = io(srv, { transports: ['polling'] });1191 var counter = 0;1192 srv.listen(function(){1193 sio.on('connection', function(s){1194 // Wait to make sure there are no packets being sent for opening the connection1195 setTimeout(function() {1196 s.emit('ev', 'data');1197 s.volatile.emit('ev', 'data');1198 s.emit('ev', 'data');1199 }, 20);1200 });1201 var socket = client(srv, { transports: ['polling'] });1202 socket.on('ev', function() {1203 counter++;1204 });1205 });1206 setTimeout(function() {1207 expect(counter).to.be(2);1208 done();1209 }, 200);1210 });1211 it('should emit regular events after trying a failed volatile event (ws)', function(done) {1212 var srv = http();1213 var sio = io(srv, { transports: ['websocket'] });1214 var counter = 0;1215 srv.listen(function(){1216 sio.on('connection', function(s){1217 // Wait to make sure there are no packets being sent for opening the connection1218 setTimeout(function() {1219 s.emit('ev', 'data');1220 s.volatile.emit('ev', 'data');1221 s.emit('ev', 'data');1222 }, 20);1223 });1224 var socket = client(srv, { transports: ['websocket'] });1225 socket.on('ev', function() {1226 counter++;1227 });1228 });1229 setTimeout(function() {1230 expect(counter).to.be(2);1231 done();1232 }, 200);1233 });1234 it('should emit message events through `send`', function(done){1235 var srv = http();1236 var sio = io(srv);1237 srv.listen(function(){1238 var socket = client(srv);1239 socket.on('message', function(a){1240 expect(a).to.be('a');1241 done();1242 });1243 sio.on('connection', function(s){1244 s.send('a');1245 });1246 });1247 });1248 it('should receive event with callbacks', function(done){1249 var srv = http();1250 var sio = io(srv);1251 srv.listen(function(){1252 var socket = client(srv);1253 sio.on('connection', function(s){1254 s.on('woot', function(fn){1255 fn(1, 2);1256 });1257 socket.emit('woot', function(a, b){1258 expect(a).to.be(1);1259 expect(b).to.be(2);1260 done();1261 });1262 });1263 });1264 });1265 it('should receive all events emitted from namespaced client immediately and in order', function(done) {1266 var srv = http();1267 var sio = io(srv);1268 var total = 0;1269 srv.listen(function(){1270 sio.of('/chat', function(s){1271 s.on('hi', function(letter){1272 total++;1273 if (total == 2 && letter == 'b') {1274 done();1275 } else if (total == 1 && letter != 'a') {1276 throw new Error('events out of order');1277 }1278 });1279 });1280 var chat = client(srv, '/chat');1281 chat.emit('hi', 'a');1282 setTimeout(function() {1283 chat.emit('hi', 'b');1284 }, 50);1285 });1286 });1287 it('should emit events with callbacks', function(done){1288 var srv = http();1289 var sio = io(srv);1290 srv.listen(function(){1291 var socket = client(srv);1292 sio.on('connection', function(s){1293 socket.on('hi', function(fn){1294 fn();1295 });1296 s.emit('hi', function(){1297 done();1298 });1299 });1300 });1301 });1302 it('should receive events with args and callback', function(done){1303 var srv = http();1304 var sio = io(srv);1305 srv.listen(function(){1306 var socket = client(srv);1307 sio.on('connection', function(s){1308 s.on('woot', function(a, b, fn){1309 expect(a).to.be(1);1310 expect(b).to.be(2);1311 fn();1312 });1313 socket.emit('woot', 1, 2, function(){1314 done();1315 });1316 });1317 });1318 });1319 it('should emit events with args and callback', function(done){1320 var srv = http();1321 var sio = io(srv);1322 srv.listen(function(){1323 var socket = client(srv);1324 sio.on('connection', function(s){1325 socket.on('hi', function(a, b, fn){1326 expect(a).to.be(1);1327 expect(b).to.be(2);1328 fn();1329 });1330 s.emit('hi', 1, 2, function(){1331 done();1332 });1333 });1334 });1335 });1336 it('should receive events with binary args and callbacks', function(done) {1337 var srv = http();1338 var sio = io(srv);1339 srv.listen(function(){1340 var socket = client(srv);1341 sio.on('connection', function(s){1342 s.on('woot', function(buf, fn){1343 expect(Buffer.isBuffer(buf)).to.be(true);1344 fn(1, 2);1345 });1346 socket.emit('woot', new Buffer(3), function(a, b){1347 expect(a).to.be(1);1348 expect(b).to.be(2);1349 done();1350 });1351 });1352 });1353 });1354 it('should emit events with binary args and callback', function(done){1355 var srv = http();1356 var sio = io(srv);1357 srv.listen(function(){1358 var socket = client(srv);1359 sio.on('connection', function(s){1360 socket.on('hi', function(a, fn){1361 expect(Buffer.isBuffer(a)).to.be(true);1362 fn();1363 });1364 s.emit('hi', new Buffer(4), function(){1365 done();1366 });1367 });1368 });1369 });1370 it('should emit events and receive binary data in a callback', function(done) {1371 var srv = http();1372 var sio = io(srv);1373 srv.listen(function(){1374 var socket = client(srv);1375 sio.on('connection', function(s){1376 socket.on('hi', function(fn){1377 fn(new Buffer(1));1378 });1379 s.emit('hi', function(a){1380 expect(Buffer.isBuffer(a)).to.be(true);1381 done();1382 });1383 });1384 });1385 });1386 it('should receive events and pass binary data in a callback', function(done) {1387 var srv = http();1388 var sio = io(srv);1389 srv.listen(function(){1390 var socket = client(srv);1391 sio.on('connection', function(s){1392 s.on('woot', function(fn){1393 fn(new Buffer(2));1394 });1395 socket.emit('woot', function(a){1396 expect(Buffer.isBuffer(a)).to.be(true);1397 done();1398 });1399 });1400 });1401 });1402 it('should have access to the client', function(done){1403 var srv = http();1404 var sio = io(srv);1405 srv.listen(function(){1406 var socket = client(srv);1407 sio.on('connection', function(s){1408 expect(s.client).to.be.an('object');1409 done();1410 });1411 });1412 });1413 it('should have access to the connection', function(done){1414 var srv = http();1415 var sio = io(srv);1416 srv.listen(function(){1417 var socket = client(srv);1418 sio.on('connection', function(s){1419 expect(s.client.conn).to.be.an('object');1420 expect(s.conn).to.be.an('object');1421 done();1422 });1423 });1424 });1425 it('should have access to the request', function(done){1426 var srv = http();1427 var sio = io(srv);1428 srv.listen(function(){1429 var socket = client(srv);1430 sio.on('connection', function(s){1431 expect(s.client.request.headers).to.be.an('object');1432 expect(s.request.headers).to.be.an('object');1433 done();1434 });1435 });1436 });1437 it('should see query parameters in the request', function(done) {1438 var srv = http();1439 var sio = io(srv);1440 srv.listen(function() {1441 var socket = client(srv, {query: {key1: 1, key2: 2}});1442 sio.on('connection', function(s) {1443 var parsed = require('url').parse(s.request.url);1444 var query = require('querystring').parse(parsed.query);1445 expect(query.key1).to.be('1');1446 expect(query.key2).to.be('2');1447 done();1448 });1449 });1450 });1451 1452 it('should see query parameters sent from secondary namespace connections in handshake object', function(done){1453 var srv = http();1454 var sio = io(srv);1455 var client1 = client(srv);1456 var client2 = client(srv, '/connection2', {query: {key1: 'aa', key2: '&=bb'}});1457 sio.on('connection', function(s){1458 });1459 sio.of('/connection2').on('connection', function(s){1460 expect(s.handshake.query.key1).to.be('aa');1461 expect(s.handshake.query.key2).to.be('&=bb');1462 done();1463 });1464 });1465 it('should handle very large json', function(done){1466 this.timeout(30000);1467 var srv = http();1468 var sio = io(srv, { perMessageDeflate: false });1469 var received = 0;1470 srv.listen(function(){1471 var socket = client(srv);1472 socket.on('big', function(a){1473 expect(Buffer.isBuffer(a.json)).to.be(false);1474 if (++received == 3)1475 done();1476 else1477 socket.emit('big', a);1478 });1479 sio.on('connection', function(s){1480 fs.readFile(join(__dirname, 'fixtures', 'big.json'), function(err, data){1481 if (err) return done(err);1482 data = JSON.parse(data);1483 s.emit('big', {hello: 'friend', json: data});1484 });1485 s.on('big', function(a){1486 s.emit('big', a);1487 });1488 });1489 });1490 });1491 it('should handle very large binary data', function(done){1492 this.timeout(30000);1493 var srv = http();1494 var sio = io(srv, { perMessageDeflate: false });1495 var received = 0;1496 srv.listen(function(){1497 var socket = client(srv);1498 socket.on('big', function(a){1499 expect(Buffer.isBuffer(a.image)).to.be(true);1500 if (++received == 3)1501 done();1502 else1503 socket.emit('big', a);1504 });1505 sio.on('connection', function(s){1506 fs.readFile(join(__dirname, 'fixtures', 'big.jpg'), function(err, data){1507 if (err) return done(err);1508 s.emit('big', {hello: 'friend', image: data});1509 });1510 s.on('big', function(a){1511 expect(Buffer.isBuffer(a.image)).to.be(true);1512 s.emit('big', a);1513 });1514 });1515 });1516 });1517 it('should be able to emit after server close and restart', function(done){1518 var srv = http();1519 var sio = io(srv);1520 sio.on('connection', function(socket){1521 socket.on('ev', function(data){1522 expect(data).to.be('payload');1523 done();1524 });1525 });1526 srv.listen(function(){1527 var port = srv.address().port;1528 var clientSocket = client(srv, { reconnectionAttempts: 10, reconnectionDelay: 100 });1529 clientSocket.once('connect', function(){1530 srv.close(function(){1531 clientSocket.on('reconnect', function(){1532 clientSocket.emit('ev', 'payload');1533 });1534 sio.listen(port);1535 });1536 });1537 });1538 });1539 it('should enable compression by default', function(done){1540 var srv = http();1541 var sio = io(srv);1542 srv.listen(function(){1543 var socket = client(srv, '/chat');1544 sio.of('/chat').on('connection', function(s){1545 s.conn.once('packetCreate', function(packet) {1546 expect(packet.options.compress).to.be(true);1547 done();1548 });1549 sio.of('/chat').emit('woot', 'hi');1550 });1551 });1552 });1553 it('should disable compression', function(done){1554 var srv = http();1555 var sio = io(srv);1556 srv.listen(function(){1557 var socket = client(srv, '/chat');1558 sio.of('/chat').on('connection', function(s){1559 s.conn.once('packetCreate', function(packet) {1560 expect(packet.options.compress).to.be(false);1561 done();1562 });1563 sio.of('/chat').compress(false).emit('woot', 'hi');1564 });1565 });1566 });1567 it('should error with raw binary and warn', function(done){1568 var srv = http();1569 var sio = io(srv);1570 srv.listen(function(){1571 var socket = client(srv, { reconnection: false });1572 sio.on('connection', function(s){1573 s.conn.on('upgrade', function(){1574 console.log('\u001b[96mNote: warning expected and normal in test.\u001b[39m');1575 socket.io.engine.write('5woooot');1576 setTimeout(function(){1577 done();1578 }, 100);1579 });1580 });1581 });1582 });1583 it('should not crash when receiving an error packet without handler', function(done){1584 var srv = http();1585 var sio = io(srv);1586 srv.listen(function(){1587 var socket = client(srv, { reconnection: false });1588 sio.on('connection', function(s){1589 s.conn.on('upgrade', function(){1590 console.log('\u001b[96mNote: warning expected and normal in test.\u001b[39m');1591 socket.io.engine.write('44["handle me please"]');1592 setTimeout(function(){1593 done();1594 }, 100);1595 });1596 });1597 });1598 });1599 it('should not crash with raw binary', function(done){1600 var srv = http();1601 var sio = io(srv);1602 srv.listen(function(){1603 var socket = client(srv, { reconnection: false });1604 sio.on('connection', function(s){1605 s.once('error', function(err){1606 expect(err.message).to.match(/Illegal attachments/);1607 done();1608 });1609 s.conn.on('upgrade', function(){1610 socket.io.engine.write('5woooot');1611 });1612 });1613 });1614 });1615 it('should handle empty binary packet', function(done){1616 var srv = http();1617 var sio = io(srv);1618 srv.listen(function(){1619 var socket = client(srv, { reconnection: false });1620 sio.on('connection', function(s){1621 s.once('error', function(err){1622 expect(err.message).to.match(/Illegal attachments/);1623 done();1624 });1625 s.conn.on('upgrade', function(){1626 socket.io.engine.write('5');1627 });1628 });1629 });1630 });1631 it('should not crash when messing with Object prototype (and other globals)', function(done){1632 Object.prototype.foo = 'bar';1633 global.File = '';1634 global.Blob = [];1635 var srv = http();1636 var sio = io(srv);1637 srv.listen(function(){1638 var socket = client(srv);1639 sio.on('connection', function(s){1640 s.disconnect(true);1641 sio.close();1642 setTimeout(function(){1643 done();1644 }, 100);1645 });1646 });1647 });1648 it('should always trigger the callback (if provided) when joining a room', function(done){1649 var srv = http();1650 var sio = io(srv);1651 srv.listen(function(){1652 var socket = client(srv);1653 sio.on('connection', function(s){1654 s.join('a', function(){1655 s.join('a', done);1656 });1657 });1658 });1659 });1660 });1661 describe('messaging many', function(){1662 it('emits to a namespace', function(done){1663 var srv = http();1664 var sio = io(srv);1665 var total = 2;1666 srv.listen(function(){1667 var socket1 = client(srv, { multiplex: false });1668 var socket2 = client(srv, { multiplex: false });1669 var socket3 = client(srv, '/test');1670 socket1.on('a', function(a){1671 expect(a).to.be('b');1672 --total || done();1673 });1674 socket2.on('a', function(a){1675 expect(a).to.be('b');1676 --total || done();1677 });1678 socket3.on('a', function(){ done(new Error('not')); });1679 var sockets = 3;1680 sio.on('connection', function(socket){1681 --sockets || emit();1682 });1683 sio.of('/test', function(socket){1684 --sockets || emit();1685 });1686 function emit(){1687 sio.emit('a', 'b');1688 }1689 });1690 });1691 it('emits binary data to a namespace', function(done){1692 var srv = http();1693 var sio = io(srv);1694 var total = 2;1695 srv.listen(function(){1696 var socket1 = client(srv, { multiplex: false });1697 var socket2 = client(srv, { multiplex: false });1698 var socket3 = client(srv, '/test');1699 socket1.on('bin', function(a){1700 expect(Buffer.isBuffer(a)).to.be(true);1701 --total || done();1702 });1703 socket2.on('bin', function(a){1704 expect(Buffer.isBuffer(a)).to.be(true);1705 --total || done();1706 });1707 socket3.on('bin', function(){ done(new Error('not')); });1708 var sockets = 3;1709 sio.on('connection', function(socket){1710 --sockets || emit();1711 });1712 sio.of('/test', function(socket){1713 --sockets || emit();1714 });1715 function emit(){1716 sio.emit('bin', new Buffer(10));1717 }1718 });1719 });1720 it('emits to the rest', function(done){1721 var srv = http();1722 var sio = io(srv);1723 var total = 2;1724 srv.listen(function(){1725 var socket1 = client(srv, { multiplex: false });1726 var socket2 = client(srv, { multiplex: false });1727 var socket3 = client(srv, '/test');1728 socket1.on('a', function(a){1729 expect(a).to.be('b');1730 socket1.emit('finish');1731 });1732 socket2.emit('broadcast');1733 socket2.on('a', function(){ done(new Error('done')); });1734 socket3.on('a', function(){ done(new Error('not')); });1735 var sockets = 2;1736 sio.on('connection', function(socket){1737 socket.on('broadcast', function(){1738 socket.broadcast.emit('a', 'b');1739 });1740 socket.on('finish', function(){1741 done();1742 });1743 });1744 });1745 });1746 it('emits to rooms', function(done){1747 var srv = http();1748 var sio = io(srv);1749 var total = 2;1750 srv.listen(function(){1751 var socket1 = client(srv, { multiplex: false });1752 var socket2 = client(srv, { multiplex: false });1753 socket2.on('a', function(){1754 done(new Error('not'));1755 });1756 socket1.on('a', function(){1757 done();1758 });1759 socket1.emit('join', 'woot', function(){1760 socket1.emit('emit', 'woot');1761 });1762 sio.on('connection', function(socket){1763 socket.on('join', function(room, fn){1764 socket.join(room, fn);1765 });1766 socket.on('emit', function(room){1767 sio.in(room).emit('a');1768 });1769 });1770 });1771 });1772 it('emits to rooms avoiding dupes', function(done){1773 var srv = http();1774 var sio = io(srv);1775 var total = 2;1776 srv.listen(function(){1777 var socket1 = client(srv, { multiplex: false });1778 var socket2 = client(srv, { multiplex: false });1779 socket2.on('a', function(){1780 done(new Error('not'));1781 });1782 socket1.on('a', function(){1783 --total || done();1784 });1785 socket2.on('b', function(){1786 --total || done();1787 });1788 socket1.emit('join', 'woot');1789 socket1.emit('join', 'test');1790 socket2.emit('join', 'third', function(){1791 socket2.emit('emit');1792 });1793 sio.on('connection', function(socket){1794 socket.on('join', function(room, fn){1795 socket.join(room, fn);1796 });1797 socket.on('emit', function(room){1798 sio.in('woot').in('test').emit('a');1799 sio.in('third').emit('b');1800 });1801 });1802 });1803 });1804 it('broadcasts to rooms', function(done){1805 var srv = http();1806 var sio = io(srv);1807 var total = 2;1808 srv.listen(function(){1809 var socket1 = client(srv, { multiplex: false });1810 var socket2 = client(srv, { multiplex: false });1811 var socket3 = client(srv, { multiplex: false });1812 socket1.emit('join', 'woot');1813 socket2.emit('join', 'test');1814 socket3.emit('join', 'test', function(){1815 socket3.emit('broadcast');1816 });1817 socket1.on('a', function(){1818 done(new Error('not'));1819 });1820 socket2.on('a', function(){1821 --total || done();1822 });1823 socket3.on('a', function(){1824 done(new Error('not'));1825 });1826 socket3.on('b', function(){1827 --total || done();1828 });1829 sio.on('connection', function(socket){1830 socket.on('join', function(room, fn){1831 socket.join(room, fn);1832 });1833 socket.on('broadcast', function(){1834 socket.broadcast.to('test').emit('a');1835 socket.emit('b');1836 });1837 });1838 });1839 });1840 it('broadcasts binary data to rooms', function(done){1841 var srv = http();1842 var sio = io(srv);1843 var total = 2;1844 srv.listen(function(){1845 var socket1 = client(srv, { multiplex: false });1846 var socket2 = client(srv, { multiplex: false });1847 var socket3 = client(srv, { multiplex: false });1848 socket1.emit('join', 'woot');1849 socket2.emit('join', 'test');1850 socket3.emit('join', 'test', function(){1851 socket3.emit('broadcast');1852 });1853 socket1.on('bin', function(data){1854 throw new Error('got bin in socket1');1855 });1856 socket2.on('bin', function(data){1857 expect(Buffer.isBuffer(data)).to.be(true);1858 --total || done();1859 });1860 socket2.on('bin2', function(data) {1861 throw new Error('socket2 got bin2');1862 });1863 socket3.on('bin', function(data) {1864 throw new Error('socket3 got bin');1865 });1866 socket3.on('bin2', function(data) {1867 expect(Buffer.isBuffer(data)).to.be(true);1868 --total || done();1869 });1870 sio.on('connection', function(socket){1871 socket.on('join', function(room, fn){1872 socket.join(room, fn);1873 });1874 socket.on('broadcast', function(){1875 socket.broadcast.to('test').emit('bin', new Buffer(5));1876 socket.emit('bin2', new Buffer(5));1877 });1878 });1879 });1880 });1881 it('keeps track of rooms', function(done){1882 var srv = http();1883 var sio = io(srv);1884 srv.listen(function(){1885 var socket = client(srv);1886 sio.on('connection', function(s){1887 s.join('a', function(){1888 expect(Object.keys(s.rooms)).to.eql([s.id, 'a']);1889 s.join('b', function(){1890 expect(Object.keys(s.rooms)).to.eql([s.id, 'a', 'b']);1891 s.join( 'c', function(){1892 expect(Object.keys(s.rooms)).to.eql([s.id, 'a', 'b', 'c']);1893 s.leave('b', function(){1894 expect(Object.keys(s.rooms)).to.eql([s.id, 'a', 'c']);1895 s.leaveAll();1896 expect(Object.keys(s.rooms)).to.eql([]);1897 done();1898 });1899 });1900 });1901 });1902 });1903 });1904 });1905 it('deletes empty rooms', function(done) {1906 var srv = http();1907 var sio = io(srv);1908 srv.listen(function(){1909 var socket = client(srv);1910 sio.on('connection', function(s){1911 s.join('a', function(){1912 expect(s.nsp.adapter.rooms).to.have.key('a');1913 s.leave('a', function(){1914 expect(s.nsp.adapter.rooms).to.not.have.key('a');1915 done();1916 });1917 });1918 });1919 });1920 });1921 it('should properly cleanup left rooms', function(done){1922 var srv = http();1923 var sio = io(srv);1924 srv.listen(function(){1925 var socket = client(srv);1926 sio.on('connection', function(s){1927 s.join('a', function(){1928 expect(Object.keys(s.rooms)).to.eql([s.id, 'a']);1929 s.join('b', function(){1930 expect(Object.keys(s.rooms)).to.eql([s.id, 'a', 'b']);1931 s.leave('unknown', function(){1932 expect(Object.keys(s.rooms)).to.eql([s.id, 'a', 'b']);1933 s.leaveAll();1934 expect(Object.keys(s.rooms)).to.eql([]);1935 done();1936 });1937 });1938 });1939 });1940 });1941 });1942 it('allows to join several rooms at once', function(done) {1943 var srv = http();1944 var sio = io(srv);1945 srv.listen(function(){1946 var socket = client(srv);1947 sio.on('connection', function(s){1948 s.join(['a', 'b', 'c'], function(){1949 expect(Object.keys(s.rooms)).to.eql([s.id, 'a', 'b', 'c']);1950 done();1951 });1952 });1953 });1954 });1955 });1956 describe('middleware', function(done){1957 var Socket = require('../lib/socket');1958 it('should call functions', function(done){1959 var srv = http();1960 var sio = io(srv);1961 var run = 0;1962 sio.use(function(socket, next){1963 expect(socket).to.be.a(Socket);1964 run++;1965 next();1966 });1967 sio.use(function(socket, next){1968 expect(socket).to.be.a(Socket);1969 run++;1970 next();1971 });1972 srv.listen(function(){1973 var socket = client(srv);1974 socket.on('connect', function(){1975 expect(run).to.be(2);1976 done();1977 });1978 });1979 });1980 it('should pass errors', function(done){1981 var srv = http();1982 var sio = io(srv);1983 var run = 0;1984 sio.use(function(socket, next){1985 next(new Error('Authentication error'));1986 });1987 sio.use(function(socket, next){1988 done(new Error('nope'));1989 });1990 srv.listen(function(){1991 var socket = client(srv);1992 socket.on('connect', function(){1993 done(new Error('nope'));1994 });1995 socket.on('error', function(err){1996 expect(err).to.be('Authentication error');1997 done();1998 });1999 });2000 });2001 it('should pass `data` of error object', function(done){2002 var srv = http();2003 var sio = io(srv);2004 var run = 0;2005 sio.use(function(socket, next){2006 var err = new Error('Authentication error');2007 err.data = { a: 'b', c: 3 };2008 next(err);2009 });2010 srv.listen(function(){2011 var socket = client(srv);2012 socket.on('connect', function(){2013 done(new Error('nope'));2014 });2015 socket.on('error', function(err){2016 expect(err).to.eql({ a: 'b', c: 3 });2017 done();2018 });2019 });2020 });2021 it('should only call connection after fns', function(done){2022 var srv = http();2023 var sio = io(srv);2024 sio.use(function(socket, next){2025 socket.name = 'guillermo';2026 next();2027 });2028 srv.listen(function(){2029 var socket = client(srv);2030 sio.on('connection', function(socket){2031 expect(socket.name).to.be('guillermo');2032 done();2033 });2034 });2035 });2036 it('should only call connection after (lengthy) fns', function(done){2037 var srv = http();2038 var sio = io(srv);2039 var authenticated = false;2040 sio.use(function(socket, next){2041 setTimeout(function () {2042 authenticated = true;2043 next();2044 }, 300);2045 });2046 srv.listen(function(){2047 var socket = client(srv);2048 socket.on('connect', function(){2049 expect(authenticated).to.be(true);2050 done();2051 });2052 });2053 });2054 it('should be ignored if socket gets closed', function(done){2055 var srv = http();2056 var sio = io(srv);2057 var socket;2058 sio.use(function(s, next){2059 socket.io.engine.on('open', function(){2060 socket.io.engine.close();2061 s.client.conn.on('close', function(){2062 process.nextTick(next);2063 setTimeout(function(){2064 done();2065 }, 50);2066 });2067 });2068 });2069 srv.listen(function(){2070 socket = client(srv);2071 sio.on('connection', function(socket){2072 done(new Error('should not fire'));2073 });2074 });2075 });2076 it('should call functions in expected order', function(done){2077 var srv = http();2078 var sio = io(srv);2079 var result = [];2080 sio.use(function(socket, next) {2081 result.push(1);2082 setTimeout(next, 50);2083 });2084 sio.use(function(socket, next) {2085 result.push(2);2086 setTimeout(next, 50);2087 });2088 sio.of('/chat').use(function(socket, next) {2089 result.push(3);2090 setTimeout(next, 50);2091 });2092 sio.of('/chat').use(function(socket, next) {2093 result.push(4);2094 setTimeout(next, 50);2095 });2096 srv.listen(function() {2097 var chat = client(srv, '/chat');2098 chat.on('connect', function() {2099 expect(result).to.eql([1, 2, 3, 4]);2100 done();2101 });2102 });2103 });2104 it('should disable the merge of handshake packets', function(done){2105 var srv = http();2106 var sio = io();2107 sio.use(function(socket, next){2108 next();2109 });2110 sio.listen(srv);2111 var socket = client(srv);2112 socket.on('connect', function(){2113 done();2114 });2115 });2116 it('should work with a custom namespace', (done) => {2117 var srv = http();2118 var sio = io();2119 sio.listen(srv);2120 sio.of('/chat').use(function(socket, next){2121 next();2122 });2123 var count = 0;2124 client(srv, '/').on('connect', () => {2125 if (++count === 2) done();2126 });2127 client(srv, '/chat').on('connect', () => {2128 if (++count === 2) done();2129 });2130 });2131 });2132 describe('socket middleware', function(done){2133 var Socket = require('../lib/socket');2134 it('should call functions', function(done){2135 var srv = http();2136 var sio = io(srv);2137 var run = 0;2138 srv.listen(function(){2139 var socket = client(srv, { multiplex: false });2140 socket.emit('join', 'woot');2141 sio.on('connection', function(socket){2142 socket.use(function(event, next){2143 expect(event).to.eql(['join', 'woot']);2144 event.unshift('wrap');2145 run++;2146 next();2147 });2148 socket.use(function(event, next){2149 expect(event).to.eql(['wrap', 'join', 'woot']);2150 run++;2151 next();2152 });2153 socket.on('wrap', function(data1, data2){2154 expect(data1).to.be('join');2155 expect(data2).to.be('woot');2156 expect(run).to.be(2);2157 done();2158 });2159 });2160 });2161 });2162 it('should pass errors', function(done){2163 var srv = http();2164 var sio = io(srv);2165 srv.listen(function(){2166 var clientSocket = client(srv, { multiplex: false });2167 clientSocket.emit('join', 'woot');2168 clientSocket.on('error', function(err){2169 expect(err).to.be('Authentication error');2170 done();2171 });2172 sio.on('connection', function(socket){2173 socket.use(function(event, next){2174 next(new Error('Authentication error'));2175 });2176 socket.use(function(event, next){2177 done(new Error('nope'));2178 });2179 socket.on('join', function(){2180 done(new Error('nope'));2181 });2182 });2183 });2184 });2185 it('should pass `data` of error object', function(done){2186 var srv = http();2187 var sio = io(srv);2188 srv.listen(function(){2189 var clientSocket = client(srv, { multiplex: false });2190 clientSocket.emit('join', 'woot');2191 clientSocket.on('error', function(err){2192 expect(err).to.eql({ a: 'b', c: 3 });2193 done();2194 });2195 sio.on('connection', function(socket){2196 socket.use(function(event, next){2197 var err = new Error('Authentication error');2198 err.data = { a: 'b', c: 3 };2199 next(err);2200 });2201 socket.on('join', function(){2202 done(new Error('nope'));2203 });2204 });2205 });2206 });2207 });...
srv_polling.ts
Source:srv_polling.ts
1import * as dns from 'dns';2import { clearTimeout, setTimeout } from 'timers';3import { MongoRuntimeError } from '../error';4import { Logger, LoggerOptions } from '../logger';5import { TypedEventEmitter } from '../mongo_types';6import { HostAddress } from '../utils';7/**8 * Determines whether a provided address matches the provided parent domain in order9 * to avoid certain attack vectors.10 *11 * @param srvAddress - The address to check against a domain12 * @param parentDomain - The domain to check the provided address against13 * @returns Whether the provided address matches the parent domain14 */15function matchesParentDomain(srvAddress: string, parentDomain: string): boolean {16 const regex = /^.*?\./;17 const srv = `.${srvAddress.replace(regex, '')}`;18 const parent = `.${parentDomain.replace(regex, '')}`;19 return srv.endsWith(parent);20}21/**22 * @internal23 * @category Event24 */25export class SrvPollingEvent {26 srvRecords: dns.SrvRecord[];27 constructor(srvRecords: dns.SrvRecord[]) {28 this.srvRecords = srvRecords;29 }30 hostnames(): Set<string> {31 return new Set(this.srvRecords.map(r => HostAddress.fromSrvRecord(r).toString()));32 }33}34/** @internal */35export interface SrvPollerOptions extends LoggerOptions {36 srvServiceName: string;37 srvMaxHosts: number;38 srvHost: string;39 heartbeatFrequencyMS: number;40}41/** @internal */42export type SrvPollerEvents = {43 srvRecordDiscovery(event: SrvPollingEvent): void;44};45/** @internal */46export class SrvPoller extends TypedEventEmitter<SrvPollerEvents> {47 srvHost: string;48 rescanSrvIntervalMS: number;49 heartbeatFrequencyMS: number;50 logger: Logger;51 haMode: boolean;52 generation: number;53 srvMaxHosts: number;54 srvServiceName: string;55 _timeout?: NodeJS.Timeout;56 /** @event */57 static readonly SRV_RECORD_DISCOVERY = 'srvRecordDiscovery' as const;58 constructor(options: SrvPollerOptions) {59 super();60 if (!options || !options.srvHost) {61 throw new MongoRuntimeError('Options for SrvPoller must exist and include srvHost');62 }63 this.srvHost = options.srvHost;64 this.srvMaxHosts = options.srvMaxHosts ?? 0;65 this.srvServiceName = options.srvServiceName ?? 'mongodb';66 this.rescanSrvIntervalMS = 60000;67 this.heartbeatFrequencyMS = options.heartbeatFrequencyMS ?? 10000;68 this.logger = new Logger('srvPoller', options);69 this.haMode = false;70 this.generation = 0;71 this._timeout = undefined;72 }73 get srvAddress(): string {74 return `_${this.srvServiceName}._tcp.${this.srvHost}`;75 }76 get intervalMS(): number {77 return this.haMode ? this.heartbeatFrequencyMS : this.rescanSrvIntervalMS;78 }79 start(): void {80 if (!this._timeout) {81 this.schedule();82 }83 }84 stop(): void {85 if (this._timeout) {86 clearTimeout(this._timeout);87 this.generation += 1;88 this._timeout = undefined;89 }90 }91 schedule(): void {92 if (this._timeout) {93 clearTimeout(this._timeout);94 }95 this._timeout = setTimeout(() => this._poll(), this.intervalMS);96 }97 success(srvRecords: dns.SrvRecord[]): void {98 this.haMode = false;99 this.schedule();100 this.emit(SrvPoller.SRV_RECORD_DISCOVERY, new SrvPollingEvent(srvRecords));101 }102 failure(message: string, obj?: NodeJS.ErrnoException): void {103 this.logger.warn(message, obj);104 this.haMode = true;105 this.schedule();106 }107 parentDomainMismatch(srvRecord: dns.SrvRecord): void {108 this.logger.warn(109 `parent domain mismatch on SRV record (${srvRecord.name}:${srvRecord.port})`,110 srvRecord111 );112 }113 _poll(): void {114 const generation = this.generation;115 dns.resolveSrv(this.srvAddress, (err, srvRecords) => {116 if (generation !== this.generation) {117 return;118 }119 if (err) {120 this.failure('DNS error', err);121 return;122 }123 const finalAddresses: dns.SrvRecord[] = [];124 for (const record of srvRecords) {125 if (matchesParentDomain(record.name, this.srvHost)) {126 finalAddresses.push(record);127 } else {128 this.parentDomainMismatch(record);129 }130 }131 if (!finalAddresses.length) {132 this.failure('No valid addresses found at host');133 return;134 }135 this.success(finalAddresses);136 });137 }...
Using AI Code Generation
1var express = require('express');2var app = express();3var stf = require('devicefarmer-stf');4var srv = stf.srv;5app.get('/', function (req, res) {6 res.send('Hello World!');7});8app.get('/getDevices', function (req, res) {9 srv.getDevices(function(err, data) {10 if(err) {11 console.log(err);12 res.send('Error');13 }14 else {15 console.log(data);16 res.send(data);17 }18 });19});20app.listen(3000, function () {21 console.log('Example app listening on port 3000!');22});
Using AI Code Generation
1var devicefarmer = require('devicefarmer-stf-client');2var srv = devicefarmer.srv;3srv.getDevices(function (err, devices) {4 if (err) {5 console.error(err);6 } else {7 console.log(devices);8 }9});10var devicefarmer = require('devicefarmer-stf-client');11devicefarmer.getDevices(function (err, devices) {12 if (err) {13 console.error(err);14 } else {15 console.log(devices);16 }17});18getDevices(callback)19getDevicesByOwner(owner, callback)20getDevicesByOwnerAndModel(owner, model, callback)21getDevicesByOwnerAndModelAndVersion(owner, model, version, callback)22getDevicesByModel(model, callback)23getDevicesByModelAndVersion(model, version, callback)24getDevicesBySerial(serial, callback)25getDevicesBySerialAndModel(serial, model, callback)26getDevicesBySerialAndModelAndVersion(serial, model, version, callback)27getDevicesByModelAndVersion(model, version, callback)28getDevicesByOwnerAndSerial(owner, serial, callback)29getDevicesByOwnerAndSerialAndModel(owner, serial, model, callback)30getDevicesByOwnerAndSerialAndModelAndVersion(owner, serial, model, version, callback)31getDevicesByOwnerAndModelAndVersion(owner, model, version, callback)32getDevicesByOwnerAndModel(owner, model, callback)33getDevicesByOwnerAndVersion(owner, version, callback)34getDevicesBySerialAndVersion(serial, version, callback)35getDevicesBySerialAndModelAndVersion(serial, model, version, callback)36getDevicesByModelAndVersion(model, version, callback)37getDevicesByOwnerAndSerialAndVersion(owner, serial, version, callback)38getDevicesByOwnerAndSerialAndModel(owner, serial, model, callback)39getDevicesByOwnerAndSerialAndModelAndVersion(owner, serial, model, version, callback)40getDevicesByOwnerAndModelAndVersion(owner, model, version, callback)41getDevicesByOwnerAndModel(owner, model, callback)42getDevicesByOwnerAndVersion(owner, version, callback)43getDevicesBySerialAndVersion(serial, version, callback)44getDevicesBySerialAndModelAndVersion(serial, model, version, callback)
Using AI Code Generation
1var stf = require('devicefarmer-stf');2var srv = new stf.Srv();3srv.getDevices(function(err, devices) {4 console.log(devices);5});6var stf = require('devicefarmer-stf');7var srv = new stf.Srv();8srv.getDevices(function(err, devices) {9 console.log(devices);10});11var stf = require('devicefarmer-stf');12var srv = new stf.Srv();13srv.getDevices(function(err, devices) {14 console.log(devices);15});16var stf = require('devicefarmer-stf');17var srv = new stf.Srv();18srv.getDevices(function(err, devices) {19 console.log(devices);20});21var stf = require('devicefarmer-stf');22var srv = new stf.Srv();23srv.getDevices(function(err, devices) {24 console.log(devices);25});26var stf = require('devicefarmer-stf');27var srv = new stf.Srv();28srv.getDevices(function(err, devices) {29 console.log(devices);30});31var stf = require('devicefarmer-stf');32var srv = new stf.Srv();33srv.getDevices(function(err, devices) {34 console.log(devices);35});36var stf = require('devicefarmer-stf');37var srv = new stf.Srv();38srv.getDevices(function(err, devices) {39 console.log(devices);40});41var stf = require('devicefarmer-stf');42var srv = new stf.Srv();43srv.getDevices(function(err, devices) {44 console.log(devices);45});
Using AI Code Generation
1var stf = require('devicefarmer-stf');2var srv = new stf.Srv();3srv.start(function (err) {4 if (err) {5 console.log('Failed to start the server');6 return;7 }8 console.log('Server is running');9});10var stf = require('devicefarmer-stf');11var srv = new stf.Srv();12srv.start(function (err) {13 if (err) {14 console.log('Failed to start the server');15 return;16 }17 console.log('Server is running');18});19var stf = require('devicefarmer-stf');20var client = new stf.Client();21client.start(function (err) {22 if (err) {23 console.log('Failed to start the client');24 return;25 }26 console.log('Client is running');27});28var stf = require('devicefarmer-stf');29var provider = new stf.Provider();30provider.start(function (err) {31 if (err) {32 console.log('Failed to start the provider');33 return;34 }35 console.log('Provider is running');36});37var stf = require('devicefarmer-stf');38var reaper = new stf.Reaper();39reaper.start(function (err) {40 if (err) {41 console.log('Failed to start the reaper');42 return;43 }44 console.log('Reaper is running');45});46var stf = require('devicefarmer-stf');47var triproxy = new stf.Triproxy();48triproxy.start(function (err) {49 if (err) {50 console.log('Failed to start the triproxy');51 return;52 }53 console.log('Triproxy is running');54});55var stf = require('devicefarmer-stf');56var auth = new stf.Auth();57auth.start(function (err) {58 if (err) {59 console.log('Failed to start the auth');60 return;61 }62 console.log('Auth is running');63});64var stf = require('devicefarmer-stf');65var processor = new stf.Processor();
Using AI Code Generation
1var stf = require('../lib/stf.js');2var device = stf.srv();3device.on('ready', function (device) {4 console.log('device is ready');5 device.use('shell', function (err, api) {6 if (err) {7 console.log('error: ' + err);8 return;9 }10 api.shell('echo "hello world"', function (err, stream) {11 if (err) {12 console.log('error: ' + err);13 return;14 }15 stream.on('data', function (chunk) {16 console.log(chunk.toString());17 });18 });19 });20});21device.on('error', function (err) {22 console.log('error: ' + err);23});
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!