Био сам у фронт-енд развоју довољно дуго да видим тренд током година: млађи програмери који раде са новом парадигмом програмирања без разумевања њеног историјског контекста. Наравно, сасвим је разумљиво не знати нешто. Веб је веома велико место са разноликим скупом вештина и специјалности, а ми не знамо увек шта не знамо. Учење у овој области је стално путовање, а не нешто што се дешава једном и завршава. Случај: Неко из мог тима је питао да ли је могуће утврдити да ли корисници одлазе са одређене картице у корисничком интерфејсу. Указао сам на догађај пре деунлоада ЈаваСцрипт-а. Али они који су се с тим раније позабавили знају да је то могуће јер су били погођени упозорењима о несачуваним подацима на другим сајтовима, за које је преунлоад типичан случај употребе. Такође сам колегиници истакао догађаје странице Сакриј и висибилитиЦханге за добру меру. Како сам знао за то? Зато што се појавио у другом пројекту, а не зато што сам га проучавао када сам у почетку учио ЈаваСцрипт. Чињеница је да савремени фронт-енд оквири стоје на раменима технолошких гиганата који су им претходили. Они апстрахују развојне праксе, често за боље искуство програмера који смањују, или чак елиминишу, потребу да се зна или додирне оно што су традиционално били суштински концепти фронт-енда које би сви вероватно требали знати. Размотрите ЦСС објектни модел (ЦССОМ). Можете очекивати да свако ко ради у ЦСС-у и ЈаваСцрипт-у има гомилу практичног ЦССОМ искуства, али то неће увек бити случај. Постојао је Реацт пројекат за веб локацију за е-трговину на којој сам радио где смо морали да учитамо листу стилова за тренутно изабраног добављача плаћања. Проблем је био у томе што се табела стилова учитавала на свакој страници када је заиста била потребна само на одређеној страници. Програмер који је имао задатак да ово оствари никада није динамички учитао листу стилова. Опет, ово је потпуно разумљиво када Реацт апстрахује традиционални приступ за којим сте можда посегнули. ЦССОМ вероватно није нешто што вам треба у свакодневном раду. Али вероватно ћете морати да ступите у интеракцију са њим у неком тренутку, чак и у једном случају. Ова искуства су ме инспирисала да напишем овај чланак. Постоје многе постојеће веб функције и технологије у дивљини које можда никада нећете додирнути директно у свом свакодневном раду. Можда сте прилично нови у развоју веба и једноставно их нисте свесни јер сте уроњени у апстракцију специфичног оквира који не захтева да га познајете дубоко, или чак уопште. Говорим конкретно о КСМЛ-у, за који многи од нас знају да је древни језик који није потпуно сличан ХТМЛ-у. Помињем ово због недавних ВХАТВГ дискусија које сугеришу да би значајан део КСМЛ стека познат као КССЛТ програмирање требало да буде уклоњен из претраживача. Ово је управо она врста старије, постојеће технологије коју смо имали годинама и која би се могла користити за нешто тако практично као што је ЦССОМ ситуација у којој се налазио мој тим. Да ли сте раније радили са КССЛТ-ом? Хајде да видимо да ли се у великој мери ослањамо на ову старију технологију и искористимо њене карактеристике ван контекста КСМЛ-а да бисмо се данас позабавили проблемима из стварног света. КСПатх: Централни АПИ Најважнија КСМЛ технологија која је можда најкориснија изван директне КСМЛ перспективе је КСПатх, језик упита који вам омогућава да пронађете било који чвор или атрибут у стаблу за означавање са једним основним елементом. Имам личну наклоност према КССЛТ-у, али то се такође ослања на КСПатх, а лична наклоност се мора оставити по страни у важности рангирања. Аргумент за уклањање КССЛТ-а не помиње КСПатх, па претпостављам да је и даље дозвољен. То је добро јер је КСПатх централни и најважнији АПИ у овом скупу технологија, посебно када покушавате да нађете нешто за коришћење ван нормалне употребе КСМЛ-а. То је важно јер, иако се ЦСС селектори могу користити за проналажење већине елемената на вашој страници, они их не могу пронаћи све. Штавише, ЦСС селектори се не могу користити за проналажење елемента на основу његове тренутне позиције у ДОМ-у. КСПатх може. Неки од вас који ово читају можда знају КСПатх, а неки не. КСПатх је прилично велика област технологије и не могу заиста да научим све основе и да вам покажем сјајне ствари које можете да урадите са тим у једном оваквом чланку. Заправо сам покушао да напишем тај чланак, али просечна публикација Смасхинг Магазина не прелази 5.000 речи. Већ сам био на више од2.000 речи док је само на пола пута кроз основе. Дакле, почећу да радим сјајне ствари са КСПатх-ом и даћу вам неке везе које можете користити за основе ако сматрате да су ове ствари занимљиве. Комбиновање КСПатх и ЦСС КСПатх може да уради много ствари које ЦСС селектори не могу када постављају упите елементима. Али ЦСС селектори такође могу да ураде неколико ствари које КСПатх не може, наиме, упити елементе по имену класе.
ЦСС КСПатх .миЦласс /*[садржи(@цласс, "моја класа")]
У овом примеру, ЦСС поставља упите за елементе који садрже име класе .миЦласс. У међувремену, КСПатх пример испитује елементе који садрже класу атрибута са стрингом „миЦласс“. Другим речима, он бира елементе са миЦласс у било ком атрибуту, укључујући елементе са именом класе .миЦласс — као и елементе са „миЦласс“ у стрингу, као што је .миЦласс2. КСПатх је шири у том смислу. Дакле, не. Не сугеришем да би требало да избацимо ЦСС и почнемо да бирамо све елементе преко КСПатх-а. То није поента. Поента је у томе да КСПатх може да ради ствари које ЦСС не може и може да буде веома користан, иако је то старија технологија у стеку претраживача и можда на први поглед не изгледа очигледно. Хајде да заједно користимо ове две технологије не само зато што можемо, већ зато што ћемо научити нешто о КСПатх-у у процесу, чинећи га још једним алатом у вашој групи – за који можда нисте знали да постоји све време! Проблем је у томе што ЈаваСцрипт метода доцумент.евалуате и различите методе селектора упита које користимо са ЦСС АПИ-јима за ЈаваСцрипт нису компатибилни. Направио сам компатибилан АПИ за упите да бисмо започели, мада морам признати да нисам много размишљао о томе јер је то одступање од онога што радимо овде. Ево прилично једноставног радног примера конструктора упита за вишекратну употребу: Погледајте Пен куериКСПатх [форкед] од Брајана Расмусена. Додао сам две методе на објекат документа: куериЦСССелецторс (који је у суштини куериСелецторАлл) и куериКСПатхс. Оба ова враћају објекат куериРесултс:
{ куериТипе: чворови | стринг | број | боолеан, резултати: било који[] // хтмл елементи, кмл елементи, стрингови, бројеви, логичке вредности, куериЦСССелецторс: (упит: стринг, изменити: боолеан) => куериРесултс, куериКспатхс: (упит: стринг, изменити: боолеан) => куериРесултс }
Функције куериЦСССелецторс и куериКспатхс покрећу упит који им дате над елементима у низу резултата, све док је низ резултата типа чворова, наравно. У супротном, вратиће куериРесулт са празним низом и типом чворова. Ако је својство измене постављено на тачно, функције ће променити сопствене резултате упита. Ни у ком случају ово не би требало да се користи у производном окружењу. Радим то на овај начин чисто да бих показао различите ефекте заједничког коришћења два АПИ-ја за упите. Пример упита Желим да покажем неколико примера различитих КСПатх упита који показују неке од моћних ствари које могу да ураде и како се могу користити уместо других приступа. Први пример је //ли/тект(). Ово испитује све ли елементе и враћа њихове текстуалне чворове. Дакле, ако бисмо тражили следећи ХТМЛ: <ул> <ли>једанли> <ли>двали> <ли>трили> ул>
… ево шта се враћа:
{"куериТипе":"кпатхЕвалуате","ресултс":["један","тво","тхрее"],"ресултТипе":"стринг"}
Другим речима, добијамо следећи низ: ["један","два","три"]. Обично бисте тражили елементе ли да бисте то добили, претворили резултат тог упита у низ, мапирали низ и вратили текстуални чвор сваког елемента. Али то можемо учинити сажетије са КСПатх-ом: доцумент.куериКСПатхс("//ли/тект()").резултати.
Приметите да је начин да добијете текстуални чвор коришћење текста(), који изгледа као потпис функције — и јесте. Враћа текстуални чвор елемента. У нашем примеру, постоје три елемента ли у маркупу, од којих сваки садржи текст („један“, „два“ и „три“). Погледајмо још један пример текста() упита. Претпоставимо да је ово наша ознака: <па хреф="/логин.хтмл">Пријавите сеа>
Хајде да напишемо упит који враћа вредност атрибута хреф: доцумент.куериКСПатхс("//а[тект() = 'Пријава']/@хреф").резултати.
Ово је КСПатх упит за тренутни документ, баш као и последњи пример, али овог пута враћамо хреф атрибут везе (елемента) који садржи текст „Пријава“. Стварни се вратиорезултат је ["/логин.хтмл"]. Преглед КСПатх функција Постоји велики број КСПатх функција и вероватно нисте упознати са њима. Постоји неколико, мислим, о којима вреди знати, укључујући следеће:
стартс-витхАко текст почиње одређеним другим примером текста, стартс-витх(@хреф, 'хттп:') враћа тачно ако атрибут хреф почиње са хттп:. цонтаинсАко текст садржи одређени други пример текста, цонтаинс(тект(), "Смасхинг Магазине") враћа труе ако текстуални чвор садржи речи "Смасхинг Магазине" било где у себи. цоунтВраћа број колико подударања има упит. На пример, цоунт(//*[стартс-витх(@хреф, 'хттп:']) враћа број колико веза у чвору контекста има елемената са атрибутом хреф који садржи текст који почиње са хттп:. субстринг Ради као ЈаваСцрипт подстринг, осим што проследите стринг као аргумент. На пример, субстринг("мој текст", 2, 4) враћа "и т". субстринг-бефоре Враћа део стринга пре другог стринга. На пример, субстинг-бефоре("мој текст", " ") враћа "мој". Слично, субстринг-бефоре("хи","бие") враћа празан стринг. субстринг-афтер Враћа део стринга после другог стринга. На пример, субстинг-афтер("мој текст", " ") враћа "текст". Слично, субстринг-афтер("хи","бие") враћа празан стринг. нормализе-спаце Враћа стринг аргумената са размаком нормализованим уклањањем водећих и завршних размака и заменом секвенци размака једним размаком. нотВраћа логички вредност труе ако је аргумент лажан, у супротном нетачан. труеВраћа боолеан труе. фалсеВраћа боолеан фалсе. цонцатИста ствар као и ЈаваСцрипт цонцат, осим што га не покрећете као метод на стрингу. Уместо тога, ставите све низове које желите да спојите. стринг-ленгтхОво није исто што и дужина стринга ЈаваСцрипт-а, већ враћа дужину стринга који је дат као аргумент. транслатеТхис узима стринг и мења други аргумент у трећи аргумент. На пример, транслате("абцдеф", "абц", "КСИЗ") даје КСИЗдеф.
Осим ових конкретних КСПатх функција, постоји низ других функција које функционишу исто као и њихове ЈаваСцрипт колеге — или у основи било ком програмском језику — које би вам вероватно такође биле корисне, као што су под, плафон, округло, збир и тако даље. Следећи демо илуструје сваку од ових функција: Погледајте нумеричке функције Пен КСПатх [рачване] од Брајана Расмусена. Имајте на уму да, као и већина функција за манипулацију стринговима, многе нумеричке имају један улаз. Ово је, наравно, зато што би требало да се користе за упите, као у последњем КСПатх примеру: //ли[флоор(тект()) > 250]/@вал
Ако их користите, као што то чини већина примера, на крају ћете га покренути на првом чвору који одговара путањи. Постоје и неке функције конверзије типова које би вероватно требало да избегавате јер ЈаваСцрипт већ има своје проблеме са конверзијом типова. Али може бити тренутака када желите да конвертујете низ у број да бисте га проверили са неким другим бројем. Функције које постављају тип нечега су боолеан, број, стринг и чвор. Ово су важни КСПатх типови података. И као што можете замислити, већина ових функција се може користити на типовима података који нису ДОМ чворови. На пример, субстринг-афтер узима стринг као што смо већ покрили, али то може бити стринг из атрибута хреф. Такође може бити само низ:
цонст тестСубстрингАфтер = доцумент.куериКСПатхс("субстринг-афтер('хелло ворлд',' ')");
Очигледно, овај пример ће нам вратити низ резултата као [„свет“]. Да бих ово показао на делу, направио сам демо страницу користећи функције против ствари које нису ДОМ чворови: Погледајте Пен куериКСПатх [форкед] од Брајана Расмусена. Требало би да приметите изненађујући аспект функције превођења, а то је да ако имате знак у другом аргументу (тј. листу знакова које желите да преведете) и нема одговарајућих знакова за превођење, тај знак се уклања из излаза. Дакле, ово:
транслате('Здраво, моје име је Иниго Монтоја, убио си мог оца, припреми се да умреш','абцдефгхијклмнопкрстуввкизАБЦДЕФГХИЈКЛМНОПКРСТУВВКСИЗ,','*')
…резултати у стрингу, укључујући размаке: [" * * ** "]
То значи да се слово „а“ преводи у звездицу (*), али сваки други знак који нема превод с обзиром на циљни низ је потпуно уклоњен. Бели размак је све што нам је осталоизмеђу преведених знакова „а“. Онда опет, овај упит:
транслате('Здраво, моје име је Иниго Монтоја, убио си мог оца, припреми се да умреш','абцдефгхијклмнопкрстуввкизАБЦДЕФГХИЈКЛМНОПКРСТУВВКСИЗ,','*******************************************************')")
...нема проблем и даје резултат који изгледа овако:
"***** ** **** ** ***** ******* *** ****** ** ****** ******* ** ***"
Можда вам падне на памет да у ЈаваСцрипт-у не постоји једноставан начин да се уради тачно оно што КСПатх транслате функција ради, иако у многим случајевима то може да реши реплацеАлл са регуларним изразима. Можете користити исти приступ који сам демонстрирао, али то је неоптимално ако је све што желите да преведете низове. Следећи демо обухвата КСПатх-ову функцију превођења да би обезбедио ЈаваСцрипт верзију: Погледајте функцију превођења оловком [форкед] од Брајана Расмусена. Где бисте могли да користите нешто овако? Размислите о шифровању Цезарове шифре са помаком од три места (нпр. врхунско шифровање из 48. п.н.е.):
транслате("Цезар планира да пређе Рубикон!", „АБЦДЕФГХИЈКЛМНОПКРСТУВВКСИЗабцдефгхијклмнопкрстуввкиз“, „КСИЗАБЦДЕФГХИЈКЛМНОПКРСТУВВкизабцдефгхијклмнопкрстувв“)
Улазни текст „Цезар планира да пређе Рубикон!“ резултира „Зкбпко фп микккфкд кл золпп кеб Орифзлк!“ Да дам још један брзи пример различитих могућности, направио сам металну функцију која узима стринг инпут и користи функцију превођења за враћање текста, укључујући све знакове који узимају умлауте. Погледајте функцију Пен метал [рачвано] од Брајана Расмусена.
цонст метал = (стр) => { ретурн транслате(стр, "АОУаоу","АОУаоу"); }
И, ако добијете текст „Мотлеи Цруе рулес, роцк он дудес!“, враћа „Мотлеи Цруе рулес, роцк он дудес!“ Очигледно, неко може имати разне пародијске употребе ове функције. Ако сте то ви, онда би овај чланак ТВТропес требао да вам пружи доста инспирације. Коришћење ЦСС-а са КСПатх-ом Запамтите наш главни разлог за коришћење ЦСС селектора заједно са КСПатх-ом: ЦСС прилично разуме шта је класа, док је најбоље што можете да урадите са КСПатх-ом упоређивање стрингова атрибута класе. То ће радити у већини случајева. Али ако бисте икада наишли у ситуацију да је, рецимо, неко креирао класе под називом .примариЛинкс и .примариЛинкс2, а ви користите КСПатх да бисте добили класу .примариЛинкс, онда бисте вероватно наишли на проблеме. Све док нема ништа слично томе, вероватно бисте користили КСПатх. Али са тугом могу да кажем да сам радио на местима где људи раде такве глупости. Ево још једне демонстрације која заједно користи ЦСС и КСПатх. Показује шта се дешава када користимо код да покренемо КСПатх на чвору контекста који није чвор документа. Погледајте Пен цсс и кпатх заједно [рачване] од Брајана Расмусена. ЦСС упит је .релатедартицлес а, који преузима два елемента а у див-у коме је додељена класа .релатедартицлес. Након тога следе три „лоша“ упита, односно упити који не раде оно што желимо да раде када се покрећу са овим елементима као контекстним чвором. Могу да објасним зашто се понашају другачије него што бисте очекивали. Три лоша упита у питању су:
//тект(): Враћа сав текст у документу. //а/тект(): Враћа сав текст унутар веза у документу. ./а/тект(): Не даје резултате.
Разлог за ове резултате је тај што, иако је ваш контекст елементи враћени из ЦСС упита, // иде против целог документа. Ово је снага КСПатх-а; ЦСС не може да иде од чвора до претка, а затим до брата или сестре тог претка, и да иде доле до потомка тог брата и сестре. Али КСПатх може. У међувремену, ./ испитује потомке тренутног чвора, где тачка (.) представља тренутни чвор, а коса црта (/) представља одлазак до неког подређеног чвора — да ли је то атрибут, елемент или текст, одређује се следећим делом путање. Али не постоји подређени елемент изабран ЦСС упитом, тако да тај упит такође ништа не враћа. У последњој демонстрацији постоје три добра упита:
.//тект(), ./тект(), нормализе-спаце(./тект()).
Упит за нормализацију простора демонстрира употребу КСПатх функције, али такође решава проблем укључен у друге упите. ХТМЛ је структуриран овако:
<а хреф="хттпс://ввв.смасхингмагазине.цом/2018/04/феатуре-тестинг-селениум-вебдривер/"> Аутоматизација тестирања функција помоћу Селениум ВебДривер-а а>
Упит враћа линију на почетку и на крају текстуалног чвора,а нормализе-спаце уклања ово. Коришћење било које КСПатх функције која враћа нешто друго осим логичког са уносом КСПатх примењује се на друге функције. Следећи демо показује неколико примера: Погледајте примере Пен кпатх функција [рачване] од Брајана Расмусена. Први пример показује проблем на који треба да пазите. Конкретно, следећи код:
доцумент.куериКСПатхс("субстринг-афтер(//а/@хреф,'хттпс://')");
… враћа један стринг:
„ввв.смасхингмагазине.цом/2018/04/феатуре-тестинг-селениум-вебдривер/“
Има смисла, зар не? Ове функције не враћају низове, већ појединачне низове или појединачне бројеве. Покретање функције било где са више резултата враћа само први резултат. Други резултат показује шта заиста желимо:
доцумент.куериЦСССелецторс("а").куериКСПатхс("субстринг-афтер(./@хреф,'хттпс://')");
Који враћа низ од два стринга:
["ввв.смасхингмагазине.цом/2018/04/феатуре-тестинг-селениум-вебдривер/","ввв.смасхингмагазине.цом/2022/11/аутоматед-тест-ресултс-импрове-аццессибилити/"]
КСПатх функције могу бити угнежђене као функције у ЈаваСцрипт-у. Дакле, ако знамо УРЛ структуру Смасхинг Магазине, могли бисмо да урадимо следеће (препоручује се коришћење шаблонских литерала): `преведи( подниз( субстринг-афтер(./@хреф, 'ввв.смасхингмагазине.цом/') ,9), '/','')`
Ово постаје превише сложено до те мере да су му потребни коментари који описују шта ради: узмите сву УРЛ адресу из атрибута хреф после ввв.смасхингмагазине.цом/, уклоните првих девет знакова, а затим преведите косу црту (/) у ништа да бисте се решили завршне косе црте унапред. Добијени низ:
["феатуре-тестинг-селениум-вебдривер","аутоматед-тест-ресултс-импрове-аццессибилити"]
Више КСПатх случајева употребе КСПатх заиста може да заблиста у тестирању. Разлог није тешко уочити, пошто се КСПатх може користити за добијање сваког елемента у ДОМ-у, са било које позиције у ДОМ-у, док ЦСС не може. Не можете рачунати на то да ће ЦСС класе остати конзистентне у многим модерним системима градње, али са КСПатх-ом, ми смо у могућности да направимо робуснија подударања у погледу садржаја текста елемента, без обзира на промену ДОМ структуре. Било је истраживања о техникама које вам омогућавају да направите отпорне КСПатх тестове. Ништа није горе од тога да тестови нестану и не успеју само зато што ЦСС селектор више не ради јер је нешто преименовано или уклоњено. КСПатх је такође заиста одличан у екстракцији вишеструких локатора. Постоји више од једног начина да користите КСПатх упите за подударање са елементом. Исто важи и за ЦСС. Али КСПатх упити могу детаљније анализирати ствари на циљанији начин који ограничава оно што се враћа, омогућавајући вам да пронађете одређено подударање где може постојати неколико могућих подударања. На пример, можемо да користимо КСПатх да вратимо одређени х2 елемент који се налази унутар дива који одмах следи братски див који, заузврат, садржи подређени елемент слике са атрибутом дата-тестИД="леадер" на себи: <див> <див> <х1>немојте схватити овај насловх1> див>
<див> <х2>Не разумејте ни овај насловх2> див>
<див> <х2>Заглавље за главну сликух2> див>
<див> <имг дата-тестИД="леадер" срц="имаге.јпг"/> див> див>
Ово је упит: доцумент.куериКСПатхс(` //див[ нект-сиблинг::див[1] /имг[@дата-тестИД='леадер'] ] /х2/ текст() `);
Хајде да убацимо демо да видимо како се све то спаја: Погледајте Пен Цомплек Х2 упит [форкед] од Брајана Расмусена. Дакле, да. Постоји много могућих путања до било ког елемента у тесту који користи КСПатх. Застарелост КССЛТ 1.0 Рано сам споменуо да Цхроме тим планира да уклони подршку за КССЛТ 1.0 из претраживача. То је важно јер КССЛТ 1.0 користи програмирање фокусирано на КСМЛ за трансформацију докумената који се, заузврат, ослања на КСПатх 1.0, који се налази у већини претраживача. Када се то догоди, изгубићемо кључну компоненту КСПатх-а. Али с обзиром на чињеницу да је КСПатх заиста одличан за писање тестова, сматрам да је мало вероватно да ће КСПатх као целина ускоро нестати. Уз то, приметио сам да се људи заинтересују за неку функцију када се она одузме. И то је свакако тачно у случају да је КССЛТ 1.0 застарео. У Хацкер Невс-у се одвија цела дискусија пуна аргумената против застаревања. Сам пост је одличан пример креирања оквира за блоговање помоћу КССЛТ-а. Виможете сами да прочитате дискусију, али улази у то како би ЈаваСцрипт могао да се користи као подлога за КСЛСТ за решавање оваквих случајева. Такође сам видео предлоге да прегледачи треба да користе СаконЈС, који је порт за ЈаваСцрипт-ове Сакон КССЛТ, КСКУЕРИ и КСПатх машине. То је занимљива идеја, посебно пошто Сакон-ЈС имплементира тренутну верзију ових спецификација, док не постоји претраживач који имплементира било коју верзију КСПатх-а или КССЛТ-а новију од 1.0, и ниједан који имплементира КСКуери. Контактирао сам Норма Товеи-Валсха из Саконица, компаније иза СаконЈС-а и других верзија Сакон мотора. рекао је: „Ако је било који добављач претраживача заинтересован да узме СаконЈС као полазну тачку за интеграцију модерних КСМЛ технологија у претраживач, били бисмо одушевљени да о томе разговарамо са њима.“ – Норм Товеи-Валсх
Али и додао: "Био бих веома изненађен када би неко помислио да би узимање СаконЈС-а у његовом тренутном облику и његово убацивање у верзију претраживача непромењеног било идеалан приступ. Продавац претраживача, по природи чињенице да изграђује претраживач, може приступити интеграцији на много дубљем нивоу него што ми можемо 'извана'." - Норм Товеи-Валсх
Вреди напоменути да су Товеи-Валсх-ови коментари дошли отприлике недељу дана пре најаве застаревања КССЛТ-а. Закључак Могао бих да набрајам. Али надам се да је ово показало моћ КСПатх-а и дало вам много примера који показују како да га користите за постизање великих ствари. То је савршен пример старије технологије у групи претраживача која и данас има много корисних својстава, чак и ако никада нисте знали да постоји или никада нисте размишљали да посегнете за њом. Даље читање
„Побољшање отпорности аутоматизованих веб тестова природним језиком“ (АЦМ дигитална библиотека) аутора Маруна Ајлија, Јусефа Бакунија, Надера Јалоула и Риме Килани. Овај чланак пружа много КСПатх примера за писање отпорних тестова. КСПатх (МДН)Ово је одлично место за почетак ако желите техничко објашњење које детаљно описује како КСПатх функционише. КСПатх туторијал (ЗВОН) Сматрам да је овај водич најкориснији у мом сопственом учењу, захваљујући обиљу примера и јасних објашњења. КСПатхерОва интерактивна алатка вам омогућава да радите директно са кодом.