<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tech - HL Tech</title>
	<atom:link href="https://www.hltech.com/en/kategoria/tech-en/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.hltech.com/en/kategoria/tech-en/</link>
	<description>TECHNOLOGY THAT MATTERS</description>
	<lastBuildDate>Wed, 09 Apr 2025 15:42:57 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
	<item>
		<title>How to make effective frontend tests?</title>
		<link>https://www.hltech.com/en/tech-en/how-to-make-effective-frontend-tests/</link>
		
		<dc:creator><![CDATA[]]></dc:creator>
		<pubDate>Wed, 09 Apr 2025 15:30:31 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<guid isPermaLink="false">https://www.hltech.com/jak-pisac-efektywne-testy-frontendow/</guid>

					<description><![CDATA[<p>Writing automated tests for frontend applications often brings some problems. It's easy to have shortcomings, wrong assumptions, quick solutions that are bad practice, and to top it all off, it's quite time-consuming.</p>
<p>The post <a href="https://www.hltech.com/en/tech-en/how-to-make-effective-frontend-tests/">How to make effective frontend tests?</a> appeared first on <a href="https://www.hltech.com/en/">HL Tech</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Writing automated tests for frontend applications often brings some problems. It&#8217;s easy to have shortcomings, wrong assumptions, quick solutions that are bad practice, and to top it all off, it&#8217;s quite time-consuming. However, the work put in to developing skills and using the right tools has created a pretty good culture of effective testing early in the development process at HL Tech.</p>
<h2>Why do we need tests?</h2>
<p>The shift-left approach is a concept that has existed in the testing world for more than twenty years. It assumes the verification of functionality at an early stage of software development. In this way, various inaccuracies can be detected relatively early. By this I mean mistakes made by the developers, but also shortcomings in the design or incomplete analysis without so-called edge scenarios.</p>
<p>This verification primarily involves automating tests that check how the solution being implemented works and whether it will damage other components in the ecosystem. This helps create a team culture of good software quality and completeness. Developers become aware of more of the challenges of keeping functionality within the constraints of the planned scenario, which culminates in better quality final work submitted to the business for final approval.</p>
<p>In order to properly implement shift-left in day-to-day development, a well-designed dev-ops layer is essential. By this I mean the creation of a sequence of tasks that check the quality of the code and software, the tools used and all other formalities related to the development phase. When all this is fulfilled, the new solution can be automatically delivered to customers, in principle even without manual verification on the tester&#8217;s side.</p>
<p>However, these issues go far beyond the subject of this article. I would like to present how we approach the testing of front-end applications in our everyday development.</p>
<h2>Code quality verification</h2>
<p>For the past few years, I have enjoyed watching junior colleagues start to realise that the quality of the functionality they write is also the result of some kind of testing. By this I mean the static analysis and automatic improvement of source code, implemented by tools like Prettier, Eslint or Typescript. This is because they are the informal, lowest layer of tests that take care of the general readability of the code, checking whether we make any typos in the commands we call and whether we go beyond the established business framework enclosed in the data types we operate on.</p>
<h2>Low-level functionality testing</h2>
<p>True and intentional testing starts at the layer of unit and integration checks, which are actually the most important in our day-to-day development. This is due to the simple fact that they verify functionality based on raw source code, requiring no compilation or prior modification. We perform them using Jest or Vitest tools, although due to the greater modernity and overall efficiency, we recommend the latter for new projects.</p>
<p>It is worth taking a pause at this point to clarify what we at HL Tech mean by unit and integration tests. This is because internet knowledge is very unclear in this area and causes a lot of misunderstandings even for experienced developers.</p>
<p>Well, unit tests are about checking the results of some closed logic. We are talking about simple functions that, with the same input arguments, will always produce the same final results. A good example would be a mapper, validator, or any helper operating on a limited range of input. In such scenarios, we check as many combinations of input as possible, sometimes manually and sometimes trying to exploit some reusability.</p>
<pre style="border: 1px solid #000;"><code style="padding: 1em; display: block;"><span style="font-weight: 400;">describe('isInRange', () =&gt; {</span>
<span style="font-weight: 400;">    it.each&lt;{value: number; result: boolean}&gt;([</span>
<span style="font-weight: 400;">        {value: -2, result: false},</span>
<span style="font-weight: 400;">        {value: -0, result: false},</span>
<span style="font-weight: 400;">        {value: 0, result: false},</span>
<span style="font-weight: 400;">        {value: 0.1, result: true},</span>
<span style="font-weight: 400;">        {value: 5, result: true},</span>
<span style="font-weight: 400;">        {value: 9.9, result: true},</span>
<span style="font-weight: 400;">        {value: 10, result: false},</span>
<span style="font-weight: 400;">        {value: 15, result: false},</span>
<span style="font-weight: 400;">    ])('returns $result if value is $value', ({value, result}) =&gt; {</span>
<span style="font-weight: 400;">        expect(isInRange(value)).toBe(result);</span>
<span style="font-weight: 400;">    });</span>
<span style="font-weight: 400;">});</span></code></pre>
<p>Unit test code example.</p>
<p>Integration tests in our ecosystem are all tests based on rendering a component in a JSDOM environment. In this layer, it is critically important to understand what this title integration is all about. This is because there is still a misconception in the frontend world that it concerns connections between parts of the code &#8211; the components. However, this approach makes integration tests dependent on implementation details, making them unreliable and hard to maintain in the future. In our projects, we consider each page in the application as a self-determining whole, which is the best candidate for testing. During these, we verify how they integrate with their so-called external world &#8211; the user reading data on the screen and using the application with the mouse and keys, the url in the browser or the api through which the view communicates with the backend.</p>
<p>Such tests are based on accurately simulating the way a user uses our application. The user-event library with functions such as click() or type() and the Testing Library with selectors, the most important of which is getByRole(), work perfectly here. Integration with the url is achieved by including a library that supports routing inside the tested component.</p>
<p>In this way, we are able to check the current url ‘in the browser’ and confirm the occurrence of expected redirects. Communication with the backend, on the the other hand, is mocked using MSW. In this case, we are very scrupulous &#8211; we handle only those endpoints that should be called during the test and only with the data we expect to send/receive with accuracy from the last character. Nothing more, nothing less, as any deviation from the planned integration with the backend results in improper processing of financial operations. For us, this can quickly escalate into significant penalties imposed by the market regulator.</p>
<p>We divide integration tests into two stages &#8211; the Happy path and the Negative path. The first is used to confirm whether all the expected elements are displayed and to go through all the actions aimed at &#8211; broadly speaking &#8211; achieving success. A good example of this would be filling out a form and submitting the data, ending with a correct response from the server. The second stage is humorously called the ‘health path’, during which we check the works of the component in the event of incorrect responses from endpoints or incorrect data input by users.</p>
<p>At this point, I have to confess that the above description is only a preview of the topic, because integration testing in itself is the material for quite a large publication. The ability to write authoritative, efficient and readable scenarios is therefore the result of painstakingly honing one&#8217;s craft, learning good practices and understanding the entire sequence of events triggered by each action on the component under test. Unfortunately, the natural tendency to use shortcuts very often ends up creating ineffective scenarios. This causes problems even for intermediate developers. My advice in such a situation is to be patient and concentrate on simulating as accurately as possible the way the user uses the component under test. The rest will come with time.</p>
<pre style="border: 1px solid #000;"><code style="padding: 1em; display: block;"><span style="font-weight: 400;">it('redirects client to /profile after successful sign up', async () =&gt; {</span>
<span style="font-weight: 400;">    // Given data used during test scenario</span>
<span style="font-weight: 400;">    const login = 'test-login';</span>
<span style="font-weight: 400;">    const password = 'test-password';</span>
<span style="font-weight: 400;">    const csrfToken = 'test-csrf-token';</span>
<span style="font-weight: 400;">    // And handler for POST /login endpoint successful call</span>
<span style="font-weight: 400;">    // Note: it handles api endpoint requested only with given requestBody definition</span>
<span style="font-weight: 400;">    </span><b><i>server</i></b><span style="font-weight: 400;">.use(loginHandler({login, password, csrfToken}, {isAuthenticated: true}));</span>
<span style="font-weight: 400;">    // And url to redirect to after successful sign up</span>
<span style="font-weight: 400;">    const redirectionUrl = '/profile';</span>
<span style="font-weight: 400;">    // When component renders</span>
<span style="font-weight: 400;">    // Note: render helper wraps View with open source libraries like React Router or React Query</span>
<span style="font-weight: 400;">    // It also starts the page within a /login url context and provides csrfToken to be mocked internally </span>
<span style="font-weight: 400;">    const {history} = renderPageWithinContexts(&lt;LoginView /&gt;, {path: '/login', csrfToken});</span>
<span style="font-weight: 400;">    // Then main header is displayed</span>
<span style="font-weight: 400;">    expect(await </span><b><i>screen</i></b><span style="font-weight: 400;">.findByRole('heading', {name: /log in to see your profile/i}));</span>
<span style="font-weight: 400;">    </span>
<span style="font-weight: 400;">    // When client fill a sign-up form</span>
<span style="font-weight: 400;">    await </span><b><i>userEvent</i></b><span style="font-weight: 400;">.</span><i><span style="font-weight: 400;">type</span></i><span style="font-weight: 400;">(</span><b><i>screen</i></b><span style="font-weight: 400;">.getByRole('textbox', {name: /login/i}), login);</span>
<span style="font-weight: 400;">    await </span><b><i>userEvent</i></b><span style="font-weight: 400;">.</span><i><span style="font-weight: 400;">type</span></i><span style="font-weight: 400;">(</span><b><i>screen</i></b><span style="font-weight: 400;">.getByRole('textbox', {name: /password/i}), password);</span>
<span style="font-weight: 400;">    await </span><b><i>userEvent</i></b><span style="font-weight: 400;">.</span><i><span style="font-weight: 400;">click</span></i><span style="font-weight: 400;">(</span><b><i>screen</i></b><span style="font-weight: 400;">.getByRole('button', {name: /sign up/i}));</span>
<span style="font-weight: 400;">    // Then they are redirected to /profile page</span>
<span style="font-weight: 400;">    await waitFor(() =&gt; expect(history.location.pathname).toEqual(redirectionUrl));</span>
<span style="font-weight: 400;">});</span></code></pre>
<p>Example of integration test code for a hypothetical login page.</p>
<h2>Application functional testing</h2>
<p>While the previous layer of testing is based on checking sections of the application &#8211; logical units, views or pages &#8211; we now focus on verifying so-called user journeys &#8211; real-world scenarios focusing on the customer achieving the expected result. For such verification, Playwright is most often useful to us. It tests the production application bundle generated locally (functional tests), or deployed on test environments (end-to-end / e2e tests).</p>
<p>Functional testing works best in so-called step-by-step applications, where customers reach their goal by passing through several views that together form their journey. An example of this is the creation of a financial transfer, which in most systems involves entering data, confirming it on the summary, entering a security code and finally sending the request to the financial institution. In the case of single-step applications, e.g. panels for operational staff, which resemble a view layer for CRUD (create, read, update, delete) operations, such tests are almost uniform with our integration tests. At this stage, communication with the endpoints is also mocked, and the application itself is tested using a real browser, which is usually implemented by Playwright.</p>
<p>e2e tests, on the other hand, focus on verifying the regression of critical paths in the application. QA engineers or so-called testers are responsible for creating them. However, thanks to the use of the common Typescript language and the Playwright tool, their work can also be performed or verified by frontend developers. This layer communicates with the real backend services, so that we regress the entire solution. Such tests are performed each time changes are implemented into the main branch of any of the ecosystem components (backend, frontend, etc.).</p>
<h2>More than just code testing</h2>
<p>If I had to describe the world of frontend development over the past few years in a single sentence, I would not hesitate to use the words &#8211; very dynamic progress. The creation of so-called ‘pretty views’ has long since been a thing of the past. Nowadays, on the front-end we also focus on the semantics of the code (in order to comply with SEO standards), we care about the performance of applications, which should display the expected data to customers as quickly as possible, or we keep a close eye on metrics indicating &#8211; generally speaking &#8211; comfort and safety related to the use of applications. And this is just a small part of our daily responsibilities.</p>
<p>Checking all this can also be automated. ‘Nice views’ are confirmed by visual tests using Playwright. These involve creating so-called ‘snapshots’ of pages, which are then saved to a graphical format. In this way, we can confirm how the page will look in the browser and whether we will inadvertently make unexpected visual changes. On the other hand, we verify metrics related to application performance, good practice or SEO compliance through automated snapshot audits performed in Lighthouse.</p>
<h2>Accessibilty testing</h2>
<p>Accessibility is an extremely important topic for us. In addition to the EAA Directive coming into force in mid-2025, requiring us to meet accessibility standards for digital services for people with disabilities, it is simply required by a huge number of our most valuable customers.</p>
<p>Of course, the most authoritative accessibility tests are performed by real users, as are tests of the overall User Experience. However, we are able to automate some of the tests at an early stage of development. This is especially true if we are talking about standards for the HTML code generated &#8211; its semantics allowing better integration with assistive technologies, or a properly laid out appearance in terms of contrasts used, size of elements, etc.</p>
<p>We have included the analysis of static code and design in a group of so-called snapshot tests. We are very strict here and in new projects we do not allow any change to be made if any error is found that does not comply with the most comprehensive WCAG guidelines. We control the tested applications using Playwright, after which we analyse their effect in Lighthouse and Axe scanners.</p>
<pre style="border: 1px solid #000;"><code style="padding: 1em; display: block;"><span style="font-weight: 400;">public async assertSnapshots(snapshotTitle: string) {</span>
<span style="font-weight: 400;">    await </span><b><i>Promise</i></b><span style="font-weight: 400;">.all([</span>
<span style="font-weight: 400;">        this.assertAccessibilityChecks(snapshotTitle),</span>
<span style="font-weight: 400;">        this.performVisualSnapshotComparison(snapshotTitle),</span>
<span style="font-weight: 400;">        this.performAriaSnapshotComparison(snapshotTitle),</span>
<span style="font-weight: 400;">        this.performLighthouseFlowSnapshot(snapshotTitle),</span>
<span style="font-weight: 400;">    ]);</span>
<span style="font-weight: 400;">}</span>
<span style="font-weight: 400;"> </span>
<span style="font-weight: 400;">private async assertAccessibilityChecks(snapshotTitle: string) {</span>
<span style="font-weight: 400;">    // Perform static a11y analysis of given page (snapshot)</span>
<span style="font-weight: 400;">    const accessibilityChecks = await new AxeBuilder({page: this.page})</span>
<span style="font-weight: 400;">        .withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22aa'])</span>
<span style="font-weight: 400;">        .analyze();</span>
<span style="font-weight: 400;">    // Attach checks into test report</span>
<span style="font-weight: 400;">    await this.testInfo.attach(this.composeA11yReportName(snapshotTitle), {</span>
<span style="font-weight: 400;">        body: </span><b><i>JSON</i></b><span style="font-weight: 400;">.stringify(accessibilityChecks, null, 2),</span>
<span style="font-weight: 400;">        contentType: 'application/json',</span>
<span style="font-weight: 400;">    });</span>
<span style="font-weight: 400;">    // Ensure no a11y errors</span>
<span style="font-weight: 400;">    </span><b><i>expect</i></b><span style="font-weight: 400;">(accessibilityChecks.violations).toEqual([]);</span>
<span style="font-weight: 400;">}</span></code></pre>
<p>Types of snapshot tests and an example of how to call a static Axe analysis.</p>
<p>In addition to this, we duplicate scenarios that test critical client journeys by navigating using only the keyboard. While we also use Playwright for this purpose, the test cases focus more on verifying the currently selected elements and triggering actions on them using the keyboard buttons. In this way, we confirm that our services are also available for users using so-called assistive technologies.</p>
<h2>Everything above is just a teaser</h2>
<p>Without a doubt, frontend testing is a tough piece of development. Many times, the simplest solutions turn out to be a bad pattern, such as identifying elements by their HTML structure or through a special data-test-id attribute. On the other hand, the getByRole() function from the Testing Library is not particularly efficient for reasonable technological reasons. Thus, the knowledge of any tips&amp;tricks to increase it becomes a kind of maturity check for test writing. And with each passing day, it becomes apparent that there is room for improvement &#8211; for scenarios to not only be robust to the implementation details of the application, but also to elements of randomness in the data, the order in which the actions occur or the configuration of the environments on which they are executed.</p>
<p>We have been discussing these topics at our in-house meetups for years, so that we are able to create tests of higher and higher quality year after year. We are aware that this increases the development time of the functionality. I am not exaggerating when I say that writing all the tests for a new functionality takes a bit longer than writing the functionality itself. However, what I personally appreciate in my day-to-day work at HL Tech is that the business is aware of the value of automated tests and never asks questions about the possibility of half-measures. In the financial market, verifiability is fortunately one of the most important regulations.</p>
<p>The post <a href="https://www.hltech.com/en/tech-en/how-to-make-effective-frontend-tests/">How to make effective frontend tests?</a> appeared first on <a href="https://www.hltech.com/en/">HL Tech</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Microapps – way to go for easier workflow and faster delivery of new functionalities</title>
		<link>https://www.hltech.com/en/tech-en/microapps-way-to-go-for-easier-workflow-and-faster-delivery-of-new-functionalities/</link>
		
		<dc:creator><![CDATA[]]></dc:creator>
		<pubDate>Tue, 27 Sep 2022 15:07:24 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<guid isPermaLink="false">https://www.hltech.com/?p=4067</guid>

					<description><![CDATA[<p>In the beginning there was a monolith I am curious how many of you remember your first developer training projects. Their aim was to teach the basics of diverse issues. For instance &#8211; connection to the source database, safe backend handling of such, or neat UI/UX design. Even if you went one step ahead and [&#8230;]</p>
<p>The post <a href="https://www.hltech.com/en/tech-en/microapps-way-to-go-for-easier-workflow-and-faster-delivery-of-new-functionalities/">Microapps – way to go for easier workflow and faster delivery of new functionalities</a> appeared first on <a href="https://www.hltech.com/en/">HL Tech</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>In the beginning there was a monolith</h2>
<p align="justify">I am curious how many of you remember your first developer training projects. Their aim was to teach the basics of diverse issues. For instance &#8211; connection to the source database, safe backend handling of such, or neat UI/UX design. Even if you went one step ahead and you have tried to apply layer separation in your application, I am pretty sure that it all has been stored in a single project repository.</p>
<p><img decoding="async" class="alignnone size-medium wp-image-4063" src="https://www.hltech.com/wp-content/uploads/2022/09/blog-male-aplikacje-monolit-300x161.png" alt="" width="300" height="161" srcset="https://www.hltech.com/wp-content/uploads/2022/09/blog-male-aplikacje-monolit-300x161.png 300w, https://www.hltech.com/wp-content/uploads/2022/09/blog-male-aplikacje-monolit.png 744w" sizes="(max-width: 300px) 100vw, 300px" /></p>
<p align="justify">At that time you probably had no idea that you were witnessing the birth of another monolith &#8211; a structure of closely connected elements of the whole application. Of course, it was not a problem at all, as the project was meant to teach you something new. The time for knowledge related to architecture was yet to come. Nevertheless, many years ago, the fundamentals of almost any application were brought forward in a similar way. In time, more and more developers were involved in writing their monolithic code and projects were growing to exorbitant sizes.</p>
<h2>First microservices</h2>
<p align="justify">For that reason, at the beginning of the XXI century, the idea of microservices started to emerge. It is an architectural concept in which the application consists of many services, each having its own, narrowed down purpose. Usually, they operate within a single business domain.</p>
<p align="justify">For that reason, larger applications started to resemble a compilation of modules and dev departments &#8211; domain or product teams. It had a positive impact on the ease of software development and particular teams efficiency in general. Their operations have been almost completely separated from each other. Developers could finally focus on their part of the business, not worrying about the functionality of the whole.</p>
<h2 class="western">Hard-rock monoliths</h2>
<p align="justify">Unfortunately, despite the many pros of such architecture, many large organizations still carry the burden of monolithic structures in one way or another. Usually, these are the oldest and most important parts of the system. Once such basic elements are in place, there is no need for any form of modification. All they require is periodic service work such as updates of software version in use.</p>
<p align="justify">Of course, many products we work on at HL Tech are usually new functionalities. However, from time to time, certain teams encounter codes written ten or fifteen years ago. In such instances, our job is to flake off part of such a monolith and safely transfer it (rewrite it) to a separate module. It resembles a bit of open surgery on a living organism. That is why before we set about rewriting such code, at first we pay particular attention to in-depth analysis of the product. And here comes the bonus. Through the contact with such an old code we get a chance to track many historical decisions within the IT world &#8211; the good ones but also the ones that, from a time perspective, seem misguided. It is always an informative experience for us, as observations like that cannot usually be made on projects developed from scratch.</p>
<h2 class="western">Frontend granularity</h2>
<p align="justify">At HL Tech we also apply the approach to divide into smaller modules in my specialization &#8211; frontend development. Just think about it &#8211; end users of the system can also be divided into several groups and each one of them will use a different part of it. Doesn’t it sound like a good way to divide the whole platform into modules? That way we enter the subject of micro-frontend architecture. About four months ago, me and Łukasz Fiszer had a chance to present it in more detail during Dev.js Summit 2022.</p>
<p align="justify">No doubt micro-frontend architecture greatly improves the everyday work of developers. However, for clients and their needs, it is unnoticeable because it does not affect general accessibility or application’s overall performance. Luckily, through observation of news from the developers’ world, I can honestly say that emerging technologies support such needs as well. Let’s have a look at some of them.</p>
<h2 class="western">Download only what the user currently needs</h2>
<p align="justify"><span style="color: #0e101a;">In general, modern front-end applications utilize the approach called Client Side Rendering (CSR). It means that when one enters a specific URL address, the browser firstly downloads the whole JavaScript code and then renders the page view. Unfortunately, output versions of the majority of apps written in React are simply two large JavaScript files. It forces the client to download the whole code, including pages he may not even want to browse. In effect, excessive traffic online is generated and wide range computations only cause the delay of the view&#8217;s display. One of the easier and popular improvements of this process is the approach called </span><span style="color: #0e101a;"><i>Lazy Loading</i></span><span style="color: #0e101a;">. It rests on the principle that whenever someone opens the website, a browser downloads only what is needed to display it &#8211; framework and current view codes. That way, it is possible to speed up the start of an application even by a couple of hundreds of milliseconds.</span></p>
<h2 class="western">Rendering run through every case</h2>
<p align="justify"><span style="color: #0e101a;">Once it has been confirmed that a smaller number of JavaScript computations speeds up applications’ start, a question arose: is it true that the display of every single element has to be an outcome of a script work? It turns out that not necessarily. The process can be improved with an approach called </span><span style="color: #0e101a;"><i>Island Architecture</i></span><span style="color: #0e101a;">. According to it, the view of every page can be divided into isolated areas. Let’s take the footer of an application as an example. It is independent of the whole and additionally, it does not change for months. The footer looks and works the same way on every single subpage. It opens the way to Server Side Rendering (SSR) in its most efficient form. Following SSR principles, the server generates a single static HTML code and distributes it among clients the output of such operation saved in internal memory. Thanks to such design, the client&#8217;s browser does not have to run time-consuming JavaScript computations and receives the final code, which in turn can be displayed on the screen.</span></p>
<p align="justify"><span style="color: #0e101a;">Above approach can even be extended to whole pages. Especially those, which do not require continuous communication with the backend. It works great within areas similar to blogs, like articles, FAQ elements or product presentation pages. In such instances, HTML code is generated for the whole page, and time-consuming JavaScript computations are reduced to almost none on the client side. This method is called Static Site Generation (SSG).</span></p>
<h2 class="western">Other ways for better performance</h2>
<p align="justify"><span style="color: #0e101a;">Lazy loading shortens the time required for displaying the page view thanks to giving up on downloading unnecessary data. However, when a client wants to open a different page, its code has to be downloaded from the server. Fortunately, current IT trends allow us to speed that process in such a way that it becomes almost unnoticeable.</span></p>
<p align="justify"><span style="color: #0e101a;">An interesting and multilayered solution has been introduced with a framework called Remix. For instance &#8211; its creators noticed that it takes a couple of hundred milliseconds from the time a user moves the cursor over a button to clicking it. If that button is a hyperlink to another page, we can start the download of its code already on hover action and not &#8211; like it was until now &#8211; on click action.</span></p>
<p align="justify"><iframe title="YouTube video player" src="https://www.youtube.com/embed/4jT7iKdqoW4" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen"></iframe></p>
<p align="justify"><span style="color: #0e101a;">This framework also gives easy control over advanced caching. It allows static content (such as graphics, CSS, HTML) to be stored at Content Delivery Network (CDN) access points. In case of providers with extended networks, access points can be located in several places across the country. What it means is that whenever a client opens a specific web page, every other client from their area is able to access the same content within a dozen or so milliseconds.</span></p>
<p align="justify"><iframe title="YouTube video player" src="https://www.youtube.com/embed/bfLFHp7Sbkg" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen"></iframe></p>
<p align="justify"><span style="color: #0e101a;">If, however, we need to display “live” data requiring constant communication with the server, Remix puts in favor already mentioned </span><span style="color: #0e101a;"><i>Island Architecture</i></span><span style="color: #0e101a;">. That way, every single part of a page prompts the data query required to display within its area. The query is initiated instantly, run in parallel, and downloaded data is being shown independently from one another.</span></p>
<p align="justify"><iframe title="YouTube video player" src="https://www.youtube.com/embed/95B8mnhzoCM" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen"></iframe></p>
<p align="justify"><span style="color: #0e101a;">All of the above have one common goal &#8211; to decrease the time between entering a web page and displaying data it holds. Whenever it is possible, a client receives already generated static content. Whereas functionalities requiring server side calculations are significantly accelerated and the time spent on processing such queries holds back only small parts of the entire application.</span></p>
<h2 class="western">Split up and be efficient</h2>
<p align="justify">Aforementioned solutions show how splitting into smaller ranges and attributions positively affects overall efficiency. Interestingly, the rule seems to be true everywhere.</p>
<p align="justify">At the organizational level &#8211; when I work within a single domain, I do not have to know and understand every business rule of the company. When starting a new project, I always try to divide its production process into stages which in turn are split into smaller tasks. Thanks to this method I am able to easily understand every aspect of them, credibly estimate the time required to complete them and encompass the work within regular sprints.</p>
<p align="justify">At the specialist level &#8211; as a frontend developer I do not need to know all the backend, DevOps, security, or database management details. I can focus on high-quality specialization within my technological field.</p>
<p align="justify">At the developer level &#8211; while writing small applications, I am able to quickly manage their code. Narrow responsibility and modest level of functionalities’ complexity, both have a positive impact on their efficiency and security. That way I can provide new solutions and content to our clients in a shorter period of time.</p>
<p>The post <a href="https://www.hltech.com/en/tech-en/microapps-way-to-go-for-easier-workflow-and-faster-delivery-of-new-functionalities/">Microapps – way to go for easier workflow and faster delivery of new functionalities</a> appeared first on <a href="https://www.hltech.com/en/">HL Tech</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How we build an accessible design system at HL Tech</title>
		<link>https://www.hltech.com/en/tech-en/how-we-build-an-accessible-design-system-at-hl-tech/</link>
		
		<dc:creator><![CDATA[]]></dc:creator>
		<pubDate>Sun, 29 Nov 2020 22:46:35 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<guid isPermaLink="false">https://www.hltech.com/?p=2572</guid>

					<description><![CDATA[<p>Who are we? HL Tech is a technology centre focused on providing cutting-edge software solutions for Hargreaves Lansdown &#8211; an award-winning investment service provider on the British Market. We believe in quality and innovation, that is why we implemented best practices into our daily workflow. But more than that, we are a team of specialists [&#8230;]</p>
<p>The post <a href="https://www.hltech.com/en/tech-en/how-we-build-an-accessible-design-system-at-hl-tech/">How we build an accessible design system at HL Tech</a> appeared first on <a href="https://www.hltech.com/en/">HL Tech</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="p1"><b>Who are we?</b></p>
<p class="p1">HL Tech is a technology centre focused on providing cutting-edge software solutions for Hargreaves Lansdown &#8211; an award-winning investment service provider on the British Market. We believe in quality and innovation, that is why we implemented best practices into our daily workflow. But more than that, we are a team of specialists willing to learn and share knowledge.</p>
<p class="p1"><b>Accessibility rules (pun intended) </b></p>
<p class="p1">Implementation of Web Content Accessibility Guidelines 1.0 first published in 1999 and subsequent updates throughout the Internet was a long and painful process. People responsible for the creation of early websites often overlooked or were unaware of these rules. The Internet was still a new medium, and like all new things, it had its infancy problems.</p>
<p class="p1">Because of limited technological advancement companies and web designers alike reached for solutions such as Adobe Flash (back then owned by Macromedia) or rich imagery often using animated GIFs to convey their message. The goal was to stand out, be visible, even overly flashy. </p>
<p class="p1">The downside? The content was not accessible by default to many people because screen readers struggled with reading Flash websites and images replacing text brought the same problem. Navigation through such websites was exhausting if not impossible for some who were not able to use computer mice or keyboard comfortably. The web, unfortunately, was mostly created for able-bodied people.</p>
<p class="p1">You may ask &#8211; why should we spend time thinking about the minority? Because all of us can be a part of it at any moment in our lives. </p>
<p><img decoding="async" class="alignnone size-medium wp-image-2559" src="https://www.hltech.com/wp-content/uploads/2020/11/img_1-300x146.png" alt="" width="300" height="146" srcset="https://www.hltech.com/wp-content/uploads/2020/11/img_1-300x146.png 300w, https://www.hltech.com/wp-content/uploads/2020/11/img_1-1024x499.png 1024w, https://www.hltech.com/wp-content/uploads/2020/11/img_1-768x374.png 768w, https://www.hltech.com/wp-content/uploads/2020/11/img_1.png 1034w" sizes="(max-width: 300px) 100vw, 300px" /> </p>
<p class="p1">A spectrum of permanent, temporary, and situational disabilities (credit: <a href="https://www.microsoft.com/en-us/design/inclusive"><span class="s1">Microsoft</span><span class="s2">’</span><span class="s1">s Inclusive Design</span></a>)</p>
<p class="p1">The simplest example &#8211; an injured arm. Good luck with using a website where you cannot use Tab key to jump around the content or purchase stuff from the online store where you need to manoeuvre with a mouse and activate each address field by a single click. </p>
<p class="p1"><b>That is why accessibility guidelines are not for a few, but everyone.</b></p>
<p class="p1"><b>Shared responsibility</b></p>
<p class="p1">Although originally WCAG was aimed to be a guidebook for <a href="https://www.w3.org/TR/WAI-WEBCONTENT/%2523content-developer"><span class="s1">Web content developers</span></a> and web-developers, the roles have shifted. Many new professions originated in the process of specialisation. Imagine a regular commercial website &#8211; we can positively assume that most of its design, search engine optimisation and content is not usually done by the same person.</p>
<p class="p1"><b>Where lies the responsibility for making products accessible?</b></p>
<p class="p1">At <span class="s3">’</span>HL Tech<span class="s3">’ </span>we understand that this is a shared responsibility, as it should be. Of course, some areas are better off being solved by developers, while others left for UI/UX designers. Still, we should all learn from each other. It is not uncommon for our teams to talk about ARIA (Accessible Rich Internet Applications) codes and design patterns used in our applications, naming conventions of the buttons or contrast.</p>
<p class="p1"><b>Design system as an opportunity </b></p>
<p class="p1">When we first began working on our design system we knew that expertise from many departments would come in handy. This year-long journey originated with three simple goals: user-friendliness, ease of use for developers and look consistent with our brand. Luckily we have many talents within the company &#8211; such as Aneta Górka, a Senior Front End Developer in the Design, UX &amp; Optimisation department who gave a brilliant talk and hosted workshops on web accessibility to widen our horizons. Conversations have started, knowledge of our teams grew, and we took this opportunity to do the right thing and add accessibility requirements to our workflow.</p>
<p class="p1">Our design process usually consists of three steps: identifying a need for the new component, designing it in line with our brand and third, a crucial one, is code review with a team of front-end developers.</p>
<p class="p1">We care for the quality of our React elements base. Nothing will go unnoticed, whether it is contrast and size of the text, missing icon, validation rules, proper ARIA snippets or text. </p>
<p class="p1">Together we created something we can rely on in our day-to-day work &#8211; we know the quality of our projects is top-notch.</p>
<p class="p1"><b>Designs system help us to be more efficient.</b></p>
<p class="p1">When we finish our design and review process for a new element, we test it from many angles. Firstly, our design team checks if the proportions, colours, contrast, WCAG requirements, HTML structure and brand standards are in line with the designs, then it is tested in isolation by our skilled Front End team to make sure it also performs up to our high standards.</p>
<p><img fetchpriority="high" decoding="async" class="alignnone size-medium wp-image-2561" src="https://www.hltech.com/wp-content/uploads/2020/11/img_2-300x209.png" alt="" width="300" height="209" srcset="https://www.hltech.com/wp-content/uploads/2020/11/img_2-300x209.png 300w, https://www.hltech.com/wp-content/uploads/2020/11/img_2-768x534.png 768w, https://www.hltech.com/wp-content/uploads/2020/11/img_2.png 1004w" sizes="(max-width: 300px) 100vw, 300px" /></p>
<p class="p1">Our Field Text component has an option to visually hide input&#8217;s label while still being read by screen readers. </p>
<p class="p1">Having this well-crafted library makes not only my job easier by having a working rendition of my design assets, but also is an easy way for developers to translate high-fidelity mockups into working products. It takes just one look to know which element needs to be used.</p>
<p class="p1">But most importantly, we do not have to worry if we broke some of the accessibility rules, one would need to try hard to do so.</p>
<p class="p1">TB</p>
<p>The post <a href="https://www.hltech.com/en/tech-en/how-we-build-an-accessible-design-system-at-hl-tech/">How we build an accessible design system at HL Tech</a> appeared first on <a href="https://www.hltech.com/en/">HL Tech</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>QCon New York 2019</title>
		<link>https://www.hltech.com/en/tech-en/qcon-new-york-2019/</link>
		
		<dc:creator><![CDATA[]]></dc:creator>
		<pubDate>Wed, 28 Aug 2019 10:12:05 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<guid isPermaLink="false">https://www.hltech.com/?p=2430</guid>

					<description><![CDATA[<p>In June I attended QCon conference held in New York. I would like to share with you my impressions. QCon is a 3 day conference + 2 days of workshop. I attended the conference part. QCon is split to different tracks. Most of them are technical, but there are some concentrating on soft skills as [&#8230;]</p>
<p>The post <a href="https://www.hltech.com/en/tech-en/qcon-new-york-2019/">QCon New York 2019</a> appeared first on <a href="https://www.hltech.com/en/">HL Tech</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In June I attended QCon conference held in New York. I would like to share with you my impressions.</p>
<p>QCon is a 3 day conference + 2 days of workshop. I attended the conference part. QCon is split to different tracks. Most of them are technical, but there are some concentrating on soft skills as well.</p>
<p>What I find interesting are Ask Me Anything sessions. Speakers from each track spent 1 hour answering questions from the audience. I attended some of them and the best one was Domain Driven Design AMA with Vaughn Vernon from Kalele, Indu Alagarsamy from Particular Software and Stuart Charlton from Pivotal. They shared their experience in implementing DDD in different companies. Even though I already participated in projects utilizing DDD approach, I think it is always good to hear what fellow developers went through and learn from their mistakes/success stories as well.</p>
<p>&nbsp;</p>
<p>There were some nice presentations during the conference. First one belonged to “Modern CS in the real world” track. Talk of Colm MacCárthaigh was about PID loops and how they are used to keep AWS systems stable. PID loops measure system behavior after signal (of any kind) is sent to the system. Metrics are constantly gathered. Difference between expected and actual value is calculated and signal is so modified that the actual value gets closer to the expected one.  It was really interesting to see this mechanism used in modern IT systems to solve common problems in production environment.</p>
<p>First of them are open loops. They occur when actions take place in the system (of any kind) and consequences of these actions are not measured. The solution is to close the loop i. e. start constant measures of the consequences.</p>
<p>Second are power laws. They occur in systems, where there are many small elements cooperating with each other to provide greater value. Sample of such configuration are IT systems and microservices environment. When one of the systems fail for any reason, for example due to broken contracts between services (how to avoid this you can read about Judge Dredd, an Open Source framework for contract testing in [1]), errors cascade to direct neighbors and exponentially further to other services. According to Colm, compartmentalization is the best solution of this problem. More compartments mean relatively smaller blast radius.</p>
<p>There are some other problems like lags (old information is sometimes worse than no information which are sometimes hard to avoid (spiky loads etc.), false functions (misleading metrics and dependencies between them leading to wrong analysis – to avoid this situation it is advisable to base analysis on basic metrics like CPU), edge triggering which means switching mode when particular threshold of value of the metric is reached (in case of controlling the new mode often kicks in at a time of high-stress).</p>
<p>&nbsp;</p>
<p>Another interesting subject for me was presented during “Software defined infrastructure: Kubernetes, service mesh and beyond” track. I would like to mention 2 presentations here. First one, “The Service Mesh: It’s about Traffic” by Oliver Gould from Linkerd, introduced the audience to the definition of service mesh – it is infrastructure layer for handling service-to-service communication. Service mesh does the following things: load balancing, service discovery, routing, tracing, handles traffic policies, secures service to service communication. Linkerd was described as sample implementation of the concept. It is worth mentioning that there are more than one solution implementing service mesh concept like Istio. In order to avoid dependency to one technology, Service Mesh Interface is introduced. It is API used to isolate concept of Service Mesh of corresponding implementations. Definition of this API and its features were nicely described by Brendan Burns (from Microsoft Azure and Kubernetes co-founder) in his talk “Introduction to SMI (the Service Mesh Interface)”.</p>
<p>&nbsp;</p>
<p>One of the best features of QCon was sharing experience from success and failure stories by fellow senior developers, technical leaders and architects. Here I would like to mention “Time Predictions in Uber Eats” talk by Zi Wang, whereby he described how Uber uses machine learning to accurately predict delivery times, “Machine-Learned Indexes – Research from Google” by Alex Beutel, whereby he goes through resent research on using machine learning algorithms to improve traditional data processing systems, “Conquering Microservices Complexity @Uber With Distributed Tracing” by Yuri Shkuro, whereby he describes methodology and solution that uses data mining to learn typical behaviour of systems from massive amounts of distributed traces, compares it with pathological behaviour during outages, and uses complexity reduction and intuitive visualizations to guide the user towards actionable insights about the root cause of the outages. The solution is built using modules available in the open source as part of Jaeger (distributed tracing system developed by Yuri Shkuro himself), Uber’s distributed tracing platform and an incubating project at Cloud Native Computing Foundation.</p>
<p>&nbsp;</p>
<p>Visiting New York and participating in QCon 2019 was a good decision I had a chance to participate in many interesting talks, meet fellow developers from American companies, discuss with them in Ask Me Anything sessions and listen to inspiring talks.</p>
<p>[1] <a href="https://dzone.com/articles/contract-testing-in-hl-tech-judge-dredd">https://dzone.com/articles/contract-testing-in-hl-tech-judge-dredd</a></p>
<p>The post <a href="https://www.hltech.com/en/tech-en/qcon-new-york-2019/">QCon New York 2019</a> appeared first on <a href="https://www.hltech.com/en/">HL Tech</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The internship programme from the programmer’s perspective</title>
		<link>https://www.hltech.com/en/tech-en/the-internship-programme-from-the-programmers-perspective/</link>
		
		<dc:creator><![CDATA[]]></dc:creator>
		<pubDate>Wed, 27 Feb 2019 09:20:25 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<guid isPermaLink="false">http://www.hltech.com/program-praktyk-okiem-programisty-nowoczesne-technologie-i-realny-projekt/</guid>

					<description><![CDATA[<p>Modern technologies and the real project! What was the challenge our interns had to face?</p>
<p>The post <a href="https://www.hltech.com/en/tech-en/the-internship-programme-from-the-programmers-perspective/">The internship programme from the programmer’s perspective</a> appeared first on <a href="https://www.hltech.com/en/">HL Tech</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Zarządzanie kapitałem wartym 86,1 miliarda funtów, które zostały zainwestowane przez ponad milion klientów Hargreaves Lansdown to ogromne wyzwanie. Z tego względu efektywny proces obsługi klienta jest tutaj kluczowy. By to osiągnąć, firma powinna korzystać z nowoczesnych, intuicyjnych i szybkich aplikacji, które w tym pomogą. Jako centrum technologiczne tworzące rozwiązania dla Hargreaves Lansdown, czyli wiodącej firmy zajmującej się zarządzaniem funduszami inwestycyjnymi i emerytalnymi w Wielkiej Brytanii, dbamy o unowocześnienie oprogramowania. To właśnie o przygotowanie aplikacji wspierającej proces obsługi klientów poprosiliśmy studentów, których zaprosiliśmy do odbycia praktyk w ramach naszego programu „Internship that matters”. Poniżej kilka słów o merytorycznych i technicznych aspektach tego programu.</p>
<h3>Potrzeba biznesowa a realizacja projektu</h3>
<p>Dział obsługi klienta w Hargreaves Lansdown potrzebował intuicyjnej, przejrzystej i szybkiej aplikacji, która poprawi efektywność obsługi klienta przy jednoczesnym braku zmiany procesów i procedur. Aplikacja miała zastąpić jedną z wielu funkcji systemu służącego do obsługi klienta w ramach dużego projektu, którego celem jest podzielenie dużej monolitycznej aplikacji na mniejsze komponenty. W ten sposób chcieliśmy ułatwić i uniezależnić rozwój poszczególnych funkcji systemu.</p>
<p>Spośród projektów możliwych do realizacji został wybrany taki, który mógł być zrealizowany w okresie trzymiesięcznych praktyk – przygotowanie aplikacji dla działu obsługi klienta w siedzibie Hargreaves Lansdown w Bristolu. Następnie wybraliśmy technologię, w ramach których będzie realizowany projekt – wszystko po to, aby przygotować dwutygodniowe szkolenie.</p>
<p>W projekcie uczestniczyło dziesięciu praktykantów oraz product owner będący reprezentantem biznesu i określający oczekiwania wobec aplikacji. Ja z kolei pełniłem rolę opiekuna technicznego i merytorycznego. W projekt zaangażowany był także software development manager oraz wielu innych programistów, którzy szkolili praktykantów.</p>
<p>System był rozwijany iteracyjnie przy użyciu Scruma. Każda iteracja miała demo, którego celem było przedstawienie użytkownikom efektów pracy w poprzedzającej iteracji oraz zebranie informacji zwrotnej. Taki proces wymuszał ciągłą gotowość do wprowadzania zmian w kolejnych iteracjach, aby było to możliwe musieliśmy zadbać o wysoką jakość kodu oraz testów.</p>
<h3>Kandydat idealny, czyli jaki</h3>
<p>Implementacja aplikacji a następnie wdrożenie na produkcję jest bardzo dużym wyzwaniem dla osób bez doświadczenia. Co więcej praca przy takim projekcie w zespole składającym się z 10 osób jest sama w sobie wyzwaniem i wymaga sprawnej komunikacji w zespole. W związku z tym w czasie procesu rekrutacji skoncentrowaliśmy się na kilku cechach, które dla nas były kluczowe.</p>
<ul>
<li>Po pierwsze: determinacja i zaangażowanie członków zespołu, ponieważ są to elementy ułatwiające pracę w projekcie, który ma określone wymagania funkcjonalne, jakościowe oraz ramy czasowe.</li>
<li>Po drugie: otwartość i przyjazne nastawienie, ponieważ cechy te znacznie ułatwiają komunikację, wymianę wiedzy i doświadczeń.</li>
<li>Ponadto ceniliśmy u kandydatów także zainteresowanie tematyką wytwarzania oprogramowania (bazy danych, projektowanie, technologie web itp.).</li>
</ul>
<p>Naszym zdaniem dobry inżynier oprogramowania powinien nie tylko znać dobrze język programowania czy bibliotekę, ale również umieć wymienić wiedzę z kolegą z zespołu, omówić problem z product ownerem, czy dobrze uargumentować swoje wybory podejmowane odnośnie rozwiązań informatycznych.</p>
<h3>Technologie, które wykorzystaliśmy</h3>
<p>Aplikacja została podzielona na dwa komponenty – frontend, stanowiący interfejs użytkownika oraz backend wystawiający API dla frontendu, zawierający logikę biznesową, element integracji z bazą danych oraz systemami uwierzytelniania użytkownika. Komponent frontendu komunikował się z backendem przy pomocy Fetch API, co zapewniało asynchroniczną komunikację. Fronted i backend miał odrębne repozytoria kodu źródłowego, dzięki czemu można było zastosować dopasowane do potrzeb technologie, biblioteki, narzędzia zarządzania zależnościami czy procesy budowania i wdrażania.</p>
<p>Zarówno frontend jak i backend był wdrażany na środowisko Kubernets, które automatycznie zarządzało zasobami takimi jak interfejsy sieciowe, procesory, pamięć RAM itp. Komponenty były dostarczane jako kontenery Docker’owe, a każda zaimplementowana i zaakceptowana przez zespół funkcja aplikacji była automatycznie wdrażana przy pomocy Jenkins’a, czyli narzędzia realizującego wcześniej skonfigurowany potok. Jego kluczowe etapy to: kompilacje, testowanie, przygotowywanie i budowanie paczki zawierającej działającą aplikację, przygotowywanie kontenera Docker i ostatecznie wdrażanie kontenera na środowisko Kubernetes.</p>
<p>Implementacja logiki biznesowej w komponencie backend była realizowana przy wykorzystaniu języka Java i Spring Boot (ułatwiający konfigurację samodzielnej aplikacji). Backend wymagał integracji z bazą danych przy użyciu Spring Data JPA oraz Hibernate. Aby ograniczyć komunikację z bazą zastosowaliśmy cache L2 oraz cache zapytań. Z kolei chcąc ograniczyć dostęp do aplikacji i zapewnić uwierzytelnianie oraz autoryzację użyliśmy Spring Security. Spring MVC posłużył nam do wystawienia metod HTTP dla aplikacji fronted. Testy integracyjne i jednostkowe były pisane przy użyciu Spock’a wykorzystującego język Groovy.</p>
<p>Frontend jako interfejs graficzny był realizowany przy użyciu technologii Web. Całość składała się z wielu małych komponentów takich jak przyciski, etykiety, pola tekstowe, pola rozwijane z automatycznym uzupełnianiem itp. Jako języka programowania użyliśmy Typescript’u, który jest „transpilowany” do Javasriptu. Jego kluczową zaletą jest statyczne typowanie, co umożliwia wykrywanie wielu błędów na etapie kompilacji oraz znacząco poprawia czytelność kodu. Wykorzystaliśmy także bibliotekę React oraz Material UI, co znacząco przyspieszyło implementację. Architektura Redux zakłada jednokierunkowy przepływ danych. Wywołania backendu są realizowane asynchronicznie przy użyciu Fetch API. Do zarządzania zależnościami i budowania aplikacji użyliśmy Yarna, Npm’a i Webpacka.</p>
<h3>Postęp w pozyskiwaniu wiedzy i umiejętności</h3>
<p>W okresie trzymiesięcznych praktyk w każdej kolejnej iteracji widać było postęp i większą samodzielność w tych obszarach. Pod koniec członkowie zespołu znacznie sprawniej radzili sobie w trakcie analizy i planowania, potrafili przewidzieć szereg konsekwencji przy wyborze konkretnego rozwiązania. Efektem tego był wzrost ilości proponowanych zmian oraz samodzielnie dostarczanych funkcji.</p>
<p>Podsumowując, do programu praktyk zaprosiliśmy 10 osób, które nie miały wcześniej żadnych doświadczeń zawodowych poza działaniami podejmowanymi w związku ze studiami lub  programowaniem we własnym zakresie. Dzięki ogromnemu zaangażowaniu i chęci uczenia się, zespół wykorzystał w pełni możliwości, jakie stwarzał program praktyk – a my przekonaliśmy się, że w tych osobach tkwi ogromny potencjał. Dlatego zdecydowaliśmy się kontynuować współpracę z chłopakami.</p>
<h3>Co dalej?</h3>
<p>Aplikacja wytworzona przez praktykantów przygotowywana jest do wdrożenia, a my implementujemy kolejne funkcjonalności. Praktykanci dołączyli do innych zespołów projektowych, gdzie będą mieli okazję zapoznać się z kolejnymi technologiami i pracować z doświadczonymi programistami.</p>
<p>The post <a href="https://www.hltech.com/en/tech-en/the-internship-programme-from-the-programmers-perspective/">The internship programme from the programmer’s perspective</a> appeared first on <a href="https://www.hltech.com/en/">HL Tech</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
