Best JavaScript code snippet using playwright-internal
llsif_cardviewer.js
Source: llsif_cardviewer.js
...422}423424/* toMemberName425====================================================================== */426function toMemberName(card, shortname) {427 if(!members_data) return '';428429 var mem_data = members_data.members.find(function(elem) { return elem.u == card.u; });430 if(!mem_data) return '';431 return shortname ? mem_data.s : mem_data.n;432}433434/* toSkillType435====================================================================== */436function toSkillType(card) {437 if(!card) return 'ç¡ã';438 if(Object.values(SKILL).indexOf(card.y) == -1) return 'ç¡ã';439 return SKILL_NAME[String(card.y)];440}441442/* toSkillDesc443====================================================================== */444function toSkillDesc(card, skill_level) {445 if(!card) return '';446 if(card.y == 0) return 'ç¡ã';447 if(skill_level == 'max') skill_level = card.k.length;448 if(skill_level > card.k.length || skill_level < 1) return '';449450 var sk = card.k[skill_level - 1];451452 var sk_target = '';453 if(card.e != 0) {454 switch(card.e[0]) {455 case EFFECT_TARGET.SUBUNIT:456 if(Object.values(SUBUNIT).indexOf(card.e[1]) != -1) sk_target = SUBUNIT_NAME[String(card.e[1])]; break;457 case EFFECT_TARGET.GROUPGRADE:458 if(Object.values(GROUP).indexOf(card.e[1]) != -1) sk_target = GROUP_NAME[String(card.e[1])] + card.e[2] + 'å¹´ç';459 break;460 }461 }462463 var sk_trigger = '', sk_chance = sk.r + '%ã®ç¢ºçã§';464 switch(card.t) {465 case TRIGGER.TIMER: sk_trigger = sk.t + 'ç§ãã¨ã«'; break;466 case TRIGGER.ICON: sk_trigger = 'ãªãºã ã¢ã¤ã³ã³' + sk.t + 'åãã¨ã«'; break;467 case TRIGGER.COMBO: sk_trigger = 'ã³ã³ã' + sk.t + 'ãéæãããã¨ã«'; break;468 case TRIGGER.SCORE: sk_trigger = 'ã¹ã³ã¢' + sk.t + 'éæãã¨ã«'; break;469 case TRIGGER.PERFECT: sk_trigger = 'PERFECTã' + sk.t + 'åéæãããã¨ã«'; break;470 case TRIGGER.STARICON: sk_trigger = 'ã¹ã¿ã¼ã¢ã¤ã³ã³PERFECT' + sk.t + 'åãã¨ã«'; break;471 case TRIGGER.CHAIN: sk_trigger = 'èªèº«ãé¤ã' + sk_target + 'ã®ç¹æããã¹ã¦çºåããã¨'; break;472 default: return '';473 }474475 var skill_desc;476 switch(card.y) {477 case SKILL.TIMINGBOOST_S:478 skill_desc = sk_trigger + sk_chance + 'å¤å®ã' + sk.s + 'ç§éå°ãå¼·åããã'; break;479 case SKILL.TIMINGBOOST_L:480 skill_desc = sk_trigger + sk_chance + 'å¤å®ã' + sk.s + 'ç§éå¼·åããã'; break;481 case SKILL.RECOVERY:482 skill_desc = sk_trigger + sk_chance + 'ä½åã' + sk.v + 'å復ãã'; break;483 case SKILL.SCOREUP:484 skill_desc = sk_trigger + sk_chance + 'ã¹ã³ã¢ã' + sk.v + 'å¢ãã'; break;485 case SKILL.SKILLCHANCE:486 skill_desc = sk_trigger + sk_chance + sk.s + 'ç§éä»ã®ç¹æã®çºå確çã' + sk.v + 'åã«ãªã'; break;487 case SKILL.SKILLREPEAT:488 skill_desc = sk_trigger + sk_chance + 'ç´åã«çºåããç¹æãªãã¼ã以å¤ã®ç¹æå¹æãçºåãã'; break;489 case SKILL.PERFECTUP:490 skill_desc = sk_trigger + sk_chance + sk.s + 'ç§éPERFECTæã®ã¿ããSCOREã' + sk.v + 'å¢ãã'; break;491 case SKILL.COMBOFEVER:492 skill_desc = sk_trigger + sk_chance + sk.s + 'ç§éã³ã³ãæ°ã«å¿ãã¦ã¿ããSCOREãå¢ãã(' + sk.v + 'ï½' + (sk.v * 10) + 'ã®éã§å¤å)'; break;493 case SKILL.PARAMSYNC:494 skill_desc = sk_trigger + sk_chance + sk.s + 'ç§é' + sk_target + 'ã®ããããã¨åãå±æ§Pã«ãªã'; break;495 case SKILL.SKILLBOOST:496 skill_desc = sk_trigger + sk_chance + '次ã«çºåããç¹æã®Lvã' + sk.v + 'ã¢ãããã'; break;497 case SKILL.PARAMUP:498 skill_desc = sk_trigger + sk_chance + sk.s + 'ç§é' + sk_target + 'ã®å±æ§Pã' + sk.v + '%UPãã'; break;499 default: return 'ç¡ã';500 }501502 if(card.hasOwnProperty('li')) { if(card.li > 0) skill_desc += '(æ大' + card.li + 'åã¾ã§)'; }503 return skill_desc;504}505506/* toCenterSkillName507====================================================================== */508function toCenterSkillName(card) {509 return '';510}511512513/* toCenterSkillDesc514====================================================================== */515function toCenterSkillDesc(card) {516 var cs_desc, e_attr;517518 if(!members_data) return '';519 if(!card) return 'ç¡ã';520 if(card.l == 0) return 'ç¡ã';521 switch(card.l.t) {522 case LEADER_SKILL.SMILE:523 e_attr = ATTR_NAME[ATTR.SMILE]; cs_desc = 'ã¹ãã¤ã«Pã' + card.l.v + '%UPãã'; break;524 case LEADER_SKILL.PURE:525 e_attr = ATTR_NAME[ATTR.PURE]; cs_desc = 'ãã¥ã¢Pã' + card.l.v + '%UPãã'; break;526 case LEADER_SKILL.COOL:527 e_attr = ATTR_NAME[ATTR.COOL]; cs_desc = 'ã¯ã¼ã«Pã' + card.l.v + '%UPãã'; break;528 case LEADER_SKILL.PUREPRINCESS:529 e_attr = ATTR_NAME[ATTR.PURE]; cs_desc = 'ã¹ãã¤ã«Pã®' + card.l.v + '%åãã¥ã¢PãUPãã'; break;530 case LEADER_SKILL.COOLPRINCESS:531 e_attr = ATTR_NAME[ATTR.COOL]; cs_desc = 'ã¹ãã¤ã«Pã®' + card.l.v + '%åã¯ã¼ã«PãUPãã'; break;532 case LEADER_SKILL.SMILEANGEL:533 e_attr = ATTR_NAME[ATTR.SMILE]; cs_desc = 'ãã¥ã¢Pã®' + card.l.v + '%åã¹ãã¤ã«PãUPãã'; break;534 case LEADER_SKILL.COOLANGEL:535 e_attr = ATTR_NAME[ATTR.COOL]; cs_desc = 'ãã¥ã¢Pã®' + card.l.v + '%åã¯ã¼ã«PãUPãã'; break;536 case LEADER_SKILL.SMILEEMPRESS:537 e_attr = ATTR_NAME[ATTR.SMILE]; cs_desc = 'ã¯ã¼ã«Pã®' + card.l.v + '%åã¹ãã¤ã«PãUPãã'; break;538 case LEADER_SKILL.PUREEMPRESS:539 e_attr = ATTR_NAME[ATTR.PURE]; cs_desc = 'ã¯ã¼ã«Pã®' + card.l.v + '%åãã¥ã¢PãUPãã'; break;540 }541542 var cs_desc_ex = '';543 switch(card.l.e) {544 case EFFECT_TARGET.GROUP:545 cs_desc_ex = GROUP_NAME[card.l.a]; break;546 case EFFECT_TARGET.GRADE:547 cs_desc_ex = card.l.a + 'å¹´ç'; break;548 case EFFECT_TARGET.SUBUNIT:549 cs_desc_ex = SUBUNIT_NAME[card.l.a]; break;550 case EFFECT_TARGET.MEMBER:551 var mem_data1 = members_data.members.find(function(elem) { return elem.u == card.l.a; });552 var mem_data2 = members_data.members.find(function(elem) { return elem.u == card.l.b; });553 cs_desc_ex = mem_data1.s;554 if(card.l.b != 0) cs_desc_ex += 'ã' + mem_data2.s;555 break;556 }557 if(cs_desc_ex != '') cs_desc_ex = 'ï¼' + cs_desc_ex + 'ã®ã¡ã³ãã¼ã¯ããã«' + e_attr + 'Pã' + card.l.x + '%UPãã';558559 return cs_desc + cs_desc_ex;560}561562563564/* ----------------------------------------------------------------------565* Card Detail566---------------------------------------------------------------------- */567568/* getCardParameter569====================================================================== */570function getCardParameter(card, level, bond) {571 var diff = param_diff.pattern.find(function(elem) { return elem.i == card.v; });572 diff = diff.p.find(function(elem) { return elem.l == level; });573574 var param = new Object;575 param.life = card.h + diff.h;576 param.smile = card.s + diff.s; param.pure = card.p + diff.p; param.cool = card.c + diff.c;577 switch(card.a) {578 case ATTR.SMILE: param.smile += bond; break;579 case ATTR.PURE: param.pure += bond; break;580 case ATTR.COOL: param.cool += bond; break;581 }582 return param;583}584585586/* showCardDetail587====================================================================== */588function showCardDetail(card, deckmem, getparam, update_func) {589 var detail_elem = document.createElement('div');590591 detail_elem.innerHTML = 592 '<div class="image_block">' +593 '<img id="data_cardimg" class="card_image" />' +594 '<div class="idolized_switch">' +595 '<div class="switch_button idolized">' +596 '<input type="radio" name="card_idolized" id="card_normal" value="normal" onchange="" />' +597 '<label for="card_normal">é常</label>' +598 '<input type="radio" name="card_idolized" id="card_idolized" value="idolized" onchange="" />' +599 '<label for="card_idolized">è¦é</label>' +600 '</div>' +601 '</div>' +602 '</div>' +603604 '<div class="detail_block">' +605 '<div class="detail_frame">' +606 '<div id="data_eponym" class="detail_title"></div>' +607 '<div id="data_member" class="card_detail text"></div>' +608 '</div>' +609610 '<div class="detail_frame">' +611 '<div class="card_detail nowrap">' +612 '<div class="detail_name">Lv</div>' +613 '<div class="detail_desc">' +614 '<div class="spin_box">' +615 '<button class="spindown_button"></button>' +616 '<input id="data_level" type="number" class="spin_value" min="1" readonly="readonly"/>' +617 '<button class="spinup_button"></button>' +618 '</div>' +619 '<div id="data_level_max" class="detail_text"></div>' +620 '<div class="min_max_button">' +621 '<button id="level_min" class="min_button"></button>' +622 '<button id="level_max" class="max_button"></button>' +623 '</div>' +624 '</div>' +625 '</div>' +626 '<div class="card_detail nowrap">' +627 '<div class="detail_name">çµ</div>' +628 '<div class="detail_desc">' +629 '<div class="spin_box">' +630 '<button class="spindown_button"></button>' +631 '<input id="data_bond" type="number" class="spin_value" min="0" readonly="readonly"/>' +632 '<button class="spinup_button"></button>' +633 '</div>' +634 '<div id="data_bond_max" class="detail_text"></div>' +635 '<div class="min_max_button">' +636 '<button id="bond_min" class="min_button"></button>' +637 '<button id="bond_max" class="max_button"></button>' +638 '</div>' +639 '</div>' +640 '</div>' +641 '<div class="card_detail nowrap">' +642 '<div class="param_life"><span id="data_life" class="param_num"></span></div>' +643 '<div class="param_smile"><span id="data_smile" class="param_num"></span></div>' +644 '<div class="param_pure"><span id="data_pure" class="param_num"></span></div>' +645 '<div class="param_cool"><span id="data_cool" class="param_num"></span></div>' +646 '</div>' +647 '</div>' +648649 '<div class="detail_frame">' +650 '<div class="card_detail nowrap">' +651 '<div class="detail_name">ç¹æ</div><div id="data_skilltype" class="detail_desc"></div>' +652 '</div>' +653 '<div class="card_detail nowrap">' +654 '<div class="detail_name">ç¹æå</div><div id="data_skillname" class="detail_desc"></div>' +655 '</div>' +656 '<div class="card_detail nowrap">' +657 '<div class="detail_name">ç¹æLv</div>' +658 '<div class="detail_desc">' +659 '<div class="spin_box">' +660 '<button class="spindown_button"></button>' +661 '<input id="data_skilllevel" type="number" class="spin_value" min="1" readonly="readonly"/>' +662 '<button class="spinup_button"></button>' +663 '</div>' +664 '<div id="data_skilllevel_max" class="detail_text"></div>' +665 '<div class="min_max_button">' +666 '<button id="skilllevel_min" class="min_button"></button>' +667 '<button id="skilllevel_max" class="max_button"></button>' +668 '</div>' +669 '</div>' +670 '</div>' +671 '<div class="card_detail nowrap">' +672 '<div class="detail_name">å¹æ</div><div id="data_skilldesc" class="detail_desc small"></div>' +673 '</div>' +674 '<div class="card_detail">' +675 '<div class="detail_name">ã»ã³ã¿ã¼ã¹ãã«</div><div id="data_centerskill" class="detail_desc small"></div>' +676 '</div>' +677 '<div class="card_detail nowrap">' +678 '<div class="detail_name">é¨å¡No.</div><div id="data_memberid" class="detail_desc small"></div>' +679 '</div>' +680 '</div>' +681 '</div>';682683684 if(deckmem == null) getparam = false;685 var diff = param_diff.pattern.find(function(elem) { return elem.i == card.v; });686 var level_max, level_maxup, bond_max; 687 if(getparam) {688 level_max = card.o || deckmem.i ? diff.a : diff.b;689 level_maxup = card.o || deckmem.i ? diff.p[diff.p.length - 1].l : diff.b;690 bond_max = card.o || deckmem.i ? diff.o : diff.l;691 } else {692 level_max = card.o ? diff.a : diff.b;693 level_maxup = card.o ? diff.p[diff.p.length - 1].l : diff.b;694 bond_max = card.o ? diff.o : diff.l;695 }696 const sklevel_max = card.k[card.k.length - 1].l;697 const level = getparam ? deckmem.lv : 1, bond = getparam ? deckmem.b : 0;698 var param = getCardParameter(card, level, bond);699700701 function change_cardidolized(radio) {702 if(!radio.checked) return;703 const new_idolized = radio.value == 'idolized';704 const get_level = parseFloat(document.getElementById('data_level').value);705 const get_bond = parseFloat(document.getElementById('data_bond').value);706 var new_levelmax = new_idolized ? diff.a : diff.b;707 const new_bondmax = new_idolized ? diff.o : diff.l;708709 document.getElementById('data_cardimg').src = toCardAssetPath(card, new_idolized);710 document.getElementById('data_level_max').textContent = '/' + new_levelmax;711 document.getElementById('data_bond_max').textContent = '/' + new_bondmax;712713 new_levelmax = new_idolized ? diff.p[diff.p.length - 1].l : diff.b;714 var input = document.getElementById('data_level');715 if(parseFloat(input.value) > new_levelmax) {716 input.value = new_levelmax; input.max = new_levelmax; change_maxvalue('data_level');717 }718 input.max = new_levelmax;719720 input = document.getElementById('data_bond');721 if(parseFloat(input.value) > new_bondmax) {722 input.value = new_bondmax; input.max = new_bondmax; ichange_maxvalue('data_bond');723 }724 input.max = new_bondmax;725 }726727 function change_card_param() {728 const new_level = parseFloat(document.getElementById('data_level').value);729 const new_bond = parseFloat(document.getElementById('data_bond').value);730 const new_param = getCardParameter(card, new_level, new_bond);731 document.getElementById('data_life').textContent = new_param.life;732 document.getElementById('data_smile').textContent = new_param.smile;733 document.getElementById('data_pure').textContent = new_param.pure;734 document.getElementById('data_cool').textContent = new_param.cool;735 }736737 function change_minvalue(elemid) {738 var input = document.getElementById(elemid); input.value = input.min; input.onchange();739 input.parentNode.querySelector('.spindown_button').disabled = true;740 input.parentNode.querySelector('.spinup_button').disabled = false;741 }742743 function change_maxvalue(elemid) {744 var input = document.getElementById(elemid); input.value = input.max; input.onchange();745 input.parentNode.querySelector('.spindown_button').disabled = false;746 input.parentNode.querySelector('.spinup_button').disabled = true;747 }748749 function change_maxlevel() {750 var input = document.getElementById('data_level');751 if(document.getElementById('card_idolized').checked) {752 input.value = parseFloat(input.value) >= diff.a ? input.max : diff.a;753 } else {754 input.value = input.max;755 }756 input.onchange();757 input.parentNode.querySelector('.spindown_button').disabled = false;758 input.parentNode.querySelector('.spinup_button').disabled = input.value == input.max;759 }760761 function change_maxskill() {762 var input = document.getElementById('data_skilllevel');763 input.value = parseFloat(input.value) >= MAX_SKILL ? input.max : MAX_SKILL;764 input.onchange();765 input.parentNode.querySelector('.spindown_button').disabled = false;766 input.parentNode.querySelector('.spinup_button').disabled = input.value == input.max;767 }768769 function update_deckmember() {770 if(deckmem == null) { closeDialog('card_detail_dlg'); return; }771772 const new_level = parseFloat(document.getElementById('data_level').value);773 const new_bond = parseFloat(document.getElementById('data_bond').value);774 const new_sklevel = parseFloat(document.getElementById('data_skilllevel').value);775 const new_idolized = getRadioValue('card_idolized') == 'idolized';776777 if(new_sklevel > MAX_SKILL) return;778779 deckmem.lv = new_level; deckmem.i = new_idolized; deckmem.b = new_bond; deckmem.sk = new_sklevel; 780 if(deckmem.id != card.i) { deckmem.id = card.i; deckmem.a_id = 0; deckmem.a_lv = 0; deckmem.sis = []; }781 closeDialog('card_detail_dlg'); update_func();782 }783784 detail_elem.querySelector('#card_normal').onchange = function() { change_cardidolized(this); }785 detail_elem.querySelector('#card_idolized').onchange = function() { change_cardidolized(this); }786787 detail_elem.querySelector('#data_level').onchange = function() { change_card_param(); }788 detail_elem.querySelector('#level_min').onclick = function() { change_minvalue('data_level'); }789 detail_elem.querySelector('#level_max').onclick = function() { change_maxlevel(); }790791 detail_elem.querySelector('#data_bond').onchange = function() { change_card_param(); }792 detail_elem.querySelector('#bond_min').onclick = function() { change_minvalue('data_bond'); }793 detail_elem.querySelector('#bond_max').onclick = function() { change_maxvalue('data_bond'); }794795 detail_elem.querySelector('#data_skilllevel').onchange = function() {796 document.getElementById('data_skilldesc').textContent = toSkillDesc(card, this.value);797 if(deckmem == null) return;798 var updatebtn = document.getElementById('card_detail_dlg').querySelector('footer > button.exec_button');799 updatebtn.disabled = parseFloat(document.getElementById('data_skilllevel').value) > MAX_SKILL800 }801 detail_elem.querySelector('#skilllevel_min').onclick = function() { change_minvalue('data_skilllevel'); }802 detail_elem.querySelector('#skilllevel_max').onclick = function() { change_maxskill(); }803804805 detail_elem.querySelector('#data_cardimg').src = toCardAssetPath(card, getparam ? deckmem.i : false);806 if(card.o) detail_elem.querySelector('#card_normal').disabled = true;807 if(card.o || (getparam ? deckmem.i : false)) {808 detail_elem.querySelector('#card_idolized').checked = true;809 } else {810 detail_elem.querySelector('#card_normal').checked = true;811 }812813 switch(card.a) {814 case ATTR.SMILE: detail_elem.className = 'detail_bg smile'; break;815 case ATTR.PURE: detail_elem.className = 'detail_bg pure'; break;816 case ATTR.COOL: detail_elem.className = 'detail_bg cool'; break;817 }818 detail_elem.querySelector('#data_eponym').textContent = card.n;819 detail_elem.querySelector('#data_member').textContent = toMemberName(card, false);820821 detail_elem.querySelector('#data_level').value = level;822 detail_elem.querySelector('#data_level').max = level_maxup;823 detail_elem.querySelector('#data_level_max').textContent = '/' + level_max;824 detail_elem.querySelector('#data_bond').value = bond;825 detail_elem.querySelector('#data_bond').max = bond_max;826 detail_elem.querySelector('#data_bond_max').textContent = '/' + bond_max;827828 detail_elem.querySelector('#data_life').textContent = param.life;829 detail_elem.querySelector('#data_smile').textContent = param.smile;830 detail_elem.querySelector('#data_pure').textContent = param.pure;831 detail_elem.querySelector('#data_cool').textContent = param.cool;832833 detail_elem.querySelector('#data_skilltype').textContent = toSkillType(card);834 detail_elem.querySelector('#data_skillname').textContent = card.m;835 detail_elem.querySelector('#data_skilllevel').value = getparam ? deckmem.sk : 1;836 detail_elem.querySelector('#data_skilllevel').max = sklevel_max;837 detail_elem.querySelector('#data_skilllevel_max').textContent = '/' + MAX_SKILL;838 detail_elem.querySelector('#data_skilldesc').textContent = toSkillDesc(card, getparam ? deckmem.sk : 1);839 detail_elem.querySelector('#data_centerskill').textContent = toCenterSkillDesc(card);840 detail_elem.querySelector('#data_memberid').textContent = card.i;841842 var spinboxs = detail_elem.getElementsByClassName('spin_box');843 for(var i = 0; i < spinboxs.length; i++) {844 var spin_input = spinboxs[i].querySelector('.spin_value');845 var spin_up = spinboxs[i].querySelector('.spinup_button');846 var spin_down = spinboxs[i].querySelector('.spindown_button');847 initSpinBox(spin_input, spin_up, spin_down);848 }849850 const btntext = deckmem != null ? 'å¤æ´ãã' : 'éãã';851 showDialog(detail_elem, '', 'card_detail_dlg', btntext, 1, update_deckmember, true, true);852}853854855856/* ----------------------------------------------------------------------857* Card Search858---------------------------------------------------------------------- */859860/* viewCardList861====================================================================== */862function viewCardList(listelem, cards, pagenum, skill_level, select_func) {863 listelem.innerHTML = '';864 items_elem = document.createDocumentFragment();865866 const pageitem_min = (VIEW_PAGEITEM * (pagenum - 1)) + 1;867 const pageitem_max = Math.min(VIEW_PAGEITEM * pagenum, cards.length);868869 for(var i = pageitem_min; i <= pageitem_max; i++) {870 var elem = cards[i - 1];871872 var item_elem = document.createElement('div'); item_elem.className = 'card_item';873 item_elem.innerHTML = 874 '<div class="member_icon" data-unitnumber="0">' +875 '<img src="" class="member_img"><img src="" class="member_frame">' +876 '</div>' +877 '<div class="card_data">' +878 '<div class="card_name"></div>' +879 '<div class="card_detail nowrap">' +880 '<div class="detail_name">ç¹æ</div><div class="detail_desc skill_type"></div>' +881 '</div>' +882 '<div class="card_detail nowrap">' +883 '<div class="detail_name">å¹æ</div><div class="detail_desc skill_desc"></div>' +884 '</div>' +885 '<div class="card_param">' +886 '<div class="param_life"><span class="param_num"></span></div>' +887 '<div class="param_smile"><span class="param_num"></span></div>' +888 '<div class="param_pure"><span class="param_num"></span></div>' +889 '<div class="param_cool"><span class="param_num"></span></div>' +890 '</div>' +891 '</div>';892893 var cardrarity = '', cardeponym = '', membername = toMemberName(elem, false);894 switch(elem.r) {895 case RARITY.UR: cardrarity = 'UR'; break;896 }897 if(elem.n != '') cardeponym = 'ã' + elem.n + 'ã';898899 item_elem.querySelector('.member_icon').dataset.unitnumber = elem.i;900 item_elem.querySelector('.member_img').src = toIconAssetPath(elem, false);901 item_elem.querySelector('.member_frame').src = toIconFrameAssetPath(elem);902 item_elem.querySelector('.card_name').textContent = cardrarity + cardeponym + membername;903 item_elem.querySelector('.skill_type').textContent = toSkillType(elem);904 item_elem.querySelector('.skill_desc').textContent = toSkillDesc(elem, skill_level);905 item_elem.querySelector('.param_life > .param_num').textContent = elem.h;906 item_elem.querySelector('.param_smile > .param_num').textContent = elem.s;907 item_elem.querySelector('.param_pure > .param_num').textContent = elem.p;
...
generateDotnetApi.js
Source: generateDotnetApi.js
...51 const asyncSuffix = item.member && item.member.async ? 'Async' : '';52 if (item.clazz)53 return `<see cref="I${toTitleCase(item.clazz.name)}"/>`;54 else if (item.member)55 return `<see cref="I${toTitleCase(item.member.clazz.name)}.${toMemberName(item.member)}${asyncSuffix}"/>`;56 else if (item.option)57 return `<paramref name="${item.option}"/>`;58 else if (item.param)59 return `<paramref name="${item.param}"/>`;60 else61 throw new Error('Unknown link format.');62});63// get the template for a class64const template = fs.readFileSync(path.join(__dirname, 'templates', 'interface.cs'), 'utf-8');65// map the name to a C# friendly one (we prepend an I to denote an interface)66const classNameMap = new Map(documentation.classesArray.map(x => [x.name, `I${toTitleCase(x.name)}`]));67// map some types that we know of68classNameMap.set('Error', 'Exception');69classNameMap.set('TimeoutError', 'TimeoutException');70classNameMap.set('EvaluationArgument', 'object');71classNameMap.set('boolean', 'bool');72classNameMap.set('Serializable', 'T');73classNameMap.set('any', 'object');74classNameMap.set('Buffer', 'byte[]');75classNameMap.set('path', 'string');76classNameMap.set('URL', 'string');77classNameMap.set('RegExp', 'Regex');78classNameMap.set('Readable', 'Stream');79/**80 *81 * @param {string} kind82 * @param {string} name83 * @param {Documentation.MarkdownNode[]} spec84 * @param {string[]} body85 * @param {string} folder86 * @param {string} extendsName87 */88function writeFile(kind, name, spec, body, folder, extendsName = null, namespace = "Microsoft.Playwright") {89 const out = [];90 // console.log(`Generating ${name}`);91 if (spec)92 out.push(...XmlDoc.renderXmlDoc(spec, maxDocumentationColumnWidth));93 else {94 let ownDocumentation = documentedResults.get(name);95 if (ownDocumentation) {96 out.push('/// <summary>');97 out.push(`/// ${ownDocumentation}`);98 out.push('/// </summary>');99 }100 }101 if (extendsName === 'IEventEmitter')102 extendsName = null;103 if (body[0] === '')104 body = body.slice(1);105 out.push(`${kind} ${name}${extendsName ? ` : ${extendsName}` : ''}`);106 out.push('{');107 out.push(...body);108 out.push('}');109 let content = template.replace('[NAMESPACE]', namespace).replace('[CONTENT]', out.join(EOL));110 fs.writeFileSync(path.join(folder, name + '.cs'), content);111}112/**113 * @param {Documentation.Class} clazz 114 */115function renderClass(clazz) {116 const name = classNameMap.get(clazz.name);117 if (name === 'TimeoutException')118 return;119 const body = [];120 for (const member of clazz.membersArray) {121 if (member.alias.startsWith('RunAnd'))122 renderMember(member, clazz, { trimRunAndPrefix: true }, body);123 renderMember(member, clazz, {}, body);124 }125 writeFile(126 'public partial interface',127 name,128 clazz.spec,129 body,130 apiDir,131 clazz.extends ? `I${toTitleCase(clazz.extends)}` : null);132}133/**134 * @param {string} name135 * @param {Documentation.Type} type136 */137function renderModelType(name, type) {138 const body = [];139 // TODO: consider how this could be merged with the `translateType` check140 if (type.union141 && type.union[0].name === 'null'142 && type.union.length == 2) {143 type = type.union[1];144 }145 if (type.name === 'Array') {146 throw new Error('Array at this stage is unexpected.');147 } else if (type.properties) {148 for (const member of type.properties) {149 let fakeType = new Type(name, null);150 renderMember(member, fakeType, {}, body);151 }152 } else {153 console.log(type);154 throw new Error(`Not sure what to do in this case.`);155 }156 writeFile('public partial class', name, null, body, typesDir);157}158/**159 * @param {string} name160 * @param {string[]} literals161 */162function renderEnum(name, literals) {163 const body = [];164 for (let literal of literals) {165 // strip out the quotes166 literal = literal.replace(/[\"]/g, ``)167 let escapedName = literal.replace(/[-]/g, ' ')168 .split(' ')169 .map(word => customTypeNames.get(word) || word[0].toUpperCase() + word.substring(1)).join('');170 body.push(`[EnumMember(Value = "${literal}")]`);171 body.push(`${escapedName},`);172 }173 writeFile('public enum', name, null, body, enumsDir);174}175/**176 * @param {string} name177 * @param {Documentation.Type} type178 */179function renderOptionType(name, type) {180 const body = [];181 renderConstructors(name, type, body);182 for (const member of type.properties)183 renderMember(member, member.type, {}, body);184 writeFile('public class', name, null, body, optionsDir);185}186for (const element of documentation.classesArray) {187 renderClass(element);188}189for (let [name, type] of optionTypes)190 renderOptionType(name, type);191for (let [name, type] of modelTypes)192 renderModelType(name, type);193for (let [name, literals] of enumTypes)194 renderEnum(name, literals);195if (process.argv[3] !== "--skip-format") {196 // run the formatting tool for .net, to ensure the files are prepped197 execSync(`dotnet format -f "${outputDir}" --include-generated --fix-whitespace`);198}199/**200 * @param {string} name201 */202function toArgumentName(name) {203 return name === 'event' ? `@${name}` : name;204}205 /**206 * @param {Documentation.Member} member207 */208function toMemberName(member, makeAsync = false) {209 const assumedName = toTitleCase(member.alias || member.name);210 if (member.kind === 'interface')211 return `I${assumedName}`;212 if (makeAsync && member.async)213 return assumedName + 'Async';214 if (!makeAsync && assumedName.endsWith('Async'))215 return assumedName.substring(0, assumedName.length - 'Async'.length);216 return assumedName;217}218/**219 * @param {string} name220 * @returns {string}221 */222function toTitleCase(name) {223 return name.charAt(0).toUpperCase() + name.substring(1);224}225/**226 *227 * @param {string} name228 * @param {Documentation.Type} type229 * @param {string[]} out230 */231function renderConstructors(name, type, out) {232 out.push(`public ${name}(){}`);233 out.push('');234 out.push(`public ${name}(${name} clone) {`);235 out.push(`if(clone == null) return;`);236 type.properties.forEach(p => {237 let propType = translateType(p.type, type, t => generateNameDefault(p, name, t, type));238 let propName = toMemberName(p);239 const overloads = getPropertyOverloads(propType, p, propName, p.type);240 for (let { name } of overloads)241 out.push(`${name} = clone.${name};`);242 });243 out.push(`}`);244}245/**246 *247 * @param {Documentation.Member} member248 * @param {Documentation.Class|Documentation.Type} parent249 * @param {{nojson?: boolean, trimRunAndPrefix?: boolean}} options250 * @param {string[]} out251 */252function renderMember(member, parent, options, out) {253 let name = toMemberName(member);254 if (member.kind === 'method') {255 renderMethod(member, parent, name, { mode: 'options', trimRunAndPrefix: options.trimRunAndPrefix }, out);256 return;257 }258 /** @type string */259 let type = translateType(member.type, parent, t => generateNameDefault(member, name, t, parent));260 if (member.kind === 'event') {261 if (!member.type)262 throw new Error(`No Event Type for ${name} in ${parent.name}`);263 out.push('');264 if (member.spec)265 out.push(...XmlDoc.renderXmlDoc(member.spec, maxDocumentationColumnWidth));266 out.push(`event EventHandler<${type}> ${name};`);267 return;268 }269 if (member.kind === 'property') {270 if (parent && member && member.name === 'children') { // this is a special hack for Accessibility271 console.warn(`children property found in ${parent.name}, assuming array.`);272 type = `IEnumerable<${parent.name}>`;273 }274 const overloads = getPropertyOverloads(type, member, name, parent);275 for (let { type, name, jsonName } of overloads) {276 out.push('');277 if (member.spec)278 out.push(...XmlDoc.renderXmlDoc(member.spec, maxDocumentationColumnWidth));279 if (!member.clazz)280 out.push(`${member.required ? '[Required]\n' : ''}[JsonPropertyName("${jsonName}")]`)281 if (!type.endsWith('?') && !member.required)282 type = `${type}?`;283 const requiredSuffix = type.endsWith('?') ? '' : ' = default!;';284 if (member.clazz)285 out.push(`public ${type} ${name} { get; }`);286 else287 out.push(`public ${type} ${name} { get; set; }${requiredSuffix}`);288 }289 return;290 }291 throw new Error(`Problem rendering a member: ${type} - ${name} (${member.kind})`);292}293/**294 *295 * @param {string} type296 * @param {Documentation.Member} member297 * @param {string} name298 * @param {Documentation.Class|Documentation.Type} parent299 * @returns [{ type: string; name: string; jsonName: string; }]300 */301function getPropertyOverloads(type, member, name, parent) {302 const overloads = [];303 if (type) {304 let jsonName = member.name;305 if (member.type.expression === '[string]|[float]')306 jsonName = `${member.name}String`;307 overloads.push({ type, name, jsonName });308 } else {309 for (const overload of member.type.union) {310 const t = translateType(overload, parent, t => generateNameDefault(member, name, t, parent));311 const suffix = toOverloadSuffix(t);312 overloads.push({ type: t, name: name + suffix, jsonName: member.name + suffix });313 }314 }315 return overloads;316}317/**318 *319 * @param {Documentation.Member} member320 * @param {string} name321 * @param {Documentation.Type} t322 * @param {*} parent323 */324function generateNameDefault(member, name, t, parent) {325 if (!t.properties326 && !t.templates327 && !t.union328 && t.expression === '[Object]')329 return 'object';330 // we'd get this call for enums, primarily331 let enumName = generateEnumNameIfApplicable(t);332 if (!enumName && member) {333 if (member.kind === 'method' || member.kind === 'property') {334 let names = [335 parent.alias || parent.name,336 toTitleCase(member.alias || member.name),337 toTitleCase(name),338 ];339 if (names[2] === names[1])340 names.pop(); // get rid of duplicates, cheaply341 let attemptedName = names.pop();342 let typesDiffer = function (left, right) {343 if (left.expression && right.expression)344 return left.expression !== right.expression;345 return JSON.stringify(right.properties) !== JSON.stringify(left.properties);346 }347 while (true) {348 // crude attempt at removing plurality349 if (attemptedName.endsWith('s')350 && !["properties", "httpcredentials"].includes(attemptedName.toLowerCase()))351 attemptedName = attemptedName.substring(0, attemptedName.length - 1);352 if (customTypeNames.get(attemptedName))353 attemptedName = customTypeNames.get(attemptedName);354 let probableType = modelTypes.get(attemptedName);355 if ((probableType && typesDiffer(t, probableType))356 || (["Value"].includes(attemptedName))) {357 if (!names.length)358 throw new Error(`Ran out of possible names: ${attemptedName}`);359 attemptedName = `${names.pop()}${attemptedName}`;360 continue;361 } else {362 registerModelType(attemptedName, t);363 }364 break;365 }366 return attemptedName;367 }368 if (member.kind === 'event') {369 return `${name}Payload`;370 }371 }372 return enumName || t.name;373}374/**375 * 376 * @param {Documentation.Type} type 377 * @returns 378 */379function generateEnumNameIfApplicable(type) {380 if (!type.union)381 return null;382 const potentialValues = type.union.filter(u => u.name.startsWith('"'));383 if ((potentialValues.length !== type.union.length)384 && !(type.union[0].name === 'null' && potentialValues.length === type.union.length - 1)) {385 return null; // this isn't an enum, so we don't care, we let the caller generate the name386 }387 return type.name;388}389/**390 * Rendering a method is so _special_, with so many weird edge cases, that it391 * makes sense to put it separate from the other logic.392 * @param {Documentation.Member} member393 * @param {Documentation.Class | Documentation.Type} parent394 * @param {string} name395 * @param {{396 * mode: 'options'|'named'|'base',397 * nodocs?: boolean,398 * abstract?: boolean,399 * public?: boolean,400 * trimRunAndPrefix?: boolean,401 * }} options402 * @param {string[]} out403 */404function renderMethod(member, parent, name, options, out) {405 out.push('');406 if (options.trimRunAndPrefix)407 name = name.substring('RunAnd'.length);408 /**409 * @param {Documentation.Type} type 410 * @returns 411 */412 function resolveType(type) {413 return translateType(type, parent, (t) => {414 let newName = `${parent.name}${toMemberName(member)}Result`;415 documentedResults.set(newName, `Result of calling <see cref="I${toTitleCase(parent.name)}.${toMemberName(member, true)}"/>.`);416 return newName;417 });418 }419 /** @type {Map<string, string[]>} */420 const paramDocs = new Map();421 const addParamsDoc = (paramName, docs) => {422 if (paramName.startsWith('@'))423 paramName = paramName.substring(1);424 if (paramDocs.get(paramName) && paramDocs.get(paramName) !== docs)425 throw new Error(`Parameter ${paramName} already exists in the docs.`);426 paramDocs.set(paramName, docs);427 };428 /** @type {string} */429 let type = null;430 // need to check the original one431 if (member.type.name === 'Object' || member.type.name === 'Array') {432 let innerType = member.type;433 let isArray = false;434 if (innerType.name === 'Array') {435 // we want to influence the name, but also change the object type436 innerType = member.type.templates[0];437 isArray = true;438 }439 if (innerType.expression === '[Object]<[string], [string]>') {440 // do nothing, because this is handled down the road441 } else if (!isArray && !innerType.properties) {442 type = `dynamic`;443 } else {444 type = classNameMap.get(innerType.name);445 if (!type)446 type = resolveType(innerType);447 if (isArray)448 type = `IReadOnlyList<${type}>`;449 }450 }451 type = type || resolveType(member.type);452 // TODO: this is something that will probably go into the docs453 // translate simple getters into read-only properties, and simple454 // set-only methods to settable properties455 if (member.args.size == 0456 && type !== 'void'457 && !name.startsWith('Get')458 && !name.startsWith('PostDataJSON')459 && !name.startsWith('As')) {460 if (!member.async) {461 if (member.spec && !options.nodocs)462 out.push(...XmlDoc.renderXmlDoc(member.spec, maxDocumentationColumnWidth));463 out.push(`${type} ${name} { get; }`);464 return;465 }466 }467 // HACK: special case for generics handling!468 if (type === 'T') {469 name = `${name}<T>`;470 }471 // adjust the return type for async methods472 if (member.async) {473 if (type === 'void')474 type = `Task`;475 else476 type = `Task<${type}>`;477 }478 // render args479 /** @type {string[]} */480 let args = [];481 /** @type {string[]} */482 let explodedArgs = [];483 /** @type {Map<string, string>} */484 let argTypeMap = new Map([]);485 /**486 *487 * @param {string} innerArgType488 * @param {string} innerArgName489 * @param {Documentation.Member} argument490 * @param {boolean} isExploded491 */492 function pushArg(innerArgType, innerArgName, argument, isExploded = false) {493 if (innerArgType === 'null')494 return;495 const requiredPrefix = (argument.required || isExploded) ? "" : "?";496 const requiredSuffix = (argument.required || isExploded) ? "" : " = default";497 var push = `${innerArgType}${requiredPrefix} ${innerArgName}${requiredSuffix}`;498 if (isExploded)499 explodedArgs.push(push)500 else501 args.push(push);502 argTypeMap.set(push, innerArgName);503 }504 /**505 * @param {Documentation.Member} arg506 */507 function processArg(arg) {508 if (options.trimRunAndPrefix && arg.name === 'action')509 return;510 if (arg.name === 'options') {511 if (options.mode === 'options' || options.mode === 'base') {512 const optionsType = member.clazz.name + name.replace('<T>', '') + 'Options';513 optionTypes.set(optionsType, arg.type);514 args.push(`${optionsType}? options = default`);515 argTypeMap.set(`${optionsType}? options = default`, 'options');516 addParamsDoc('options', ['Call options']);517 } else {518 arg.type.properties.forEach(processArg);519 }520 return;521 }522 if (arg.type.expression === '[string]|[path]') {523 let argName = toArgumentName(arg.name);524 pushArg("string?", `${argName} = default`, arg);525 pushArg("string?", `${argName}Path = default`, arg);526 if (arg.spec) {527 addParamsDoc(argName, XmlDoc.renderTextOnly(arg.spec, maxDocumentationColumnWidth));528 addParamsDoc(`${argName}Path`, [`Instead of specifying <paramref name="${argName}"/>, gives the file name to load from.`]);529 }530 return;531 } else if (arg.type.expression === '[boolean]|[Array]<[string]>') {532 // HACK: this hurts my brain too533 // we split this into two args, one boolean, with the logical name534 let argName = toArgumentName(arg.name);535 let leftArgType = translateType(arg.type.union[0], parent, (t) => { throw new Error('Not supported'); });536 let rightArgType = translateType(arg.type.union[1], parent, (t) => { throw new Error('Not supported'); });537 pushArg(leftArgType, argName, arg);538 pushArg(rightArgType, `${argName}Values`, arg);539 addParamsDoc(argName, XmlDoc.renderTextOnly(arg.spec, maxDocumentationColumnWidth));540 addParamsDoc(`${argName}Values`, [`The values to take into account when <paramref name="${argName}"/> is <code>true</code>.`]);541 return;542 }543 const argName = toArgumentName(arg.alias || arg.name);544 const argType = translateType(arg.type, parent, (t) => generateNameDefault(member, argName, t, parent));545 if (argType === null && arg.type.union) {546 // we might have to split this into multiple arguments547 let translatedArguments = arg.type.union.map(t => translateType(t, parent, (x) => generateNameDefault(member, argName, x, parent)));548 if (translatedArguments.includes(null))549 throw new Error('Unexpected null in translated argument types. Aborting.');550 let argDocumentation = XmlDoc.renderTextOnly(arg.spec, maxDocumentationColumnWidth);551 for (const newArg of translatedArguments) {552 pushArg(newArg, argName, arg, true); // push the exploded arg553 addParamsDoc(argName, argDocumentation);554 }555 args.push(arg.required ? 'EXPLODED_ARG' : 'OPTIONAL_EXPLODED_ARG');556 return;557 }558 addParamsDoc(argName, XmlDoc.renderTextOnly(arg.spec, maxDocumentationColumnWidth));559 if (argName === 'timeout' && argType === 'decimal') {560 args.push(`int timeout = 0`); // a special argument, we ignore our convention561 return;562 }563 pushArg(argType, argName, arg);564 }565 let modifiers = '';566 if (options.abstract)567 modifiers = 'protected abstract ';568 if (options.public)569 modifiers = 'public ';570 member.argsArray571 .sort((a, b) => b.alias === 'options' ? -1 : 0) //move options to the back to the arguments list572 .forEach(processArg);573 574 let body = ';';575 if (options.mode === 'base') {576 // Generate options -> named transition.577 const tokens = [];578 for (const arg of member.argsArray) {579 if (arg.name === 'action' && options.trimRunAndPrefix)580 continue;581 if (arg.name !== 'options') {582 tokens.push(toArgumentName(arg.name));583 continue;584 }585 for (const opt of arg.type.properties) {586 // TODO: use translate type here?587 if (opt.type.union && !opt.type.union[0].name.startsWith('"') && opt.type.union[0].name !== 'null' && opt.type.expression !== '[string]|[Buffer]') {588 // Explode overloads.589 for (const t of opt.type.union) {590 const suffix = toOverloadSuffix(translateType(t, parent));591 tokens.push(`${opt.name}${suffix}: options.${toMemberName(opt)}${suffix}`);592 }593 } else {594 tokens.push(`${opt.alias || opt.name}: options.${toMemberName(opt)}`);595 }596 }597 }598 body = `599{600 options ??= new ${member.clazz.name}${name}Options();601 return ${toAsync(name, member.async)}(${tokens.join(', ')});602}`;603 }604 if (!explodedArgs.length) {605 if (!options.nodocs) {606 out.push(...XmlDoc.renderXmlDoc(member.spec, maxDocumentationColumnWidth));607 paramDocs.forEach((value, i) => printArgDoc(i, value, out));608 }...
AirBasix.js
Source: AirBasix.js
1/**2 * AirBasix 3 * Author: Paul McDowell4 * 5 * @description AirBasix (Airbase + Wix ) enables synchronizing airtable bases to6 * wix collections. This is the stand-alone version contained below. The newer 7 * "current" version that is found via npm is contained in the source directory. 8 * This version has been left intact for those that want an easier to read and9 * more guided version of the program that doesn't require them to implement a10 * wrapper on the node module for executing against potentially multiple bases11 * and collections. This is a 'one and done' design.12 * 13 */14/*15 * If you're not sure how this all works, the following three keys are the 16 * most important things you need to change. Please note, for security purposes17 * make a secondary airtable account and grant it read-only access to your airtable18 * base, then use the API key for that user here. That way if it becomes compromised19 * 1) your data source remains uncorrupted and 2) you can easily change the key or20 * restrict the account from having access.21 */22const airtableApiKey = ''; // the per-user key from your read-only airtable account23const airtableBaseId = ''; // the ID of the base - you can find this in your api docs24/*25 * The name of the collection we intend to store our synchronized data in.26 * NOTE: This collection is going to be code-managed, and thus SHOULD NOT27 * BE USED FOR OTHER ENTRIES. Data not in the airtable source WILL be deleted28 * from the wix collection at every synchronization.29 */30const wixAirtableStore = 'Places'; 31/*32 * The name of the view we want to use (typically your default table name). If you don't want to use33 * the default view, change this to the view name of your choice.34 */35const airtableRootDb = 'Places'; 36const Airtable = require('airtable'); 37const baseApi = new Airtable({apiKey: airtableApiKey}).base(airtableBaseId);38const wixDataOpts = { 'suppressAuth' : true };39import wixData from 'wix-data';40// This is universal to all wix collections, and will likely break everything if you41// change it. 42// ex: const wixIdName = '_id';43const wixIdName = '_id';44/*45 * The following are field detection assumptions made based on my own needs. You may46 * need to change some of these based on your own assumptions of how things should 47 * be organized in airtables.48 */49// atid is an arbitrary airtable Id field for tracking purposes.50const wixAirtableIdName = 'atid';51const airtableTagsSubstring = 'tags';52const shadowTagFieldSuffix = 'shadow';53const generateShadowTagFields = true; // if you don't want shadow fields for using tags in dataset processing, set to false54const airtableAddressSubstring = 'address';55/*56 * If you need to use maps on your wix site based on airtable address data, you'll need to add a secondary field in airtable57 * that contains the geocode info for each address. This can be created by using the Maps App in Airtable. 58 */59const airtableGeocodeFieldName = 'geocode';60/**61 * Begins the process of synchronizing an airtables db and views with a wix collection.62 * This is the main entry point for a backend-only synchronizing module.63 * PLEASE NOTE: Due to the sensitive nature of the processes involved, you should not64 * run this on a front-end. This is a backend only module.65 */66export async function ManualUpdate() {67 await SyncViews();68 console.log("completed update");69}70/**71 * Processes views provided in the views constant, relative to the configured base api.72 * If the same Id is present in multiple airtable views the duplicates are skipped.73 */74async function SyncViews() {75 var presentIds = [];76 let noErrorsFound = true;77 /* For the chosen view, iterate over all the pages contained in that view and collect78 * that record data for use below. 79 */80 let atrecords = await baseApi(airtableRootDb)81 .select({pageSize: 100})82 .all();83 84 atrecords.forEach(function(atrecord) { 85 var currId = atrecord.id;86 if(presentIds.indexOf(currId) >= 0) {87 return; // skip IDs we've already processed if dupes are found. 88 }89 90 presentIds.push(currId);91 wixData.query(wixAirtableStore) 92 .eq(wixAirtableIdName, currId) 93 .find()94 .then(function(wixrecords) {95 if(wixrecords.items.length > 0) {96 UpdateRecord(atrecord, wixrecords.items[0]);97 } else {98 InsertRecord(atrecord);99 }100 }).catch((error) => {101 noErrorsFound = false;102 LogError(error.message, error.code);103 });104 105 });106 console.log(`Updated ${presentIds.length} records.`);107 // clean up missing records if no errors were found in processing.108 if(noErrorsFound)109 await RemoveMissingRecords(presentIds);110}111/**112 * Process error handling centrally for this module.113 * @param {string} errorMsg - The message describing the error received.114 * @param {string} code - The error code received, usually from the API. 115 */116function LogError (errorMsg, code) {117 console.log(`Error code ${code}: ${errorMsg}`);118}119/**120 * Inserts a new Airtable entry into the wix collection.121 * @param {object} atRecord - Airtable Record object.122 */123function InsertRecord(atRecord) {124 var wixItem = wixItem || {125 [wixAirtableIdName] : atRecord.id,126 'createdTime': atRecord.createdTime127 };128 129 wixItem = CopyAirtableFieldsToWixRecord(atRecord.fields, wixItem);130 UpdateWix(wixItem);131}132/**133 * Update the record data for a given entry existing in the wix collection.134 * @param {object} atRecord - Airtable Record object.135 * @param {object} wixRecord - Wix record object.136 */137function UpdateRecord(atRecord, wixRecord) {138 var wixItem = wixRecord || {139 [wixIdName] : wixItem._id,140 [wixAirtableIdName] : atRecord.id,141 'createdTime': atRecord.createdTime142 };143 wixItem = CopyAirtableFieldsToWixRecord(atRecord.fields, wixItem);144 UpdateWix(wixItem);145}146/**147 * Copies the fields from airtable to the appropriate wix record entries148 * based on a pre-determined field map.149 * @param {object} atFields - The Fields entry from the Airtable Record.150 * @param {object} wixRecord - The record being sent to wix, preloaded with151 * required ID and timestamp properties.152 * @returns {object} A WixRecord object with the appropriate data entries added.153 */154function CopyAirtableFieldsToWixRecord(atFields, wixRecord) {155 for(var member in atFields) { // automated field processing156 if(typeof(atFields) === 'function')157 continue; // skip over functions, only process data members. 158 159 var data = atFields[member];160 // this camelCases the member name so it fits with the fields used in Wix.161 var toMemberName = member.toLowerCase().replace('/','').replace(/(?:^\w|[A-Z]|\b\w)/g, (word,index) => index == 0 ? word.toLowerCase() : word.toUpperCase()).replace(/\s+/g,'');162 if(Array.isArray(atFields[member])) {163 var dt = typeof(data[0]);164 if(dt === "string") {165 // strings should map cleanly across without processing.166 wixRecord[toMemberName] = data;167 168 if(generateShadowTagFields) {169 // if this is a tags field add a shadow field with concatinated values170 // so we can use it for filtering, since wix doesn't support filtering 171 // by tags for some dumb reason.172 if(member.toLowerCase().indexOf(airtableTagsSubstring) >= 0) {173 wixRecord[toMemberName + shadowTagFieldSuffix] = data.join(',');174 }175 }176 }177 else if(dt === 'object') {178 if(data[0].hasOwnProperty('type') && data[0].type.indexOf('image') >= 0) {179 // process as an array of images.180 var images = [];181 data.forEach((image) => images.push({type: 'image', src: image.url}));182 wixRecord[toMemberName] = images;183 }184 }185 }186 else { 187 /* If this is an address place it into an object with the value as "formatted"188 * otherwise check to see if it's a geocode entry for marking map locations.189 */190 if(member.toLowerCase().indexOf(airtableAddressSubstring) >= 0) {191 wixRecord[toMemberName] = { formatted: atFields[member]};192 }193 else if(member.toLowerCase().indexOf(airtableGeocodeFieldName) >= 0) {194 // geocode data in airtable is stored in a base64 string, so we need to 195 // break that out into json and then parse it into an object we can work with.196 var jsonString = new Buffer(atFields[member].split(' ')[1], 'base64').toString();197 var jsonObj = JSON.parse(jsonString);198 var wixObj = {'formatted': jsonObj.o.formattedAddress,199 'location': {200 'latitude': jsonObj.o.lat,201 'longitude': jsonObj.o.lng202 },203 //'subdivision': "OK", // You may need to add these for your purpose, if so look at the geocode entries. 204 //'country': "US"205 };206 wixRecord[toMemberName] = wixObj;207 } else {208 // process as basic strings and numbers, which need no translation.209 wixRecord[toMemberName] = atFields[member];210 }211 }212 }213 return wixRecord;214}215/**216 * Updates the wix collection with the specified entry, either calling insert217 * or update as needed via the wix-data.save function.218 * @param {object} wixItem - The fully formed WixRecord for entry.219 */220function UpdateWix(wixItem) {221 wixData.save(wixAirtableStore, wixItem, wixDataOpts).then((results) => {222 // the item was updated successfully223 console.debug("item " + results._id + " created.");224 }).catch((error) => { LogError(error.message, error.code); });225}226/**227 * Gathers a list of Ids contained in the wix collection that do not match Ids synchronized from228 * Airtable. These Ids likely need to be deleted, thus making that a simpler process.229 * @param {Array} keepids The ids we want to keep in the table, stored as an array of strings230 * @returns An array of wix collection Ids not matching the supplied list (limited to 1,000 Ids)231 */232async function getOrphanIds(keepids) {233 let foundIds = [];234 let records = await wixData.query(wixAirtableStore)235 .limit(1000) // this arbitrary limit is created by Wix. Should their policy change, so can this236 .not(wixData.query(wixAirtableStore).hasSome([wixAirtableIdName], keepids))237 .find(wixDataOpts);238 records.items.forEach(record => foundIds.push(record._id));239 return foundIds; 240}241/**242 * Processes all the Ids on Wix against a supplied list of airtable ids. 243 * Any that don't match what is in airtable are deleted. NOTE: Wix has an artificial limit based244 * on implementation that will only remove up to 1,000 IDs at a time. If you need to remove more,245 * I suggest you expand on this section to enable that process. 246 * @param {string[]} keepids - The list of all valid Ids from airtable.247 */248async function RemoveMissingRecords(keepids) {249 if(keepids == null || keepids == undefined || keepids.length == 0)250 return;251 252 console.log(keepids);253 let removeids = await getOrphanIds(keepids);254 255 if(removeids.length == 0) { // skip out if we're empty.256 console.log(`no orphans found, ending removal.`);257 return;258 }259 console.log(`${removeids.length} orphans found.`);260 261 wixData.bulkRemove(wixAirtableStore, removeids, wixDataOpts)262 .then((results) => {263 if(results.skipped > 0)264 { console.error('skipped ' + results.skipped + ' items.'); }265 console.log('Removed ' + removeids.length +' orphaned entries.')266 }).catch((error) => {LogError(error.errorMsg, error.code)});...
sendController.js
Source: sendController.js
1const { Request, Member } = require("../models");2const { getAnswer, getAnswerFromButtonGroup } = require("../utils/lib");3const maxStrikes = 4;4const sendController = async (bot, msg) => {5 const chatId = msg.chat.id;6 const selectedUserId = +msg.text.split(" ")[1];7 if (selectedUserId == msg.from.id) {8 bot.sendMessage(chatId, "Seriously dude, Why you sending to yourself?ð¤¦");9 return;10 }11 const requestsSentByThisUser = await Request.find({ fromId: msg.from.id })12 .lean()13 .exec();14 if (requestsSentByThisUser.length === maxStrikes) {15 bot.sendMessage(16 chatId,17 `You've already used all your ${maxStrikes} chances.\n`18 );19 await Member.findOneAndUpdate({ chatId }, { allStrikesOut: true });20 return;21 }22 const requestsReceivedToThisUser = await Request.find({ toId: msg.from.id })23 .lean()24 .exec();25 const selectedUserMatch = requestsReceivedToThisUser.find(26 (m) => m.fromId === selectedUserId27 );28 const currUserName =29 msg.from.first_name ||30 "" + msg.from.last_name + "" ||31 "@" + msg.from.username;32 if (selectedUserMatch) {33 const { fromUserName, fromId: matchedUserId } = selectedUserMatch;34 const name = fromUserName;35 bot.sendMessage(36 chatId,37 `Congragulations, You've got a match!\nBoth you and ${name} can spend Valentine's day togetherâ¤ï¸\nNotification sent to ${name} informing the match!ð`38 );39 bot.sendMessage(40 matchedUserId,41 `Congragulations, ${42 msg.from.username ? "@" + msg.from.username : currUserName43 } has found a match with you!\nNow go call them up and spend Valentine's day together!ð¯`44 );45 selectedUserMatch.matched = true;46 Request.findByIdAndUpdate(selectedUserMatch._id, { matched: true })47 .then(() => console.log("request status updated"))48 .catch((err) => console.log("Error in updating request status: " + err));49 return;50 }51 const toMember = await Member.findOne({ userId: selectedUserId }).exec();52 if (requestsReceivedToThisUser.length) {53 toMemberName = toMember.fullName;54 await bot.sendMessage(55 chatId,56 `${toMemberName} was not the one who sent you the message.\nBut you can send an anonymous message to ${toMemberName} to see if ${toMemberName} have some feelings towards you!`57 );58 requestsReceivedToThisUser59 .filter((r) => !r.matched)60 .forEach((r) => {61 bot.sendMessage(62 r.fromId,63 `Hi, ${r.toUserName} tried selecting someone, but unfortunately that wasn't you.`64 );65 });66 // await Member.findByIdAndUpdate();67 }68 const { extraMsg } = await getAnswer(69 {70 key: "extraMsg",71 prompt: `Enter the special message you want to send to ${toMember.fullName}. eg: "I'm your classmate and we used to go together by College Bus. I don't talk very much, but I really like you!"`,72 // formatter: (val) => (val === "." ? null : val),73 },74 chatId,75 bot76 );77 console.log(extraMsg);78 const confirmButtons = ["Yes, Nothing to loseð¤", "No, I'm good with myself"];79 const crushMsg = `Hi, this is to let you know that someone from MEC have feelings towards you. Here is the anonymous message sent by that special person to you:\n---\n${extraMsg}\n---\n\nHave some idea who this is from? Enter /start to check or try /faq or /help to know more details about this bot.`;80 const confirmSendMessage = await getAnswerFromButtonGroup(81 {82 key: "confirmSendMessage",83 prompt: `The following message will be sent to ${toMember.fullName}:\n${crushMsg}\n\n\n-------\nDo you want to confirm this?`,84 buttons: confirmButtons,85 condition: (val) => confirmButtons.includes(val),86 formatter: (val) => val === confirmButtons[0],87 },88 chatId,89 bot90 );91 if (confirmSendMessage) {92 try {93 bot94 .sendMessage(selectedUserId, crushMsg)95 .then((r) => console.log("Message sent successfully"));96 bot.sendMessage(chatId, `Message has been sent to ${toMember.fullName}`);97 const newRequest = new Request({98 fromId: msg.chat.id,99 toId: selectedUserId,100 matched: false,101 fromUserName: currUserName,102 toUserName: toMember.fullName,103 });104 await newRequest.save();105 // console.log(savedRequest);106 } catch (err) {107 bot.sendMessage(chatId, "There's been some error. Please try again");108 console.log("Error: " + err);109 }110 } else {111 bot.sendMessage(112 chatId,113 "Cancelled sending message.\nEnter /start to try again."114 );115 }116};...
frepleybbs.js
Source: frepleybbs.js
1$(function () {2 $("#jqGrid").jqGrid({3 url: baseURL + 'sys/frepleybbs/list',4 datatype: "json",5 colModel: [ 6 { label: 'itemid', name: 'itemid', index: 'itemid', width: 50, key: true,hidden:true },7 { label: '主贴', name: 'title', index: 'title', width: 80 },8 { label: 'åå¤å
容', name: 'repleyContent', index: 'repley_content', width: 80 ,hidden: true},9 { label: 'åå¤äºº', name: 'repleyname', index: 'repleyname', width: 80 },10 { label: 'ipå°å', name: 'ip', index: 'ip', width: 80 }, 11 { label: '被è·å¸äºº', name: 'tomembername', index: 'tomembername', width: 80 },12 //{ label: 'æå±å°åº', name: 'areaid', index: 'areaid', width: 80 },13 { label: '楼å±', name: 'floor', index: 'floor', width: 80 }, 14 { label: 'æ·»å æ¶é´', name: 'addtime', index: 'addtime', width: 80 },15 { label: 'æä½', name: 'contentDetail', index: 'content_detail', width: 80,formatter: function (cellvalue, options, rowdata) {16 var str = '<a href="javascript:void(0);" onclick="clickth('+ rowdata.itemid +')">æ¥ç</a>';17 return str;18 } }19 ],20 viewrecords: true,21 height: 385,22 rowNum: 10,23 rowList : [10,30,50],24 rownumbers: true, 25 rownumWidth: 25, 26 autowidth:true,27 multiselect: true,28 pager: "#jqGridPager",29 jsonReader : {30 root: "page.list",31 page: "page.currPage",32 total: "page.totalPage",33 records: "page.totalCount"34 },35 prmNames : {36 page:"page", 37 rows:"limit", 38 order: "order"39 },40 gridComplete:function(){41 //éègridåºé¨æ»å¨æ¡42 $("#jqGrid").closest(".ui-jqgrid-bdiv").css({ "overflow-x" : "hidden" }); 43 }44 });45});46var vm = new Vue({47 el:'#rrapp',48 data:{49 showList: true,50 title: null,51 fRepleyBbs: {}52 },53 methods: {54 query: function () {55 vm.reload();56 },57 add: function(){58 vm.showList = false;59 vm.title = "æ°å¢";60 vm.fRepleyBbs = {};61 },62 update: function (event) {63 var itemid = getSelectedRow();64 if(itemid == null){65 return ;66 }67 vm.showList = false;68 vm.title = "ä¿®æ¹";69 70 vm.getInfo(itemid)71 },72 saveOrUpdate: function (event) {73 var url = vm.fRepleyBbs.itemid == null ? "sys/frepleybbs/save" : "sys/frepleybbs/update";74 $.ajax({75 type: "POST",76 url: baseURL + url,77 contentType: "application/json",78 data: JSON.stringify(vm.fRepleyBbs),79 success: function(r){80 if(r.code === 0){81 alert('æä½æå', function(index){82 vm.reload();83 });84 }else{85 alert(r.msg);86 }87 }88 });89 },90 del: function (event) {91 var itemids = getSelectedRows();92 if(itemids == null){93 return ;94 }95 96 confirm('ç¡®å®è¦å é¤éä¸çè®°å½ï¼', function(){97 $.ajax({98 type: "POST",99 url: baseURL + "sys/frepleybbs/delete",100 contentType: "application/json",101 data: JSON.stringify(itemids),102 success: function(r){103 if(r.code == 0){104 alert('æä½æå', function(index){105 $("#jqGrid").trigger("reloadGrid");106 });107 }else{108 alert(r.msg);109 }110 }111 });112 });113 },114 getInfo: function(itemid){115 $.get(baseURL + "sys/frepleybbs/info/"+itemid, function(r){116 vm.fRepleyBbs = r.fRepleyBbs;117 });118 },119 reload: function (event) {120 vm.showList = true;121 var page = $("#jqGrid").jqGrid('getGridParam','page');122 $("#jqGrid").jqGrid('setGridParam',{ 123 page:page124 }).trigger("reloadGrid");125 }126 }127});128//æ¥ç详ç»129function clickth(id) {130 $.get(baseURL + "sys/frepleybbs/info/" + id, function (r) {131 if(r.code==0){132 var strbug = "";133 strbug+="<table>åå¤å
容ï¼"+r.fRepleyBbs.repleyContent+"<br/></table>";134 document.getElementById("showDetailDIV").innerHTML=strbug;135 layer.open({136 type: 1,137 // btn: savebug,138 skin: 'layui-layer-molv',139 title: "详æ
",140 area: ['600px', '500px'],141 shadeClose: false,142 content: jQuery("#showDetail")143 });144 }145 });...
index.js
Source: index.js
1var app = getApp()2const config = require('../../../../../../utils/config.js')3Page({4 /**5 * 页é¢çåå§æ°æ®6 */7 data: {8 toMemberName: '',9 toMemberId: '',10 imei: '',11 toMemberPhone: '',12 followerPhone: '',13 relationShip: '',14 },15 /**16 * çå½å¨æå½æ°--çå¬é¡µé¢å è½½17 */18 onLoad: function(options) {19 this.setData({20 imei: options.imei,21 toMemberId: options.toMemberId,22 toMemberPhone: options.toMemberPhone,23 toMemberName: options.toMemberName24 })25 },26 // è·åç¨æ·è¾å
¥çææºå·27 toGetFollowerPhone: function(e) {28 this.setData({29 followerPhone: e.detail.value30 })31 },32 // è·åå
³ç³»33 toGetFollowerRelationShip: function(e) {34 var index = e.currentTarget.dataset.id35 var relationShipChoosen = this.data.relationShips[index]36 this.setData({37 relationShip: relationShipChoosen,38 showRelationShipsModalStatus: false39 })40 },41 // è·åç¨æ·è¾å
¥çå
³ç³»42 enterRelation: function(e) {43 let length = this.data.relation44 if (length > 5) {45 wx.showToast({46 title: 'æå¤åªè½è¾å
¥6个å符ï¼',47 icon: 'none',48 duration: app.globalData.duration49 })50 } else {51 this.setData({52 relationShip: e.detail.value,53 showRelationShipsModalStatus: false54 })55 }56 },57 // ç¹å»æ·»å æå58 doAddFollower: function(e) {59 var userId = app.globalData.userId60 var followerPhone = this.data.followerPhone61 var imei = this.data.imei62 var relationShip = this.data.relationShip63 var toMemberId = this.data.toMemberId64 var toMemberPhone = this.data.toMemberPhone65 var toMemberName = this.data.toMemberName66 if (followerPhone.length < 11) {67 wx.showToast({68 title: '请è¾å
¥æ£ç¡®ææºå·',69 icon: 'none',70 duration: app.globalData.duration71 })72 } else {73 if (relationShip === '') {74 wx.showToast({75 title: '请è¾å
¥æ¨ä¸ä½©æ´è
å
³ç³»',76 icon: 'none',77 duration: app.globalData.duration78 })79 } else {80 app.http.postRequest(config.postAddFollower, {81 userId: userId,82 followerPhone: followerPhone,83 imei: imei,84 relation: relationShip,85 toMemberId: toMemberId,86 toMemberPhone: toMemberPhone,87 toMemberName: toMemberName88 }).then(res => {89 if (res.data.code === 'GN00000') {90 wx.showToast({91 title: 'å
³æ³¨è®¾å¤æå!',92 duration:app.globalData.duration93 });94 setTimeout(function(){95 wx.navigateBack({96 delta: 197 })98 },500)99 } else if (res.data.code === 'GN60011') {100 wx.showToast({101 title: 'å·²å
³è该设å¤!',102 icon: 'none'103 })104 } else {105 wx.showToast({106 title: 'å
³æ³¨è®¾å¤å¤±è´¥ï¼è¯·ç¨åéè¯!',107 icon: 'none'108 })109 }110 })111 }112 }113 }...
table.js
Source: table.js
...50 tbody.insertRow().innerHTML = `51 <td>${fromPackageAndClassName(packageDep, memberDep)}</td>52 <td>${fromMemberName(memberDep)}</td>53 <td>→</td>54 <td>${toMemberName(memberDep)}</td>55 <td>${toPackageAndClassName(packageDep, memberDep)}</td>56 `;57 }58 }59 const table = document.createElement('table');60 table.appendChild(thead);61 table.appendChild(tbody);62 const tableWrapper = document.createElement('div');63 tableWrapper.id = 'table-wrapper';64 tableWrapper.appendChild(table);65 return tableWrapper;66}67function fromPackageAndClassName(packageDep, memberDep) {68 return [packageDep.from.relativeName, memberDep.from.className].filter(x => x).join('.');69}70function toPackageAndClassName(packageDep, memberDep) {71 return [packageDep.to.relativeName, memberDep.to.className].filter(x => x).join('.');72}73function fromMemberName(memberDep) {74 return memberDep.from.memberName !== null75 ? memberDep.from.memberName.replace('<', '<').replace('>', '>')76 : '';77}78function toMemberName(memberDep) {79 return memberDep.to.memberName !== null80 ? memberDep.to.memberName.replaceAll('<', '<').replaceAll('>', '>')81 : '<i>' + memberDep.type.toLowerCase().replaceAll('_', ' ') + '</i>';...
dynamics.js
Source: dynamics.js
12function dynamicsMessageType1(messages){3 eval("message = "+messages);4 document.write("<a target=_blank href=blog-home.action?tomember.id="+message.memberId+">");5 document.write(message.memberName);6 document.write("</a>_");7 document.write(message.date);8 document.write("å<a target=_blank href=blog-home.action?tomember.id="+message.tomemberId+">");9 document.write(message.tomemberName);10 document.write("</a>");11 document.write("å 为äºå¥½å");12}1314function dynamicsMessageType2(messages){15 eval("message = "+messages);16 document.write("<a target=_blank href='blog-home.action?tomember.id="+message.memberId+"'>");17 document.write(message.memberName);18 document.write("</a>_");19 document.write(message.date);20 document.write("åå¸äºæ°æ¥å¿");21 document.write("<a target=_blank href=blog-content.action?id="+message.articleId+"&&tomember.id="+message.memberId+">");22 document.write("\""+message.articleTitle+"\"");23 document.write("</a>");24}2526function dynamicsMessageType3(messages){27 eval("message = "+messages);28 document.write("<a target=_blank href=blog-home.action?tomember.id="+message.memberId+">");29 document.write(message.memberName);30 document.write("</a>_");31 document.write(message.date);32 document.write("åå¸äºæ°ä½å");33 document.write("<a target=_blank href=blog-content.action?id="+message.articleId+"&&tomember.id="+message.memberId+">");34 document.write("\""+message.articleTitle+"\"");35 document.write("</a>");36}3738function dynamicsMessageType4(messages){39 eval("message = "+messages);40 document.write("<a target=_blank href=blog-home.action?tomember.id="+message.memberId+">");41 document.write(message.memberName);42 document.write("</a>_");43 document.write(message.date);44 document.write("æ¶èäºæç« ");45 document.write("<a target=_blank href=../searcharticlecontent.action?article.id="+message.articleId+">");46 document.write("\""+message.articleTitle+"\"");47 document.write("</a>");48}4950//æ¥çç¨æ·å¨ææ´å¤51function getDynamicsMore(){52 var url = "member-dynamics-more.action";53 var data = {'ssuid':1};54 jQuery.post(url,data,function(data){55 56 $("#dynamicsMore").after(data);57 $("#dynamicsMore").hide();58 });
...
Using AI Code Generation
1const { toMemberName } = require('playwright/lib/server/page');2const { toMemberName } = require('playwright/lib/server/elementHandler');3const { toMemberName } = require('playwright/lib/server/jsHandle');4const { toMemberName } = require('playwright/lib/server/frame');5const { toMemberName } = require('playwright/lib/server/worker');6const { toMemberName } = require('playwright/lib/server/browserContext');7const { toMemberName } = require('playwright/lib/server/browser');8const { toMemberName } = require('playwright/lib/server/browserType');9const { toMemberName } = require('playwright/lib/server/playwright');10const { toMemberName } = require('playwright/lib/server/connection');11const { toMemberName } = require('playwright/lib/server/dispatcher');12const { toMemberName } = require('playwright/lib/server/dispatcherConnection');13const { toMemberName } = require('playwright/lib/server/dispatcherScope');14const { toMemberName } = require('playwright/lib/server/dispatcherSession');15const { toMemberName } = require('playwright/lib/server/eventsDispatcher');16const { toMemberName } = require('playwright/lib/server/sdkObject');
Using AI Code Generation
1const { toMemberName } = require('playwright/lib/utils/utils');2console.log(toMemberName('some string'));3const { toMemberName } = require('playwright/lib/utils/utils');4console.log(toMemberName('some string'));5const { toMemberName } = require('playwright/lib/utils/utils');6console.log(toMemberName('some string'));7const { toMemberName } = require('playwright/lib/utils/utils');8console.log(toMemberName('some string'));9const { toMemberName } = require('playwright/lib/utils/utils');10console.log(toMemberName('some string'));11const { toMemberName } = require('playwright/lib/utils/utils');12console.log(toMemberName('some string'));13const { toMemberName } = require('playwright/lib/utils/utils');14console.log(toMemberName('some string'));15const { toMemberName } = require('playwright/lib/utils/utils');16console.log(toMemberName('some string'));17const { toMemberName } = require('playwright/lib/utils/utils');18console.log(toMemberName('some string'));19const { toMemberName } = require('playwright/lib/utils/utils');20console.log(toMemberName('some string'));
Using AI Code Generation
1const { toMemberName } = require('playwright/lib/utils/utils');2const name = toMemberName('some string');3console.log(name);4const { toMemberName } = require('playwright/lib/utils/utils');5const name = toMemberName('some string');6console.log(name);
Using AI Code Generation
1const { toMemberName } = require('playwright/lib/utils/utils');2console.log(toMemberName('myMethod'));3console.log(toMemberName('myMethod1'));4console.log(toMemberName('myMethod2'));5const { toMemberName } = require('playwright/lib/utils/utils');6console.log(toMemberName('myMethod'));7console.log(toMemberName('myMethod1'));8console.log(toMemberName('myMethod2'));9const { toMemberName } = require('playwright/lib/utils/utils');10console.log(toMemberName('myMethod'));11console.log(toMemberName('myMethod1'));12console.log(toMemberName('myMethod2'));13const { toMemberName } = require('playwright/lib/utils/utils');14console.log(toMemberName('myMethod'));15console.log(toMemberName('myMethod1'));16console.log(toMemberName('myMethod2'));17const { toMemberName } = require('playwright/lib/utils/utils');18console.log(toMemberName('myMethod'));19console.log(toMemberName('myMethod1'));20console.log(toMemberName('myMethod2'));21const { toMemberName } = require('playwright/lib/utils/utils');22console.log(toMemberName('myMethod'));23console.log(toMemberName('myMethod1'));24console.log(toMemberName('myMethod2'));25const { toMemberName } = require('playwright
Using AI Code Generation
1const { toMemberName } = require('playwright-core/lib/server/helper');2const name = toMemberName('someName');3console.log(name);4const { toMemberName } = require('playwright/lib/server/helper');5const name = toMemberName('someName');6console.log(name);7const { toMemberName } = require('playwright-chromium/lib/server/helper');8const name = toMemberName('someName');9console.log(name);10const { toMemberName } = require('playwright-firefox/lib/server/helper');11const name = toMemberName('someName');12console.log(name);13const { toMemberName } = require('playwright-webkit/lib/server/helper');14const name = toMemberName('someName');15console.log(name);16const { toMemberName } = require('playwright/lib/helper');17const name = toMemberName('someName');18console.log(name);19const { toMemberName } = require('playwright-chromium/lib/helper');20const name = toMemberName('someName');21console.log(name);22const { toMemberName } = require('playwright-firefox/lib/helper');23const name = toMemberName('someName');24console.log(name);25const { toMemberName } = require('playwright-webkit/lib/helper');26const name = toMemberName('someName');27console.log(name);28const { toMemberName } = require('playwright/lib/api/helper');29const name = toMemberName('someName');30console.log(name);31const { toMemberName } = require('playwright-chromium/lib/api/helper');32const name = toMemberName('someName');33console.log(name);34const { toMemberName } = require('playwright-firefox
Using AI Code Generation
1import { toMemberName } from '@playwright/test/lib/server/frames';2export async function getMemberName(page) {3 const elementHandle = await page.$('div');4 const memberName = toMemberName(elementHandle);5 console.log(memberName);6}7const { toMemberName } = require('@playwright/test/lib/server/frames');8async function getMemberName(page) {9 const elementHandle = await page.$('div');10 const memberName = toMemberName(elementHandle);11 console.log(memberName);12}13import { toMemberName } from '@playwright/test/lib/server/frames';14const { toMemberName } = require('@playwright/test/lib/server/frames');15export async function getMemberName(page) {16 const elementHandle = await page.$('div');17 const memberName = toMemberName(elementHandle);18 console.log(memberName);19}20async function getMemberName(page) {21 const elementHandle = await page.$('div');22 const memberName = toMemberName(elementHandle);23 console.log(memberName);24}25import { toMemberName } from '@playwright/test/lib/server/frames';26export async function getMemberName(page) {27 const elementHandle = await page.$('div');28 const memberName = toMemberName(elementHandle);29 console.log(memberName);30}31const { toMemberName } = require('@playwright/test/lib/server/frames');32async function getMemberName(page) {33 const elementHandle = await page.$('div');34 const memberName = toMemberName(elementHandle);35 console.log(memberName);36}37import { toMemberName } from '@playwright/test/lib/server/frames';38const { toMemberName } = require('@playwright/test/lib/server/frames');39export async function getMemberName(page) {40 const elementHandle = await page.$('div');41 const memberName = toMemberName(elementHandle);42 console.log(memberName);43}44async function getMemberName(page) {45 const elementHandle = await page.$('div');46 const memberName = toMemberName(elementHandle);47 console.log(memberName);48}49import {
Jest + Playwright - Test callbacks of event-based DOM library
firefox browser does not start in playwright
Is it possible to get the selector from a locator object in playwright?
How to run a list of test suites in a single file concurrently in jest?
Running Playwright in Azure Function
firefox browser does not start in playwright
This question is quite close to a "need more focus" question. But let's try to give it some focus:
Does Playwright has access to the cPicker object on the page? Does it has access to the window object?
Yes, you can access both cPicker and the window object inside an evaluate call.
Should I trigger the events from the HTML file itself, and in the callbacks, print in the DOM the result, in some dummy-element, and then infer from that dummy element text that the callbacks fired?
Exactly, or you can assign values to a javascript variable:
const cPicker = new ColorPicker({
onClickOutside(e){
},
onInput(color){
window['color'] = color;
},
onChange(color){
window['result'] = color;
}
})
And then
it('Should call all callbacks with correct arguments', async() => {
await page.goto(`http://localhost:5000/tests/visual/basic.html`, {waitUntil:'load'})
// Wait until the next frame
await page.evaluate(() => new Promise(requestAnimationFrame))
// Act
// Assert
const result = await page.evaluate(() => window['color']);
// Check the value
})
Check out the latest blogs from LambdaTest on this topic:
Native apps are developed specifically for one platform. Hence they are fast and deliver superior performance. They can be downloaded from various app stores and are not accessible through browsers.
One of the essential parts when performing automated UI testing, whether using Selenium or another framework, is identifying the correct web elements the tests will interact with. However, if the web elements are not located correctly, you might get NoSuchElementException in Selenium. This would cause a false negative result because we won’t get to the actual functionality check. Instead, our test will fail simply because it failed to interact with the correct element.
Smartphones have changed the way humans interact with technology. Be it travel, fitness, lifestyle, video games, or even services, it’s all just a few touches away (quite literally so). We only need to look at the growing throngs of smartphone or tablet users vs. desktop users to grasp this reality.
As part of one of my consulting efforts, I worked with a mid-sized company that was looking to move toward a more agile manner of developing software. As with any shift in work style, there is some bewilderment and, for some, considerable anxiety. People are being challenged to leave their comfort zones and embrace a continuously changing, dynamic working environment. And, dare I say it, testing may be the most ‘disturbed’ of the software roles in agile development.
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!