How to use cookieJar method in apickli

Best JavaScript code snippet using apickli

cookieUtil.js

Source:cookieUtil.js Github

copy

Full Screen

1/*jslint forin:true sub:true anon:true, sloppy:true, stupid:true nomen:true, node:true continue:true*/2/*global require: true, console: true, escape: true, window:true, process:true, module:true*/3/*4 * Copyright (c) 2012 Yahoo! Inc. All rights reserved.5 * Copyrights licensed under the New BSD License.6 * See the accompanying LICENSE file for terms.7 */8/** Yahoo Cookie test helper module, and it could be use in both browser and node.js.9 * @module cookieUtil10 */11YUI.add('cookieUtil', function (Y) {12 'use strict';13 Y.namespace("Arrow");14 var ERRORMSG = {15 UNKNOWN_COOKIE_NAME: "unknown cookie name ",16 INVALID_COOKIE_NAME: "invalid cookie name ",17 INVALID_COOKIE_VALUE: "invalid cookie value",18 MISSING_PARAMETER_NAME: "missing parameter: name is expected. ",19 MISSING_PARAMETER_VALUE: "missing parameter: cookie value is expected.",20 UNSUPPORTED_OPTION: "unsupported option is found.",21 INVALID_SUBCOOKIE: "invalid subcookie name or subcookie value.",22 UNEXPECTED_RESPONSE: "unexpected response received. either cookies or location is missing.",23 INVALID_OBJECT: " is expected as an object.",24 WRONG_PARAMETER_COOKIEVALUE: "wrong parameter: cookie value(string) is expected.",25 WRONG_PARAMETER_SUBFIELDS_ARRAY: "wrong parameter: a subFields array expected.",26 WRONG_PARAMETER_SUBFIELDS_OBJECT: "wrong parameter: a subFields object is expected.",27 WRONG_PARAMETER_CALLBACK: "wrong parameter: a callback is expected.",28 INVALID_PARAMETER: "wrong parameter: following parameters are expected:",29 EXISTING_COOKIE: "the cookie has existed. name: ",30 NONEXISTING_COOKIE: "the cookie doesn't exist. name: ",31 INVALID_COOKIEJAR: "cookiejar is undefined or blank, please input a valid value. ",32 UNDEFINED_HEADER: "header is undfined, please input a valid header. ",33 WRONG_PARAMETER_COOKIES_OBJECT: "wrong parameter: a cookies object is expected.",34 ILLEGAL_RESPONSE: "illegal response",35 NO_COOKIE_FROM_SERVER: "no cookies info from server side",36 INVALID_CONFIG: "invalid configuration file type."37 };38 var defaultconfig = {39 separator: '&',40 equalChar: "=",41 semiColon: ";",42 comma: ",",43 space: " ",44 userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:16.0) Gecko/20100101 Firefox/16.0'45 };46 /**47 * CookieUtil class,Yahoo Cookie test helper module, and it could be use in both browser and node.js48 * @class CookieUtil49 * @constructor50 */51 function CookieUtil() {52 CookieUtil.superclass.constructor.apply(this, arguments);53 }54 Y.extend(CookieUtil, Y.Base, {55 /**56 * Init lifecycle implementation.57 *58 * @method initializer59 * @param {Object} config Configuration object.60 * @protected61 */62 initializer: function (config) {63 if (config && typeof (config) === "object") {64 this.config = config || {};65 } else {66 throw new Error(ERRORMSG.INVALID_CONFIG);67 }68 },69 /**70 * to get separator in cookie value,71 * if it is not urlEncode, return &72 * if it is urlEncode, return %2673 * @method _getSeparator74 * @return {String} '=' or '%26'75 * @private76 */77 _getSeparator: function () {78 var separator = defaultconfig.separator;79 if (this.config.urlEncode) {80 separator = escape(separator);81 }82 return separator;83 },84 /**85 * to get equal char in cookie,86 * if it is not urlEncode, return =87 * if it is urlEncode, return %3D88 * @method _getEqualChar89 * @return {String} '=' or '%3D'90 * @private91 */92 _getEqualChar: function () {93 var equalChar = defaultconfig.equalChar;94 if (this.config.urlEncode) {95 equalChar = escape(equalChar);96 }97 return equalChar;98 },99 /**100 * to get semi colon,101 * if it is not urlEncode, return ;102 * if it is urlEncode, return %3B103 * @method _getSemicolon104 * @return {String} ';' or '%3B'105 * @private106 */107 _getSemicolon: function () {108 var semiColon = defaultconfig.semiColon;109 if (this.config.urlEncode) {110 semiColon = escape(semiColon);111 }112 return semiColon;113 },114 /**115 * to get comma,116 * if it is not urlEncode, return ,117 * if it is urlEncode, return %2C118 * @method _getComma119 * @return {String} ',' or '%2C'120 * @private121 */122 _getComma: function () {123 var comma = defaultconfig.comma;124 if (this.config.urlEncode) {125 comma = escape(comma);126 }127 return comma;128 },129 /**130 * to get white space in cookie,131 * if it is not urlEncode, return space ' '132 * if it is urlEncode, return %20133 * @method _getSpace134 * @return {String} ' ' or '%20'135 * @private136 */137 _getSpace: function () {138 var space = defaultconfig.space;139 if (this.config.urlEncode) {140 space = escape(space);141 }142 return space;143 },144 /**145 * whether this is run on the server side146 * @method _isServer147 * @return {Boolean} return true if it is server side, otherwise it is client side148 * @private149 */150 _isServer: function () {151 if (typeof process === 'object') {152 if (process.versions && process.versions.node) {153 return true;154 }155 } else {156 return false;157 }158 },159 /**160 * generate a customized cookie for the user161 * @method createCustCookie162 * @example163 *164 * createCustCookie ( "custcookie",165 * {166 * fieldA: valueA,167 * fieldB: valueB,168 * },169 * {170 * domain: ".xx.com",171 * path: "/",172 * secure: true,173 * expires: Wednesday, 09-Nov-99 23:12:40 GMT174 * });175 * return cookie string like "SSID=AHOkKrqp7_awIDQ2J;domain=**;expires=**"176 * @param name the cookie name you want to generate177 * @param subFieldsObj an object contains each value of the cookie178 * @param options the options of the cookie. i.e path, domain, secure, expires.179 * @param cb {Function}180 */181 createCustCookie: function (name, subFieldsObj, options, cb) {182 if (!Y.Lang.isFunction(cb)) {183 throw new Error(ERRORMSG.WRONG_PARAMETER_CALLBACK);184 }185 if ((Y.Lang.isUndefined(subFieldsObj))) {186 cb(new Error(ERRORMSG.MISSING_PARAMETER_VALUE));187 return;188 }189 if (!Y.Lang.isObject(subFieldsObj)) {190 cb(new Error(subFieldsObj + ERRORMSG.INVALID_OBJECT));191 return;192 }193 if ((Y.Lang.isUndefined(name))) {194 cb(new Error(ERRORMSG.MISSING_PARAMETER_NAME));195 return;196 }197 var self = this, equalChar, separator, value, error, expires, path, domain, k, v;198 if (self._validateCookieName(name)) {199 equalChar = self._getEqualChar();200 separator = self._getSeparator();201 value = name + equalChar;202 error = null;203 for (k in subFieldsObj) {204 if (subFieldsObj.hasOwnProperty(k)) {205 v = subFieldsObj[k];206 error = self._validateCookieName(k) ? error : true;207 if (v !== "") {208 error = self._validateCookieSpec(v) ? error : true;209 }210 value = value + k + equalChar + v + separator;211 }212 }213 if (error) {214 cb(new Error(ERRORMSG.INVALID_SUBCOOKIE));215 } else {216 //trip off the last &217 value = value.slice(0, value.length - 1);218 options = options || {};219 expires = options.expires;220 path = options.path;221 domain = options.domain;222 if (Y.Lang.isObject(options)) {223 for (k in options) {224 if (options.hasOwnProperty(k)) {225 v = options[k];226 var lowerKey = k.toLowerCase();227 if ((lowerKey !== "domain") && (lowerKey !== "path") && (lowerKey !== "secure") && (lowerKey !== "expires")) {228 console.log(ERRORMSG.UNSUPPORTED_OPTION + k, "warn");229 error = true;230 }231 }232 }233 if (error) {234 cb(new Error(ERRORMSG.UNSUPPORTED_OPTION));235 } else {236 //expiration date237 if (expires instanceof Date) {238 value += "; expires=" + expires.toUTCString();239 }240 //path241 if (Y.Lang.isString(path) && path !== "") {242 value += "; path=" + path;243 }244 //domain245 if (Y.Lang.isString(domain) && domain !== "") {246 value += "; domain=" + domain;247 }248 //secure249 if (options.secure === true) {250 value += "; secure";251 }252 cb(null, value);253 }254 } else {255 cb(new Error("option is expected as an object."));256 }257 }258 } else {259 cb(new Error(ERRORMSG.INVALID_COOKIE_NAME));260 }261 },262 /**263 * validate whether this is a valid cookie name, a cookie name cannot be empty, contains ; or , or ' ',264 * and it is a string265 * @method _validateCookieName266 * @param {String} name the cookie name or sub cookie name267 * @return {*}268 * @private269 */270 _validateCookieName: function (name) {271 if ((name === "") || (name === null)) {272 console.log("the cookie name(sub cookie name) shoud not be empty or null", "error");273 return false;274 }275 return this._validateCookieSpec(name);276 },277 /**278 * the NAME=VALUE should be a string, and not contains ; or , or ' '.279 * @method _validateCookieSpec280 * @param {String} field - the field value281 * @private282 */283 _validateCookieSpec: function (field) {284 if (!Y.Lang.isString(field)) {285 console.log("'" + field + "' is not string");286 return false;287 }288 var semiColon = field.search(this._getSemicolon()), comma = field.search(this._getComma()), space = field.search(this._getSpace());289 // check isString first, else it will fail when user input name like number 1290 if ((semiColon !== -1) || (comma !== -1) || (space !== -1)) {291 console.log("'" + field + "' Error field, each field should be string and doesn't contain ; or , or space.", "error");292 return false;293 }294 return true;295 },296 /**297 * parse cookie string and return an object, the object would be:298 *{299 * _f1:"ddesee",300 * b: "3",301 * a: "8q",302 *}303 * @method _parseCookieString304 * @param value - a string like "ddesee&b=3&a=8q"305 * @param cb {Function}306 * @private307 */308 _parseCookieString: function (value, cb) {309 var separator = this._getSeparator(), equalChar = this._getEqualChar(), text = {}, subFieldsArray = value.split(separator);310 for (var i = 0; i < subFieldsArray.length; i++) {311 var subField = subFieldsArray[i], element = subField.split(equalChar);312 if (element.length > 2) {313 cb(new Error(ERRORMSG.INVALID_COOKIE_VALUE + "[" + value + "]"));314 return;315 }316 if (element.length === 1 && i === 0) {317 //has the subfield, but it is the first field.318 text._f1 = element[0];319 } else {320 text[element[0]] = element[1];321 }322 }323 //check whether input is a valid cookie324 var error = null, v, k, self = this;325 for (k in text) {326 if (text.hasOwnProperty(k)) {327 v = text[k];328 error = self._validateCookieName(k) ? error : true;329 if (!error && v !== "") {330 error = self._validateCookieSpec(v) ? error : true;331 }332 }333 }334 if (error) {335 cb(new Error(ERRORMSG.INVALID_COOKIE_VALUE));336 return;337 } else {338 cb(null, text);339 }340 },341 /**342 * parse cookie object and return an cookie string.343 * @method _parseCookieObjToString344 * @param cookieObj - e.g. {345 * _f1:"bsse",346 * b: "3",347 * a: "8q",348 * }349 * @param cb {Function}350 * @private351 */352 _parseCookieObjToString: function (cookieObj, cb) {353 var separator = this._getSeparator(), equalChar = this._getEqualChar(), text = "", begin = "", v, k;354 for (k in cookieObj) {355 if (cookieObj.hasOwnProperty(k)) {356 v = cookieObj[k];357 if (k === "_f1") {358 begin = v + separator;359 } else {360 text = text + k + equalChar + v + separator;361 }362 }363 }364 text = begin + text;365 // trip off the last separator366 text = text.slice(0, text.length - separator.length);367 cb(null, text);368 },369 /**370 * delete a field or several fields in the cookie value, if all the sub fields are deleted,371 * then set the cookie expire, if the field is not in the cookie, warn and leave it,372 * return the modified cookie string.373 * @method deleteSubCookie374 * @example375 *376 * deleteSubCookie('bsse&b=3&a=8q',['b','a']);377 * @param value - a cookie string like "bsse&b=3&a=8q"378 * @param subFieldsArray - an array contains all the subfield' names379 * @param cb {Function}380 */381 deleteSubCookie: function (value, subFieldsArray, cb) {382 if (!Y.Lang.isFunction(cb)) {383 throw new Error(ERRORMSG.WRONG_PARAMETER_CALLBACK);384 }385 if (Y.Lang.isUndefined(value) || value === "") {386 cb(new Error(ERRORMSG.WRONG_PARAMETER_COOKIEVALUE));387 return;388 }389 if (!Y.Lang.isArray(subFieldsArray)) {390 cb(new Error(ERRORMSG.WRONG_PARAMETER_SUBFIELDS_ARRAY));391 return;392 }393 var self = this;394 this._parseCookieString(value, function (err, cookieObj) {395 if (err) {396 cb(err);397 } else {398 for (var i = 0; i < subFieldsArray.length; i++) {399 if (Y.Lang.isUndefined(cookieObj[subFieldsArray[i]])) {400 console.log("No subfield '" + subFieldsArray[i] + "' found in the cookie", "warn");401 } else {402 //remove the item in the cookieObj403 delete cookieObj[subFieldsArray[i]];404 }405 }406 self._parseCookieObjToString(cookieObj, cb);407 }408 });409 },410 /**411 * Add a sub cookie field to the existing cookie string412 * @method addSubCookie413 * @param value - a cookie string like "ssssx&b=3&a=8q"414 * @param subFieldsObj {Object} - an object includes all the new added field information, examples are:415 * {416 * s: "9j"417 * d: "asdfdsdfa"418 * }419 * return the modified cookie string420 * @param cb {Function}421 */422 addSubCookie: function (value, subFieldsObj, cb) {423 if (!Y.Lang.isFunction(cb)) {424 throw new Error(ERRORMSG.WRONG_PARAMETER_CALLBACK);425 }426 if (Y.Lang.isUndefined(value) || value === "") {427 cb(new Error(ERRORMSG.WRONG_PARAMETER_COOKIEVALUE));428 } else if (!Y.Lang.isObject(subFieldsObj)) {429 cb(new Error(ERRORMSG.WRONG_PARAMETER_SUBFIELDS_OBJECT));430 } else {431 var self = this;432 this._parseCookieString(value, function (err, cookieObj) {433 if (err) {434 cb(err);435 } else {436 var error = false, v, k;437 for (k in subFieldsObj) {438 if (subFieldsObj.hasOwnProperty(k)) {439 v = subFieldsObj[k];440 if (!self._validateCookieSpec(v) || !self._validateCookieName(k)) {441 error = true;442 }443 //check whether the subfield has existed444 if (!Y.Lang.isUndefined(cookieObj[k])) {445 console.log("the subfield '" + k + "' has existed, new value '" + v + "' will replace the old one: " + cookieObj[k], "warn");446 }447 cookieObj[k] = v;448 }449 }450 if (error) {451 cb(new Error("invalid cookie value"));452 } else {453 self._parseCookieObjToString(cookieObj, cb);454 }455 }456 });457 }458 },459 /**460 * modify each field of the cookie if the field exist, otherwise warn the user and leave it be.461 * @method modifyCookie462 * @param value - cookie string463 * @param subFieldsObj {Object} an object includes all the new added field information, examples are:464 * {465 * s: "9j"466 * d: "asdfdsdfa"467 * }468 * @param cb {Function}469 */470 modifyCookie: function (value, subFieldsObj, cb) {471 var self = this, error = null;472 if (!Y.Lang.isFunction(cb)) {473 throw new Error(ERRORMSG.WRONG_PARAMETER_CALLBACK);474 }475 if (Y.Lang.isUndefined(value) || value === "") {476 cb(new Error(ERRORMSG.WRONG_PARAMETER_COOKIEVALUE));477 return;478 }479 if (!Y.Lang.isObject(subFieldsObj)) {480 cb(new Error(ERRORMSG.WRONG_PARAMETER_SUBFIELDS_OBJECT));481 return;482 }483 self._parseCookieString(value, function (err, cookieObj) {484 if (!err) {485 var k, v;486 for (k in subFieldsObj) {487 if (subFieldsObj.hasOwnProperty(k)) {488 v = subFieldsObj[k];489 if (!(self._validateCookieName(k)) || (!self._validateCookieSpec(v))) {490 error = new Error(ERRORMSG.INVALID_SUBCOOKIE);491 }492 if (Y.Lang.isUndefined(cookieObj[k])) {493 error = new Error("try to modify a field doesn't exist");494 } else {495 cookieObj[k] = v;496 }497 }498 }499 if (!error) {500 self._parseCookieObjToString(cookieObj, cb);501 } else {502 cb(error, value);503 }504 } else {505 cb(err, value);506 }507 });508 },509 /**510 * append a cookie in the existing cookiejar511 * @method appendCookieInCookiejar512 * @param cookiejar - the existing cookiejar513 * @param name - the cookie name514 * @param value - the cookie string value515 * @param cb {Function}- a callback to return the error and modified cookie string516 */517 appendCookieInCookiejar: function (cookiejar, name, value, cb) {518 if (!(Y.Lang.isString(cookiejar) && Y.Lang.isString(name) && Y.Lang.isString(value) && Y.Lang.isFunction(cb))) {519 throw new Error(ERRORMSG.INVALID_PARAMETER + "\ncookiejar {String}, name {String}, value {String}, cb {Function}");520 }521 var cookieValue = value, self = this;522 //this is the client side523 if (!self._isServer()) {524 var n = value.indexOf(";");525 cookieValue = value.slice(0, n);526 }527 if ((self._validateCookieName(name)) && (self._validateCookieSpec(cookieValue))) {528 self.getCookieInCookiejar(cookiejar, name, function (err, cookieArray) {529 if (!err) {530 cb(new Error(ERRORMSG.EXISTING_COOKIE + name));531 } else {532 if (self._isServer()) {533 cb(null, cookiejar + "; " + name + "=" + value);534 } else {535 window.document.cookie = name + "=" + value;536 cb(null, window.document.cookie);537 }538 }539 });540 } else {541 cb(new Error(ERRORMSG.INVALID_COOKIE_NAME + "or " + ERRORMSG.INVALID_COOKIE_VALUE));542 }543 },544 /**545 * modify a existing cookie in the cookie jar546 * @method modifyCookieInCookiejar547 * @param cookiejar - the existing cookiejar548 * @param name - the existing cookie name549 * @param value - the cookie value550 * @param cb {Function}- a callback to return the error and the modified cookie string551 */552 modifyCookieInCookiejar: function (cookiejar, name, value, cb) {553 var cookieValue = value, self = this;554 if (!(Y.Lang.isString(cookiejar) && Y.Lang.isString(name) && Y.Lang.isString(value) && Y.Lang.isFunction(cb))) {555 throw new Error(ERRORMSG.INVALID_PARAMETER + "\ncookiejar {String}, name {String}, value {String}, cb {Function}");556 }557 //this is the client side558 if (!self._isServer()) {559 var n = value.indexOf(";");560 cookieValue = value.slice(0, n);561 }562 if (self._validateCookieSpec(cookieValue)) {563 //check whether the cookie has existed in the cookiejar564 self.getCookieInCookiejar(cookiejar, name, function (err, cookieArray) {565 if (!err) {566 var newCookiejar = cookiejar;567 for (var i = 0; i < cookieArray.length; i++) {568 if (self._isServer()) {569 newCookiejar = cookiejar.replace(cookieArray[i], name + "=" + value);570 cookiejar = newCookiejar;571 } else {572 window.document.cookie = name + "=" + value;573 newCookiejar = window.document.cookie;574 }575 }576 cb(null, newCookiejar);577 } else {578 cb(err);579 }580 });581 } else {582 cb(new Error(ERRORMSG.INVALID_COOKIE_VALUE + value));583 }584 },585 /**586 * delete a certain cookie in the cookie jar587 * @method deleteCookieInCookiejar588 * @param cookiejar - a existing cookiejar string589 * @param name - the cookie you want to delete590 * @param cb {Function}- a callback to return the error or modified cookie jar591 */592 deleteCookieInCookiejar: function (cookiejar, name, cb) {593 var self = this;594 if (!(Y.Lang.isString(cookiejar) && Y.Lang.isString(name) && Y.Lang.isFunction(cb))) {595 throw new Error(ERRORMSG.INVALID_PARAMETER + "\ncookiejar {String}, name {String}, cb {Function}");596 }597 self.getCookieInCookiejar(cookiejar, name, function (err, cookieArray) {598 if (!err) {599 for (var i = 0; i < cookieArray.length; i++) {600 var cookieString = cookieArray[i];601 if (self._isServer()) {602 cookiejar = cookiejar.trim();603 var newCookiejar = cookiejar.replace(cookieString, "");604 newCookiejar = newCookiejar.trim();605 var n = newCookiejar.search(";");606 if (n === 0) {607 //delete the first cookie608 cookiejar = newCookiejar.slice(1, newCookiejar.length);609 } else if (newCookiejar.slice(newCookiejar.length - 1, newCookiejar.length) === ";") {610 //delete the last cookie611 cookiejar = newCookiejar.slice(0, newCookiejar.length - 1);612 } else {613 cookiejar = cookiejar.replace(cookieString + ";", "");614 }615 } else {616 //delete the cookie in the cookiejar617 var expireDate = new Date(0);618 window.document.cookie = name + "=;expires=" + expireDate;619 cookiejar = window.document.cookie;620 }621 }622 cb(null, cookiejar);623 } else {624 cb(new Error(ERRORMSG.NONEXISTING_COOKIE + name), cookiejar);625 }626 });627 },628 /**629 * extract the whole cookie from the cookiejar630 * @method getCookieInCookiejar631 * @param cookiejar - a cookie jar632 * @param name - a cookie name633 * @param cb {Function}- a callback to return the error and extracted cookie string634 */635 getCookieInCookiejar: function (cookiejar, name, cb) {636 var self = this;637 if (!(Y.Lang.isString(cookiejar) && Y.Lang.isString(name) && Y.Lang.isFunction(cb))) {638 throw new Error(ERRORMSG.INVALID_PARAMETER + "\ncookiejar {String}, name {String}, cb {Function}");639 }640 //check whether the cookie has existed in the cookiejar641 var patt = new RegExp("^" + name + "="), one, cookieArray = cookiejar.split(";"), matchedCookie = [];642 for (var i = 0; i < cookieArray.length; i++) {643 one = cookieArray[i].trim();644 if (one.match(patt)) {645 matchedCookie.push(one);646 }647 }648 if (matchedCookie.length > 0) {649 cb(null, matchedCookie);650 } else {651 cb(new Error(ERRORMSG.NONEXISTING_COOKIE + name));652 }653 },654 /**655 * Get cookies from "set-cookie" fields in response headers and return the cookies object with key-value pair.656 * e.g. for cookie 'set-cookie: X=v=1&n=hhhhress; path=/; domain=.domain.com'657 * to get X cookie: cookies["X"] , value is 'v=1&n=hhhhress', does not contain path, domain and other options658 *659 * @method getCookiesFromHeader660 * @example661 * var responseCookies;662 * YUI.io(url, {663 * method: 'POST',664 * headers: headers,665 * on: {666 * complete: function (id, response) {667 * responseCookies = cookieUtil.getCookiesFromHeader(response);668 * //get X cookie;669 * var Xcookie=responseCookies["X"];670 * }671 * }672 * });673 * @param response - response http response object after send request674 * @param cb {Function}- return cookies object with cookie name as key, cookie value as value.675 */676 getCookiesFromHeader: function (response, cb) {677 var cookies = {};678 if (Y.Lang.isUndefined(response) || response === null || !Y.Lang.isObject(response)) {679 cb(new Error(ERRORMSG.ILLEGAL_RESPONSE));680 } else {681 console.log('response headers is [' + response.getAllResponseHeaders() + "]");682 var key, value, headers = response.headers;683 for (key in headers) {684 if (headers.hasOwnProperty(key)) {685 value = headers[key];686 if (key.toLowerCase() === "set-cookie") {687 // parse cookies688 if (!Y.Lang.isArray(value)) {689 value = [value];690 }691 for (var j = 0; j < value.length; j++) {692 var one = value[j];693 // example: X=a=1&m=xxes33; path=/; domain=.xx.com694 var cookieValue = one.split(";")[0], i = cookieValue.indexOf("=");695 if (i !== -1) {696 var v = cookieValue.slice(i + 1);697 cookies[cookieValue.slice(0, i)] = v;698 } else {699 console.log("invalid cookie: " + one, "warn");700 }701 }702 }703 }704 }705 if (Y.Object.isEmpty(cookies)) {706 cb(new Error(ERRORMSG.NO_COOKIE_FROM_SERVER));707 } else {708 cb(null, cookies);709 }710 }711 },712 /**713 * set cookiejar to http request header, e.g. set "AO=o=1&s=1&dnt=1; X=fa683mt88i5me&b=xxx" to header.714 * after set cookiejar to header, there is 'Cookie' header in request headers, e.g.715 * " Cookie: AO=o=1&s=1&dnt=1; X=fa683mt88i5me&b=xxx ".716 *717 * this is different for client and server side718 * for client: set cookiejar to window.document.cookie, then browser will send the cookie in header719 * for server: set cookiejar to 'Cookie' header in http request.720 * @method setCookiejarToHeader721 * @param cookiejar - a cookiejar string which can set to http header directly.e.g. AO=o=1&s=1&dnt=1; X=fa683mt88i5me&b=xxx722 * @param headers current headers object, required if send the http request from nodejs723 * @example724 * YUI.io(url, {725 * method: 'POST',726 * headers: headers,727 * on: {728 * complete: function(id, response) {729 * // validate response730 * }731 * }732 * }733 *734 * @param cb {Function}735 */736 setCookiejarToHeader: function (cookiejar, headers, cb) {737 if (Y.Lang.isUndefined(cookiejar) || cookiejar === null || cookiejar.length === 0) {738 console.log("cookiejar is undefined, did not set cookie to header");739 cb(new Error(ERRORMSG.INVALID_COOKIEJAR));740 } else if (!this._isServer()) {741 // if this is client side742 window.document.cookie = cookiejar;743 cb(null);744 } else {745 // if this is not server side746 if (Y.Lang.isUndefined(headers)) {747 console.log("headers is undefined");748 cb(new Error(ERRORMSG.UNDEFINED_HEADER));749 } else {750 headers.Cookie = cookiejar;751 cb(null, headers);752 }753 }754 },755 /**756 * Both cookie name and value should not contain any semi-colon, comma or white space characters.757 * this method creates invalid format cookie by adding semi-colon, comma or white space characters in the cookie name and value,758 * @method generateInvalidFormatCookie759 * @param cookiejar - valid format cookiejar which does not contain semi-colon, comma or white space760 * e.g. 'X=bnas=0; H=1; K=a=nJN0&b=Jhio'761 * @param cb {Function}- return invalidCookiejar invalid format cookiejar which contains semi-colon, comma or whitespace762 * e.g. 'X,=bnas=0; H=1; K=a=nJN0&b=Jhio; '763 */764 generateInvalidFormatCookie: function (cookiejar, cb) {765 var semiColon = this._getSemicolon(), comma = this._getComma(), space = this._getSpace();766 if (!Y.Lang.isUndefined(cookiejar) && Y.Lang.isString(cookiejar)) {767 cookiejar = semiColon + cookiejar + comma + space;768 cb(null, cookiejar);769 } else {770 cb(new Error(ERRORMSG.INVALID_COOKIEJAR));771 }772 },773 /**774 * @method parseCookiesObjToCookiejar775 * parse cookies object to cookiejar776 * @param cookiesObj - a object including cookies from "set-cookie" in http response header with key-value pair only , does not contain info about path, domain, expire etc.,777 * , e.g. cookies["X"]="k=1&H=ab3"778 * @param cb {Function}- return cookiejar, a String which can be used in http request 'Cookie' header and send out.779 */780 parseCookiesObjToCookiejar: function (cookiesObj, cb) {781 var separator = this._getSeparator(), equalChar = this._getEqualChar(), cookiejar, self = this;782 if (Y.Lang.isUndefined(cookiesObj) || !Y.Lang.isObject(cookiesObj) || Y.Object.isEmpty(cookiesObj)) {783 cb(new Error(ERRORMSG.WRONG_PARAMETER_COOKIES_OBJECT));784 } else {785 var error = false, key, value;786 for (key in cookiesObj) {787 if (cookiesObj.hasOwnProperty(key)) {788 value = cookiesObj[key];789 if (self._validateCookieName(key) && self._validateCookieSpec(value)) {790 cookiejar = cookiejar + key + equalChar + value + separator;791 } else {792 error = true;793 }794 }795 }796 if (error) {797 cb(new Error(ERRORMSG.INVALID_COOKIE_VALUE));798 } else {799 cookiejar = cookiejar.slice(0, cookiejar.length - separator.length);800 cb(null, cookiejar);801 }802 }803 }804 });805 Y.Arrow.CookieUtil = CookieUtil;...

Full Screen

Full Screen

loginjobs.js

Source:loginjobs.js Github

copy

Full Screen

1var request = require("request");2var captchaUtil = require('./captchautil.js');3var RSAKey = require('./rsa.js');4var logutil = require("../logutil").config('lulogin');5var simplehttp = require('../simplehttp');6var htmlparser = require('../htmlparser');7var mobileheaderutil = require("./mobileheaderutil");8var loginLock = false;9exports.login = login;10function login(account, callback) {11 if (loginLock) {12 logutil.warn("Login is locking", account.user)13 callback(null);14 } else {15 loginLock = true;16 login_mobile(account, function(cookie, info){17 loginLock = false;18 callback(cookie, info);19 });20 21 }22}23function login_mobile(account, callback) {24 var publicKey, rsaExponent;25 var rsakey = new RSAKey();26 securityValid(function (pkey, exp) {27 if (!pkey) {28 callback(null);29 return;30 }31 publicKey = pkey;32 rsaExponent = exp;33 rsakey.setPublic(publicKey, rsaExponent);34 account.rsakey = rsakey;35 var cookieJar = request.jar();36 var cncryptPassword = rsakey.encrypt(account.password);37 //{"userNameLogin":"coolinker","password":"8139CA3D93FAA7D50498E37642EED8D106C486771DC220E22AE63BDF3545A394DD440790B33EA5DF30213940AED9EDC710EC05C7D70352FF9E45BABAF25EFFBC1A111BEBEFCD3632DFD2D47E9B2E300DD3BCCD621D15B2CBB4B27596C0A558913DBC822B0C2FBBE46B27563D47C52CEDEED743E9A6ED348B2951DFCBBA5BD5CB",38 //"validNum":"","IMVC":"","mobileSerial":"868191022314031"}39 //{"userNameLogin":"luhuiqing","password":"0A63B5746D1E545C76D9F39F2189D6FF7EA32FB9EA9CAF2A7D044B28B4B134301844088971AD36FDFF328E17E6008E4B4505AE8AD89E2D1065438661C94C8024E1D8D42C3FA8FDE600082180BE639655CFFCF759F916EC97B33E2A9962BBF634AAAD40F248B39DEC112686A9365659190CE4DD172D9EA6AD152C008C76F9FA32","validNum":"kwp7","IMVC":"","mobileSerial":"868191022314031"}40 captchaUtil.guessCaptchaForLogin("login", cookieJar, function (captachStr) {41 // var t = new Date().getTime() - 2345;42 // var sig = mobilesigutil.genSig(null, t);43 simplehttp.POST('https://ma.lu.com/mapp/service/public?M8001', {44 "cookieJar": cookieJar,45 form: {46 requestCode: "M8001",47 version: "3.4.9",48 params: '{"userNameLogin":"' + account.user + '","password":"' + cncryptPassword + '","validNum":"' + captachStr + '","IMVC":"","mobileSerial":"868191022314031"}'49 },50 headers: mobileheaderutil.getHeaders()51 // {52 // "mobile_agent": "appVersion:3.4.9,platform:android,osVersion:17,device:GT-P5210,resourceVersion:2.7.0,channel:H5",53 // "X-LUFAX-MOBILE-DATA-AGENT": "qFgr54W0EdddXNHAEiURy9j3gNNZl1XtNIyKJrjynMS6LEhmOA1dqIM9+BhHucXUY1FcS/OK5No62MHrRqwHcm/lXEhbeygM8rp8Zevk9E2Ze7+1z3geqdnEDfAGN/eKFrgIzRQIR5jItWwVv8UZ6w==",54 // "x-lufax-mobile-t": t,55 // "x-lufax-mobile-signature": sig56 // }57 },58 function (err, httpResponse, body) {59 var cookie_string = cookieJar.getCookieString("https://user.lu.com");60 logutil.info("login status:", cookie_string.indexOf("lufaxSID") > 0, account.user);61 if (cookie_string.indexOf("lufaxSID") < 0) {62 callback(null);63 } else {64 var info = JSON.parse(body);65 account.cookieJar = cookieJar;66 account.uid = info.result.userOverview.userId;67 account.loginTime = new Date();68 userInfo_mobile(account, function (result) {69 //account.uid = result.userInfo.userName;70 // if (result.asset) {71 // account.availableBalance = Number(result.asset.availableAmount.text);72 // account.allIncomeAmount = Number(result.asset.allIncomeAmount.text);73 // account.ongoingTotalBuyBackAmount = Number(result.ongoingTotalBuyBackAmount);74 // account.totalAssets = account.allIncomeAmount + account.ongoingTotalBuyBackAmount/9;75 // }76 // logutil.info("account.availableBalance:", account.availableBalance, account.uid, account.totalAssets);77 callback(cookieJar, account.JSONInfo());78 });79 }80 });81 });82 });83}84function userInfo_mobile(account, callback) {85 simplehttp.POST('https://ma.lu.com/mapp/service/private?M6057', {86 "cookieJar": account.cookieJar,87 form: {88 requestCode: "M6057",89 version: "3.4.9",90 params: '{"ver":"1.0" , "source":"android"}'91 },92 headers: mobileheaderutil.getHeaders(account.uid)93 },94 function (err, httpResponse, body) {95 try {96 var info = JSON.parse(body);97 if (info.code !== '0000') console.log("Error userInfo_mobile:", body);98 var result = info.result;99 if (!result) {100 console.log("ERROR: userInfo_mobile", body);101 callback(null)102 return;103 }104 totalBuyBack_mobile(account, function (buyback, items) {105 if (buyback === null) {106 callback(null);107 return;108 }109 var today = new Date();110 var todayrepay = 0;111 items.forEach(function (item) {112 var day = new Date(item.systemBuyBackDate);113 if (day.getDate() === today.getDate() && day - today < 24 * 60 * 60 * 1000) {114 todayrepay += Number(item.buyBackAmount);115 }116 })117 result.ongoingTotalBuyBackAmount = Number(buyback);118 result.ongoingTodayBuyBackAmount = Number(todayrepay);119 if (result.asset) {120 account.availableBalance = Number(result.asset.availableAmount.text);121 account.allIncomeAmount = Number(result.asset.allIncomeAmount.text);122 account.ongoingTodayBuyBackAmount = result.ongoingTodayBuyBackAmount;123 account.totalAssets = Math.round(account.allIncomeAmount + result.ongoingTotalBuyBackAmount / 9);124 }125 logutil.info("account.availableBalance:", account.availableBalance, "ongoingTodayBuyBackAmount:", account.ongoingTodayBuyBackAmount, 126 "uid:", account.uid, "totalAssets:", account.totalAssets, "buyback:", buyback, "leverage:", account.capability.leverage);127 callback(result);128 })129 } catch (e) {130 console.log("ERROR: userInfo_mobile", e.stack, body);131 callback(null);132 }133 });134}135function login_brwoser(account, callback) {136 var user = account.user;137 var password = account.password;138 // var cncryptPassword = encrypt(password, publicKey);139 var cookieJar = request.jar();140 var rsakey = new RSAKey();141 //logutil.info("login...", user);142 simplehttp.GET('https://user.lu.com/user/login', {143 "cookieJar": cookieJar144 },145 function (err, httpResponse, body) {146 var publicKey = htmlparser.getValueFromBody('id="publicKey" name="publicKey" value="', '" />', body);147 var rsaExponent = htmlparser.getValueFromBody('id="rsaExponent" name="rsaExponent" value="', '" />', body);148 rsakey.setPublic(publicKey, rsaExponent);149 var cncryptPassword = rsakey.encrypt(password);150 captchaUtil.guessCaptchaForLogin("login", cookieJar, function (captachStr) {151 doLogin(user, cncryptPassword, captachStr, cookieJar, function (info) {152 if (info.uid) {153 account.cookieJar = cookieJar;154 account.availableBalance = info.availableFund;155 account.uid = info.uid;156 account.loginTime = new Date();157 callback(cookieJar, account.JSONInfo());158 } else {159 account.cookieJar = null;160 callback(null, info);161 }162 // logutil.info("account.availableBalance:", account.availableBalance, account.uid, info)163 })164 })165 });166}167function captchaAuthorize(source, username, cookieJar, callback) {168 simplehttp.POST('https://user.lu.com/user/service/login/captcha-authorize', {169 form: {170 source: source,171 username: username172 },173 "cookieJar": cookieJar174 },175 function (err, httpResponse, body) {176 callback(body)177 })178}179function doLogin(userNameLogin, cncryptPassword, captcha, cookieJar, callback) {180 simplehttp.POST('https://user.lu.com/user/login', {181 form: {182 userName: userNameLogin,183 password: cncryptPassword,184 validNum: captcha,185 loginagree: "on",186 isTrust: "Y"187 },188 "cookieJar": cookieJar189 },190 function (err, httpResponse, body) {191 var cookie_string = cookieJar.getCookieString("https://user.lu.com");192 logutil.info("doLogin -> login status:", cookie_string.indexOf("lufaxSID") > 0, userNameLogin, body);193 if (cookie_string.indexOf("lufaxSID") < 0) {194 callback(JSON.parse(body));195 } else {196 getUserInfo(cookieJar, callback);197 }198 });199}200function getUserInfo(cookieJar, callback) {201 getUserId(cookieJar, function (info) {202 getFundInfo(cookieJar, info.uid, function (json) {203 for (var att in json) {204 info[att] = json[att];205 }206 callback(info);207 })208 });209}210function getFundInfo(cookieJar, uid, callback) {211 simplehttp.GET('https://cashier.lu.com/cashier/service/users/' + uid + '/account-system/overview', {212 "cookieJar": cookieJar213 },214 function (err, httpResponse, body) {215 var info = JSON.parse(body);216 if (!info) logutil.error("ERROR getFundInfo:", body)217 callback(info);218 });219}220function getUserId(cookieJar, callback) {221 simplehttp.GET('https://user.lu.com/user/service/user/current-user-info-for-homepage', {222 "cookieJar": cookieJar223 },224 function (err, httpResponse, body) {225 var info = JSON.parse(body);226 // logutil.info("---------", info) 18270.60227 if (!info) logutil.error("ERROR getUserId:", body)228 callback(info);229 });230}231exports.extendLogin = extendLogin;232function extendLogin(account, callback) {233 if (new Date() - account.loginTime > 25 * 60 * 1000) {234 login(account, function (cookieJar, info) {235 logutil.info("extendLogin======", account.user, account.source);236 account.loginExtendedTime = new Date();237 callback(cookieJar);238 });239 } else {240 userInfo_mobile(account, function (result) {241 if (result) {242 account.loginExtendedTime = new Date();243 callback(account.cookieJar)244 } else {245 login(account, function (cookieJar, info) {246 logutil.info("extendLogin======1", account.user, account.source);247 account.loginExtendedTime = new Date();248 callback(cookieJar);249 });250 }251 });252 }253}254function securityValid(callback) {255 simplehttp.GET('https://static.lufaxcdn.com/trading/resource/securityValid/main/1be866c2e005.securityValid.js', {},256 function (err, httpResponse, body) {257 try {258 var publicKey = htmlparser.getValueFromBody('encryptPwd:function(e){var t="', '",n=', body);259 var rsaExponent = htmlparser.getValueFromBody('n.setPublic(t,"', '"),n.', body);260 callback(publicKey, rsaExponent);261 } catch (e) {262 console.log("************", err, e.stack)263 callback(null);264 }265 });266}267function totalBuyBack_mobile(account, callback, pageNum) {268 if (!pageNum) pageNum = 1;269 simplehttp.POST("https://ma.lu.com/mapp/service/private?M3205", {270 "cookieJar": account.cookieJar,271 "headers": mobileheaderutil.getHeaders(account.uid),272 form: {273 requestCode: "M3205",274 version: "3.4.9",275 //{"sortType":"desc","requestType":"APPLY","assetType":"FINANCE","filter":"","pageNum":"1"}276 params: '{"type":"list","page":' + pageNum + '}'277 }278 },279 function (err, httpResponse, body) {280 try {281 if (err) {282 console.log("Error ************* totalBuyBack_mobile", err)283 callback(null);284 return;285 }286 var result = JSON.parse(body).result;287 if (!result) {288 console.log("Error ************* totalBuyBack_mobile", pageNum, body)289 callback(null);290 return;291 }292 var buyback = Number(result.ongoingTotalBuyBackAmount);293 if (pageNum < Number(result.totalPage)) {294 //console.log("totalBuyBack_mobile:", result.totalPage)295 totalBuyBack_mobile(account, function (bb, applys) {296 297 if (bb === null || applys.length === 0 && bb === 0) bb = buyback;298 if (!applys) {299 applys = [];300 console.log("ERROR: ****************************applys = undefined", bb, result.mappList)301 }302 callback(bb, applys.concat(result.mappList));303 }, pageNum + 1)304 } else {305 callback(buyback, result.mappList);306 }307 } catch (e) {308 console.error("getRecentApply exception:", new Date().toTimeString(), pageNum, err, e.stack);309 totalBuyBack_mobile(account, callback); 310 }311 });...

Full Screen

Full Screen

CookieJar.d.ts

Source:CookieJar.d.ts Github

copy

Full Screen

1/// <reference types="node" />2export = CookieJar;3declare class CookieJar {4 /**5 * Creates an instance of CookieJar.6 * @memberof CookieJar7 */8 constructor(...args: any[]);9 /**10 * @type {CookieJar.Cookie[]}11 */12 cookies: (typeof Cookie)[];13 /**14 * Adds cookie to the Jar15 * @param {string | CookieJar.Cookie | http.ServerResponse | http.IncomingMessage | fetch.Response} cookie Cookie name (requires second parameter), Cookie String, CookieJar.Cookie object, ServerResponseLike object16 * @param {string} [value=undefined]17 * @param {Object<string, any>} [options={}]18 * @return {CookieJar}19 * @memberof CookieJar20 */21 setCookie(cookie: string | typeof Cookie | http.ServerResponse | http.IncomingMessage | fetch.Response, value?: string, options?: {22 [x: string]: any;23 }): CookieJar;24 /**25 * Retrns cookie object found by name26 * @param {string} name Cookie name27 * @return {CookieJar.Cookie} Cookie object if found, otherwise undefined28 * @memberof CookieJar29 */30 getCookie(name: string): typeof Cookie;31 /**32 * Removes cookie from the Jar33 * @param {string | CookieJar.Cookie} cookie34 * @return {CookieJar.Cookie} Deleted cookie35 * @memberof CookieJar36 */37 deleteCookie(cookie: string | typeof Cookie): typeof Cookie;38 /**39 * Sends header with cookies40 * @param {http.ServerResponse} response Server response object41 * @param {boolean} [full=true] Include cookie properties and flags42 * @return {CookieJar}43 * @memberof CookieJar44 */45 sendCookies(response: http.ServerResponse, full?: boolean): CookieJar;46 /**47 * Converts Cookie object to cookie string48 * @param {boolean} [full=true] Include cookie properties and flags49 * @return {string} Cookie String50 * @memberof CookieJar51 */52 toString(full?: boolean): string;53 /**54 * Checks if the Jar is empty55 * @return {boolean} true if Jar is empty, otherwise false56 * @memberof CookieJar57 */58 isEmpty(): boolean;59 /**60 * Checks if the Jar contains cookie with certain name61 * @param {string} name Cookie name62 * @return {boolean} true if Jar contians cookie with certain name, otherwise false63 * @memberof CookieJar64 */65 includes(name: string): boolean;66 /**67 * Adds cookies to the Jar68 * @param {CookieJar.Cookie[]} cookies69 * @memberof CookieJar70 */71 _addCookiesToJar(...cookies: (typeof Cookie)[]): void;72 /**73 * Removes expired cookies from the Jar74 * @memberof CookieJar75 */76 _removeExpiredCookies(): void;77}78declare namespace CookieJar {79 export { Cookie };80}81declare class Cookie {82 static keywords: string[];83 static formatKeyword(key: any): string | false;84 static parse(cookieStringArray: any): any;85 name: string;86 value: string;87 /**88 * @type {CookieProperties}89 */90 props: {91 /**92 * The maximum lifetime of the cookie as an HTTP-date timestamp.93 */94 Expires?: string;95 /**96 * Number of seconds until the cookie expires. A zero or negative number will expire the cookie immediately.97 */98 "Max-Age"?: string;99 /**100 * Host to which the cookie will be sent.101 */102 Domain?: string;103 /**104 * A path that must exist in the requested URL, or the browser won't send the `Cookie` header.105 */106 Path?: string;107 /**108 * Controls whether a cookie is sent with cross-origin requests, providing some protection against cross-site request forgery attacks (CSRF).109 */110 SameSite?: string;111 };112 /**113 * @type {Array<"Secure" | "HttpOnly">}114 */115 flags: Array<"Secure" | "HttpOnly">;116 /**117 * Convert cookie to cookie string118 * @override119 * @param {boolean} [full=true] Include cookie properties and flags120 * @return {string} Cookie String121 */122 override toString(full?: boolean): string;123}...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1var Apickli = require('apickli');2var apickli = new Apickli.Apickli('http', 'httpbin.org');3var cookieJar = apickli.getCookieJar();4console.log(cookie);5apickli.get('/cookies', function (error, response) {6 if (error) {7 console.log(error);8 } else {9 console.log(response);10 }11});12apickli=apickli; Path=/13{ request:14 { 'User-Agent': 'Apickli/0.0.1',15 Accept: 'application/json' } },16 { statusCode: 200,17 '{\r18"cookies": {\r19}\r20}\r21 { server: 'nginx',22 via: '1.1 vegur' },23 { uri: [Object],24 body: undefined },25 bodyAsJson: { cookies: [Object] } } }

Full Screen

Using AI Code Generation

copy

Full Screen

1var apickli = require('apickli');2var {Before, After} = require('cucumber');3var request = require('request');4var cookieJar = request.jar();5Before(function () {6 this.apickli = new apickli.Apickli('https', 'test.apigee.net');7 this.apickli.storeValueInScenarioScope('cookieJar', cookieJar);8});9After(function () {10});11var apickli = require('apickli');12var {defineSupportCode} = require('cucumber');13defineSupportCode(function ({Given, Then, When, Before, After}) {14 Given('I set cookie {string} to {string}', function (cookieName, cookieValue, callback) {15 var cookieJar = this.apickli.getScenarioVariable('cookieJar');16 var cookie = request.cookie(cookieName + '=' + cookieValue);17 var url = this.apickli.getDomain() + this.apickli.getHttpPath();18 cookieJar.setCookie(cookie, url);19 callback();20 });21});22 <Condition>(proxy.pathsuffix MatchesPath "/setcookie")</Condition>

Full Screen

Using AI Code Generation

copy

Full Screen

1this.apickli.setCookieJar();2this.apickli.setCookie("myCookie","myValue");3this.apickli.getCookie("myCookie");4this.apickli.deleteCookie("myCookie");5var apickli = require('apickli');6var {defineSupportCode} = require('cucumber');7defineSupportCode(function({Given, When, Then}) {8 this.apickli = new apickli.Apickli('http', 'localhost:3000');9 this.apickli.addRequestHeader('Content-Type', 'application/json');10 this.apickli.addRequestHeader('Accept', 'application/json');11 Given(/^I set cookie jar$/, function(callback) {12 this.apickli.setCookieJar();13 callback();14 });15 Given(/^I set cookie "([^"]*)" to "([^"]*)"$/, function(cookieName, cookieValue, callback) {16 this.apickli.setCookie(cookieName, cookieValue);17 callback();18 });19 Given(/^I get cookie "([^"]*)"$/, function(cookieName, callback) {20 this.apickli.getCookie(cookieName);21 callback();22 });23 Given(/^I delete cookie "([^"]*)"$/, function(cookieName, callback) {24 this.apickli.deleteCookie(cookieName);25 callback();26 });27 Given(/^I login to the application$/, function(callback) {28 this.apickli.post('/login', '{"username":"admin","password":"admin"}', callback);29 });30 Given(/^I check the cookie$/, function(callback) {31 var cookieValue = this.apickli.getCookie("myCookie");32 if (cookie

Full Screen

Automation Testing Tutorials

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.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run apickli automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful