Pokazywanie postów oznaczonych etykietą plugin. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą plugin. Pokaż wszystkie posty

poniedziałek, 22 lipca 2013

Selenium - software testing framework for web applications

Przeglądając wykład Grzegorza Dudy podczas konferencji confitura 2012 pt. From Busy to Effective Developer odkryłem fajne, nowe narzędzie, które zademonstrował Grzegorz. Narzędzie nazywa się selenium i służy do testowania stron internetowych. O ile, nie wgłębiałem się szczegółowo w API tego narzędzia, to jego podstawowa funkcjonalność, dostępna jako plug-in do przeglądardki firefox służy do nagrywania/reprodukcji schematu poruszania się po stronie internetowej.

Czasami zdarza się bowiem, że aby odtworzyć błąd, trzeba się 'przeklikać' przez wiele formularzy (i dopiero wtedy podpiąć debugger). W takich właśnie momentach przydaje się Selenium. Za pierwszym razem, przeklikując się przez formularze włączamy opcję 'rejestrowania', a przy nast., okazji, gdy potrzebujemy wykonać identyczną operację tylko włączamy opcję odtwarzania poprzednio zapisanego scenariusza testowego.

Narzędzie dostępne jest na licencji Apache 2.0 więc spokojnie możemy z niego korzystać, a nawet rozwijać.

piątek, 1 marca 2013

Pinterest / Blocksit layout

Jednym z najnowszych "krzyków mody", jest wyświetlanie newsów na stronie internetowej w "pseudo-tabelaryczny" sposób. Jest to sposób, który na pierwszy rzut oka przypomina nieco tabelę, ale nią nie jest, czyli dane ustawione są w kolumny, ale wysokość wierszy jest różna i zależna od ilości contentu (wysokość zdjęcia, ilość i długość komentarzy do zdjęcia itp.). Dodatkowo, resizując stronę (zmniejszając lub zwiększając okno przeglądarki) newsy się przestawiają w swojej "pseudo tabeli". Jako pierwsze (ale mogę się mylić), taki layout graficzny zastosowało na swojej stronie https://pinterest.com/, dlatego nazwałem ten layout "pinterest layout".

Teoretycznie, można by było zalogować się na stronę https://pinterest.com/ i spróbować przekopiować ich layout, ale takie rozwiązanie nie było by ani zbyt grzeczne, ani zbyt moralnie poprawne. Na szczęście dzięki www.google.com udało mi się znaleźć stronę, która zagregowała 'know how", czyli link do wtfdiary.com, na którym jest 6 'know how to do pinterest loyout'.

Mi osobiście najbardziej przypadł do gustu BlocksIt.js dlatego w dalszej części skupię się właśnie na tym rozwiązaniu. Jego zalety:
- to łatwość i prostota obsługi,
- ładny wygląd zewnętrzny,
- przystępny tutorial (zawierający 2 projekty demo)
- licencja  GNU GPL 2.0

Samo rozwiązanie nie jest niczym innym, jak wykorzystaniem biblioteki jQuery oraz dołączeniem do niego odpowiedniego jQuery plugin. Do tego dochodzą nam style CSS (ostylowanie naszego contentu) oraz kilka prostych skrytpów javascript (m.in. wykorzystywanych podczas resizowania strony).

To co potrzebujemy to pobrać najnowszą wersję biblioteki query oraz plik zip z demami blocksit

Moje rozwiązanie, które tutaj przedstawię, w dużej mierze opiera się na demie, które można pobrać z linku powyżej i jest to jedynie dostosowanie tego dema do aplikacji typu .net (asp.net / sharepoint).

Aby wykorzystać 'Blocksit' tworzymy nową stronę .aspx (może to być kontrolka .ascx), następnie do projektu dodajemy odpowiednie pliki:
- jquery-1.9.1.min (najnowsza wersja jquery w dniu 2013-03-01)
- blocksit.min (znajduje się w pliku z demem blocksit  - \blocksit-js\blocksit\demo2)
- style.css (znajduje się w pliku z demem blocksit - \blocksit-js\blocksit\demo2)
- zchpitblocksitdemo.js  (nasz plik ze skryptami, jakie będziemy utuchamiać na stronie)

Standardowo te skrypty były na stronie z demem, ale ja wolałem je przenieść do osobnego pliku .js i wyglądają one następująco:

$(document).ready(function () {
    //vendor script
    $('#header')
    .css({ 'top': -50 })
    .delay(1000)
    .animate({ 'top': 0 }, 800);

    $('#footer')
    .css({ 'bottom': -15 })
    .delay(1000)
    .animate({ 'bottom': 0 }, 800);

    //blocksit define
    $(window).load(function () {
        $('#container').BlocksIt({
            numOfCol: 5,
            offsetX: 8,
            offsetY: 8,
            blockElement: '.grid'
        });
    });

    //window resize
    var currentWidth = 1100;
    $(window).resize(function () {
        var winWidth = $(window).width();
        var conWidth;
        if (winWidth < 660) {
            conWidth = 440;
            col = 2
        } else if (winWidth < 880) {
            conWidth = 660;
            col = 3
        } else if (winWidth < 1100) {
            conWidth = 880;
            col = 4;
        } else {
            conWidth = 1100;
            col = 5;
        }

        if (conWidth != currentWidth) {
            currentWidth = conWidth;
            $('#container').width(conWidth);
            $('#container').BlocksIt({
                numOfCol: col,
                offsetX: 8,
                offsetY: 8
            });
        }
    });
});
 Ok. Przejdźmy zatem do omówienia najważniejszej części, czyli kodu strony .aspx / kontrolki .ascx:

Aby uzyskać ten layout, teoretycznie nie potrzebujemy żadnego 'code behind' i wystarczy nam czysty html, który docelowo powinien wyglądać podobnie jak na stronie z dema, czyli mniej więcej tak:

<link rel="stylesheet" href="/_layouts/style.css" type="text/css" />
<script src="/_layouts/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="/_layouts/blocksit.min.js" type="text/javascript"></script>
<script src="/_layouts//zchpitblocksitdemo.js" type="text/javascript"></script>
<div id="container">
    <div class="grid">
        <div class="imgholder">
            <img src="http://www.inwebson.com/demo/blocksit-js/demo2/images/img26.jpg" />
        </div>
        <strong>Bridge to Heaven</strong>
        <p>Where is the bridge lead to?</p>
        <div class="meta">by SigitEko</div>
    </div>
    <div class="grid">
        <div class="imgholder">
            <img src="http://www.inwebson.com/demo/blocksit-js/demo2/images/img15.jpg" />
        </div>
        <strong>Autumn</strong>
        <p>The fall of the tree...</p>
        <div class="meta">by Lars van de Goor</div>
    </div>
</div>
Aby jednak uzyskać, w pełni dynamicznie generowany przez nas layout, skorzystamy z kontrolki literala, czyli nasz kod html będzie wyglądał tak:

<link rel="stylesheet" href="/_layouts/style.css" type="text/css" />
<script src="/_layouts/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="/_layouts/blocksit.min.js" type="text/javascript"></script>
<script src="/_layouts//zchpitblocksitdemo.js" type="text/javascript"></script>

<div id="container">
    <asp:Literal runat="server" ID="ltrGrid" ></asp:Literal>
</div>
W tym przypadku, będziemy potrzebowali stworzyć 'code behind', który w najprostszym możliwym przypadku będzie wyglądał tak:

        protected void Page_Load(object sender, EventArgs e)
        {
            SetLiteralGrid();
        }
        private void SetLiteralGrid()
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("<div class='grid'>");
            sb.AppendLine("<div class='imgholder'>");
            sb.AppendLine("<img src='http://www.inwebson.com/demo/blocksit-js/demo2/images/img27.jpg' />");
            sb.AppendLine("</div>");
            sb.AppendLine("<strong>Sunset Lake</strong>");
            sb.AppendLine("<p>A peaceful sunset view...</p>");
            sb.AppendLine("<div class='meta'>by j osborn</div>");
            sb.AppendLine("</div>");

            ltrGrid.Text = sb.ToString();
        }
 Oczywiście w realnych scenariuszach interesuje nas wypełnienie contentem pełnej strony (a nie tylko pojedyńczego newsa), ale wtedy w 'code behind' wystarczy zwyczajnie wcześniej pobrać potrzebne dane i wrzucić je do StringBuildera za pomocą pętli.



środa, 22 sierpnia 2012

jQuery growfield plugin

Kolejnym bardzo interesującym pluginem jQuery, który chciałbym zaprezentować, jest "growfield", czyli funkcjonalność dynamicznego rozszerzania się textBoxa znana z przeglądarki Mozilla Firefox. Na czym ta funkcjonalność polega? Na tym, że mając textbox i wpisując/usuwając z niego tekst, textbox automatycznie się rozszerza/minimalizuje.
Użytkownicy przeglądarki Mozilla Firefox mają tą funkcję w standardzie, aby jednak uzyskać podobną funkcjonalność w innych przeglądarkach, należy skorzystać z darmowego pluginu jQuery o nazwie "growfield".

Growfield, stanowi część projektu jQuery, i podobnie jak on, udostępniony jest na licencji MIT/X11.
Samo włączenie funkcji autorozszerzania jest banalnie proste i polega na
  • podpięciu odpowiednich bibliotek do projektu (zarówno standardowego jQuery.js w wersji minium 1.8, oraz growfield.js w wersji minimum 1.3),
  • dodaniu referencji do tych plików na stronie asp.net
  • wywołania prostego skryptu jQuery która aktywuje feature na odpowiednim obiekcie
Przykład skryptu aktywującego:

<script type="text/javascript">
    $(function () {
        $('.cssAreaNote').growfield();
    });
</script>

Samo podpięcie 'growfield' nie jest niczym innym, niż wywołanie dodatkowej funkcji na selektorze.W tym konkretnym przykładzie, jako element wyszukujący selektora  użyłem klasy CSS.

Uwaga: w trakcie pracy i testowania tej funkcjonalności spotkałem się z błędem w bibliotece, objawiającym się tym, że czasami do textboxa dopisywane były dodatkowe wartości (dokładnie '111'). Problem był już poruszony na forum StackOveflow. Tak jak ktoś dobrze zauważył, problem polegał na tym, że drugi "textBox" (rozwiązanie opiera się na pomyśle 2x textBoxów, z czego w jednym czasie tylko jeden z nich jest widoczny) miał taką samą nazwę jak pierwszy :/
Rozwiązanie tego problemu jest bardzo proste:
  • bierzemy plik z biblioteką 'growfield.js'
  • odnajdujemy funkcję o nazwie 'createDummy'
  • zmieniamy fragment odpowiadający za tworzenie "kopii zapasowej'' (czyli textBoxa nr.2) na:   
var dummy = o.clone().addClass('growfieldDummy').attr('name', '').attr('id', o.attr('id') + '-dummy')
                               .css({position: 'absolute', left: -9999, top: 0, height: '20px', resize: 'none'})
                               .insertBefore(o).show();

Możliwe, że w momencie, w którym Ty, mój drogi czytelniku pobierzesz najnowszą wersję tej biblioteki, problem będzie już rozwiązany. Możliwe jednak, że... pojawi się również u Ciebie, a wtedy będziesz wiedział co zrobić, aby temu zaradzić ;)

wtorek, 21 sierpnia 2012

jQuery tooltip plugin

Często podczas pracy, zdarza się potrzeba skorzystania z funkcjonalności, której nie posiadają standardowe biblioteki dostarczone przez platformę .NET. Rozwiązania tego problemu są dwa:
  • napisać rozwiązanie samodzielnie
  • skorzystać z gotowego rozwiązania
 Ponieważ jestem przeciwnikiem ponownego odkrywania koła, a po doświadczeniach związanych z pracą (i efektami tej pracy) na kontrolkach firmy DevExpress jestem wielkim fanem korzystania z gotowych rozwiązań wielokrotnie zanim samemu zacznę cokolwiek zacznę kodować, sprawdzam, czy taki problem nie został już przez kogoś innego rozwiązany.
Z uwagi na fakt, iż w mojej obecnej firmie, aktualnie nie posiadamy zakupionych komercyjnych kontrolek firm trzecich, to wykorzystujemy wszelkiego rodzaju rozwiązania dostępne za darmo. Przykładem takich kontrolek, są darmowe pluginy do jQuery. Jednym z takich pluginów jest 'jQuery tooltip plugin' udostępniony za darmo na stronie http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/.
Z pluginem tym, spotkałem się w momencie, gdy w jednej z aplikacji, pojawiła się potrzeba dłuższego czasu wyświetlania tooltipa. Opisy pól w tooltipie były na tyle duże, że normalny człowiek w kilka sek. nie był w stanie ich przeczytać.
Rozwiązaniem okazała się darmowa kontrolka, jQuery tooltip plugin, którą tutaj przedstawiam. Główne zalety kontrolki:
- nielimitowany czas wyświetlania tooltipa
- możliwość schowania tooltipa w momencie wystąpienia zdarzenia jQuery (podpięcie 'schowania' pod event)
- tooltip oraz jego zawartość określana za pomocą edytowalnej klasy CSS
- możliwość umieszczania obrazków, 'image map' oraz linków w tooltipie.
- bardzo łatwa obsługa podpinania komponentu do istniejących rozwiązań (plugin przechwytuje istniejącego tooltipa i się pod niego podszywa).
- licencja MIT pozwalająca na darmowe, komercyjne zastosowanie kontrolek


Samo podpięcie nowego, lepszego tooltipa, do istniejącego rozwiązania z tooltipami jest banalnie proste. Potrzebujemy:
  • dodać do naszego projektu pliki *.js z biblioteką jQuery oraz "jQuery tooltip plugin"
  • umieścić referencje do tych plików, na stronach, na których będziemy się do nich odwoływać (zazwyczaj takie rzeczy umieszcza się w master page)
  • utworzyć nową "pustą" klasę CSS, która będzie nam służyła jako "wskaźnik", dla każdego typu tooltipa (osobny css dla "obrazków", osobny dla "zwykłego tekstu" itp.)
  • dodać referencje do pliku *.css w którym znajduje się nasz znacznik, na stronie, na której będziemy korzystać z tego pluginu (zazwyczaj takie rzeczy umieszcza się w master page)
  •  do każdego obiektu, w którym ma być użyty extra tooltip, dołożyć klasę css odpowiedniego typu
  • upewnić się, że pliki posiadają wypełnioną właściwość "tooltip" (kontrolki asp.net) lub 'title' (kontrolki html).
  • przy uruchamianiu strony, wywołać skrypt aktywujący jQuery plugin tooltip
Na pierwszy rzut oka wydaje się tego sporo, ale w praktyce 90% z tych rzeczy powinno być już "zrobione" wcześniej (tooltipy w kontrolkach, pliki js osobno, pliki css osobno, do tego jakiś master page, z referencjami do tych plików).

Przykładowa kontrolka, z tooltipem wygląda tak:
<asp:TextBox ID="txtHelper" runat="server" ToolTip="tooltipHelper" CssClass="cssHelper"></asp:TextBox>
 Natomiast skrypt, aktywujący tooltipy dla każdego obiektu, który posiada klasę CSS o nazwie "cssHelper" wygląda tak:
    $("document").ready(function () {
        var objs = $(".cssHelper");

        jQuery.each(objs, function () {
            $("#" + this.id).tooltip();
        });
    });

P.S. Zachęcam do zapoznania się z projektem. Więcej przykładów znajduje się na stronie projektu w zakładce demo.

Edit:
Aby zrobić "multiline", czy też "page break" to należy:
                $('#selector').tooltip({
                    content: function () {
                        return $(this).attr('title');
                    }
                });
I dzięki temu, w tooltipie można skorzystać z  <br>