<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tom Andrews</title>
    <description>The latest articles on DEV Community by Tom Andrews (@tgandrews).</description>
    <link>https://dev.to/tgandrews</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F170863%2F7b764bf9-e153-49c2-b3de-3d9f358b16f8.jpeg</url>
      <title>DEV Community: Tom Andrews</title>
      <link>https://dev.to/tgandrews</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tgandrews"/>
    <language>en</language>
    <item>
      <title>Rounding at the start</title>
      <dc:creator>Tom Andrews</dc:creator>
      <pubDate>Sat, 06 Feb 2021 22:26:03 +0000</pubDate>
      <link>https://dev.to/tgandrews/rounding-at-the-start-433j</link>
      <guid>https://dev.to/tgandrews/rounding-at-the-start-433j</guid>
      <description>&lt;p&gt;At a recent consulting client I was working on fixing a few issues with their in app calendar. The calendar has all of the usual features such as adding short, all day events and then displaying them in a calendar view allowing day, 3 day or week views. This is a surprisingly difficult endeavour in both the front end and back end.&lt;/p&gt;

&lt;p&gt;One of the issues was that all day events were appearing on the wrong day. So adding an all day event on Tuesday would create an all day event starting on Monday and lasting two days. Given this it sounded like something weird was happing with the starting date. But given that it now spread two days I was very confused as I expected an all day event to only store the start date and the length. So how was the length changing? Also, speaking to a colleague who had looked into this before they said they had spent some time before and narrowed down the location of the issue to the database. But that sounded crazy as we are using MS SQL so a very well battle tested database and we shouldn’t be doing anything weird. So I thought it would be best to take a fresh look and start from the beginning.&lt;/p&gt;

&lt;p&gt;So the first thing to do was to try and recreate it locally. This was luckily very easy and worked - I mean didn’t work - exactly as described. I tried a few different versions of all day events. But they all had the same issue. So we needed to start the actual work.&lt;/p&gt;

&lt;p&gt;Digging into the network transfer from the UI to the backend you could see that all events were the same sending a start date and time and and ending date and time. For the all day event the event started at midnight and ended at one second before midnight. I could see the correct values were being sent for the all day event but this API didn’t match my expectations. The response from the API also had the invalid start date but the time was still correct and it returned the events ID.&lt;/p&gt;

&lt;p&gt;Now, into the API. This is a calendar specific microservice so luckily wasn’t too big. Also its pretty straightforward using the patterns found throughout the rest of the microservices -&lt;a href="https://nestjs.com/"&gt;NestJS&lt;/a&gt; and &lt;a href="https://typeorm.io/#/"&gt;TypeORM&lt;/a&gt;. So it was easy to see that how the data flowed through the application and how it was saved. The TypeORM entity defined which table the data lived in so I opened up&lt;a href="https://dbeaver.io/"&gt;DBeaver&lt;/a&gt; and queried the events table and could see for the all day events I had created were exactly like we saw in the UI - they had the wrong date.&lt;/p&gt;

&lt;p&gt;So either, the problem lies in either what the API’s input, our processing or what we are sending to the DB. I added logging at the first point we receive the start date time and the place where we pass it to TypeORM to save. At both of those places it was correct! Could it really be MS SQL?!&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/5b27edb49ba984f70074cceb81de5e46/b4294/wat.jpg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GAgQTjGk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://tomandrews.co.uk/static/5b27edb49ba984f70074cceb81de5e46/1c72d/wat.jpg" alt="WAT duck" title="WAT duck"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So there is still one layer between us and MS SQL - TypeORM. Now TypeORM is a pretty popular library in of itself - not as battle tested as MS SQL but I definitely wouldn’t expect it to be the source of the issue but the logging proves it isn’t us. So I googled it and found an issue that matched it exactly &lt;a href="https://github.com/typeorm/typeorm/issues/3202"&gt;node-mssql v5 incorrectly stores Dates&lt;/a&gt;. So the database adapter that TypeORM relies on &lt;a href="https://www.npmjs.com/package/mssqlgit"&gt;mssql&lt;/a&gt; it had an issue where it would incorrectly round dates within the first 3 seconds of the day&lt;a href="https://github.com/typeorm/typeorm/issues/3202#issuecomment-706762605"&gt;brilliantly deduced&lt;/a&gt; by&lt;a href="https://github.com/imnotjames"&gt;@imnotjames&lt;/a&gt;. The &lt;a href="https://github.com/tediousjs/tedious/pull/1023"&gt;mssql issue&lt;/a&gt;had been resolved but the newly released version 7 alphas of mssql were not compatible with TypeORM.&lt;/p&gt;

&lt;p&gt;So this meant that we had to tackle this on two fronts. Firstly we needed to put a workaround in to the calendar microservice so that it would take any datetime this was pretty straightforward. A small PR to wrap any save of a date in the calendar service in a function that checked if the datetime was close to midnight and then add a minute. Secondly I created a &lt;a href="https://github.com/typeorm/typeorm/pull/7264"&gt;PR&lt;/a&gt;that fixed the pretty minor compatibility issues between TypeORM and mssql v7.&lt;/p&gt;

&lt;p&gt;This morning I can happily say that the PR has been merged and so will be in the next release of TypeORM and we can remove the workaround in the calendar micro service.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/qngUbAbaWRuFy/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/qngUbAbaWRuFy/giphy.gif" alt="Happy Dance"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’m pretty happy with how this went and got to dig into the internals of some pretty core parts of our app and the libraries we depend on learning a lot in the process. The fact this is all open and I have the ability to fix issues that we encounter is really empowering. But lets hope I don’t have to do it too often 🤞&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Scripting projects</title>
      <dc:creator>Tom Andrews</dc:creator>
      <pubDate>Tue, 22 Sep 2020 22:11:00 +0000</pubDate>
      <link>https://dev.to/tgandrews/scripting-projects-3hmb</link>
      <guid>https://dev.to/tgandrews/scripting-projects-3hmb</guid>
      <description>&lt;p&gt;Over my career the move from monolithic applications to micro-services has come with a number ofbenefits. In my experience some of the best features are that they can reduce overall complexity,enforce design discipline, scale much better to larger applications (and teams) and allow for moreappropriate technical choices. One of the problems they bring is that the developer’s environmentcan get a lot more complex. Each service you require to run the app is an additional bit ofcomplexity as each service needs certain dependencies installing, needs the correct environmentvariables, the correct branch etc. Then once you’ve got them running you need to be able to accesseach one so you can make the necessary change for your work - you might even need to be able makechanges to multiple services ones in one go.&lt;/p&gt;

&lt;p&gt;As a new developer working on one of these applications can be a bit of a nightmare. You often needa decent amount of the services running every time you want to start work. You need the servicesstarted, you might need the tests running as well and then you’ll need a terminal in the rightdirectory as well. For years I’ve been doing this all manually - log on in the morning and spenda couple of minutes getting everything started or if its a specific laptop just for this projectthen hope everything survived the wake from sleep and hope I don’t need to restart it ever! As youcan see this was never sustainable especially when I started working on a mature project that pushedthis much further than I have seen before.&lt;/p&gt;

&lt;p&gt;For this mature project to run the public facing website required a dozen services and a multi-dayset up process using internal tools to import the necessary data. This was also running on my laptopso when I wanted to stop working on the project and work on home projects in the evening I needed toable to stop all of these services and then start them all when I started work the next morning.&lt;/p&gt;

&lt;p&gt;To solve this problem I chatted firstly with the existing developers and they were using acombination of &lt;a href="https://www.iterm2.com/"&gt;iterm&lt;/a&gt; and &lt;a href="https://www.gnu.org/software/screen/screen.html"&gt;screen&lt;/a&gt;.All the solutions were very custom to their individual developer and contained many caveats so Icouldn’t take them wholesale and just get going. So I needed to build my own. From a technology the&lt;code&gt;iterm&lt;/code&gt; solution was not ideal, the scripting seemed very complex so might work for the currentproject but would need a custom solution for each project. &lt;code&gt;screen&lt;/code&gt; looked much better but I havebeen listening to a lot of &lt;a href="https://www.bikeshed.fm/"&gt;podcasts from people in the ruby community&lt;/a&gt;who have heavily been advocating &lt;a href="https://github.com/tmux/tmux/wiki"&gt;tmux&lt;/a&gt; which I have noodled within the past (for adding tabs to &lt;a href="https://github.com/alacritty/alacritty"&gt;alacritty&lt;/a&gt;). So if I’mgoing to have to learn a tool I think its best I use the one I am starting from a better positionespecially as I didn’t have a lot of time to do this.&lt;/p&gt;

&lt;p&gt;So I ended creating a pretty small but useful script for the project that would start all theservices and bring them up in their own tabs and two panes for each application - one running it theother just in the correct directory for &lt;code&gt;git&lt;/code&gt; commands, running tests etc. There is also a killcommand to bring it all back down again so that there is nothing left running when I have finishedfor the day. This solution has worked well enough and I’ve really enjoyed living without any &lt;code&gt;iterm&lt;/code&gt;tabs and just living in &lt;code&gt;tmux&lt;/code&gt;. So much so that I’ve also started creating similar scripts for allmy projects. Even if they don’t require multiple services, just having a nice consistent way ofgoing into the project and running a single command its all up and running is really nice. Thisspace needs a lot of work there are a few things that don’t work well &lt;em&gt;yet&lt;/em&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Starting a dozen or more services starts them ALL at the same time which means that your CPU isoverwhelmed for those first couple of minutes&lt;/li&gt;
&lt;li&gt;A proper way of defining shutdown commands for each of the services rather than just killingeverything seems necessary&lt;/li&gt;
&lt;li&gt;Some sort of priority order would also be nice but I would hope most services should be prettyresilient.&lt;/li&gt;
&lt;li&gt;Integration of existing tooling like &lt;a href="https://docs.docker.com/compose/"&gt;docker compose&lt;/a&gt; etcwould be nice so that you don’t have to define too much for each app.&lt;/li&gt;
&lt;li&gt;Allowing a user to customise what additional things every app gets or defining some sort ofstandard layout would be nice as people work in different ways and this is defining the servicesand how to run the tools not forcing a workflow.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here are my current versions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The one that started it all &lt;a href="https://github.com/tgandrews/dp-start"&gt;dp-start&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A simple version for an in progress dynamodb ORM called &lt;a href="https://github.com/tgandrews/dynamodb2/blob/rewrite/start.sh"&gt;dynamodb2&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Accessibility - VoiceOver iOS anchor bug</title>
      <dc:creator>Tom Andrews</dc:creator>
      <pubDate>Sat, 15 Aug 2020 18:50:03 +0000</pubDate>
      <link>https://dev.to/tgandrews/accessibility-voiceover-ios-anchor-bug-hg0</link>
      <guid>https://dev.to/tgandrews/accessibility-voiceover-ios-anchor-bug-hg0</guid>
      <description>&lt;p&gt;An interesting thing about accessibility work on the web is that they bring a completely newmechanism for interacting with webpages - the rotor. The rotor is a mechanism for jumping todifferent parts of the pages by the type of the item, this could be links, headings, tables etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/9c8d8d7a86d5ede0e17bf54713fbac69/09262/rotor-example.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wboYy5EA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://tomandrews.co.uk/static/9c8d8d7a86d5ede0e17bf54713fbac69/fcda8/rotor-example.png" alt="Example of heading rotor with VoiceOver for Mac and Chrome on a blog post for tomandrews.co.uk" title="Example of heading rotor with VoiceOver for Mac and Chrome on a blog post for tomandrews.co.uk"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The thing about the rotor is that it removes the context you would get normally in a page so forexample if you have download links for different documents in different formats you would have agrouping containing the title of the document and then the different download links just containingthe format e.g. &lt;code&gt;xls&lt;/code&gt;, &lt;code&gt;csv&lt;/code&gt; etc.&lt;/p&gt;

&lt;p&gt;When this example is pulled out into a rotor you get a list of links saying &lt;code&gt;xls&lt;/code&gt;, &lt;code&gt;csv&lt;/code&gt; over andover again which is really not helpful and would be super confusing to the user.&lt;/p&gt;

&lt;p&gt;The solution is usually to add some additional context that only the screen reader would notice.This content is hidden using a &lt;em&gt;very&lt;/em&gt; hackish CSS class usually called something like &lt;code&gt;sr-only&lt;/code&gt; or&lt;code&gt;visuallyhidden&lt;/code&gt;. These classes are very complex and fraught with danger. If you want some lightreading there is an &lt;a href="https://github.com/h5bp/main.css/issues/12"&gt;enlightening github issue&lt;/a&gt; aboutthe one in html 5 boilerplate. There is also &lt;a href="https://github.com/w3c/csswg-drafts/issues/560"&gt;another interesting github issue&lt;/a&gt;where the amazing &lt;a href="https://twitter.com/SaraSoueidan"&gt;Sara Soueidan&lt;/a&gt; raises the possibility ofgetting this built in to CSS all the way back in 2016. This seems like a no brainer to me given thatlots of people are having to add this in user space and that the benefits of a stable solution forusers using a screen would be immense.&lt;/p&gt;

&lt;p&gt;So basically we were bound to find places where adding &lt;code&gt;visuallyhidden&lt;/code&gt; elements was not going towork and here is one of them.&lt;/p&gt;

&lt;p&gt;On VoiceOver for iOS (v13.6.1) the &lt;code&gt;visuallyhidden&lt;/code&gt; text is ignored when added inside of a link sofor example from an article page&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;a href="/download?id=123&amp;amp;format=xls"&amp;gt;
  &amp;lt;span class="visuallyhidden"&amp;gt;Download table A as&amp;lt;/span&amp;gt;xls
&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It would read just &lt;code&gt;xls&lt;/code&gt; and only show &lt;code&gt;xls&lt;/code&gt; in the rotor. Which is very confusing when on anarticle with lots of tables!&lt;/p&gt;

&lt;p&gt;So after some digging I found &lt;a href="https://gist.github.com/nickcolley/19b80ed24d0364cfd3afd3b1b49c4014"&gt;some research from Nick Colley of the gov.uk frontend team&lt;/a&gt;who had researched this thoroughly. The best solution was to give up on &lt;code&gt;visuallyhidden&lt;/code&gt; and switchto using &lt;code&gt;aria-label&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So it became:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;a href="/download?id=123&amp;amp;format=xls" aria-label="Download table A as xls"&amp;gt;
  xls
&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Whilst the change wasn’t drastic the complexity of getting to the solution and finding out how toresolve it was the tricky part. Additionally I did a small amount of research to how well this wassupported in JAWS - the last major screen reader I don’t have access to. In my search I came acrossa tool similar to &lt;a href="https://caniuse.com/"&gt;Can I Use&lt;/a&gt; but for screen readers called &lt;a href="https://www.powermapper.com/tests/screen-readers/"&gt;Screen reader reliability by PowerMapper&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Accessibility - Running NVDA on a Mac</title>
      <dc:creator>Tom Andrews</dc:creator>
      <pubDate>Fri, 14 Aug 2020 17:52:03 +0000</pubDate>
      <link>https://dev.to/tgandrews/accessibility-running-nvda-on-a-mac-m1c</link>
      <guid>https://dev.to/tgandrews/accessibility-running-nvda-on-a-mac-m1c</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;For the past month I’ve been work on an accessibility project. There are three major screen readers&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.freedomscientific.com/products/software/jaws/"&gt;JAWS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nvaccess.org/"&gt;NVDA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.apple.com/uk/accessibility/mac/vision/"&gt;VoiceOver&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Given that JAWS is pretty pricey and has a steep learning curve I have mostly been focussing ongetting everything running well on NVDA and VoiceOver and getting support from other members of theteam to check JAWS.&lt;/p&gt;

&lt;p&gt;For the past 8 years I have been working on a Mac. Whilst there is VoiceOver for Mac (which is notthe same as VoiceOver on iOS) NVDA is not available and only runs on Windows. To get this runningrequired a bit of work that I couldn’t find documented anywhere else. So here it is for you andfuture me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instructions
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The first thing is to get a copy of Windows so that we can run in VirtualBox locally. LuckilyMicrosoft provide &lt;a href="https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/"&gt;Window 10 images&lt;/a&gt;for testing browsers on Windows. They expire after 3 months but saves £150.&lt;/li&gt;
&lt;li&gt;Once you have Windows then you also need &lt;a href="https://www.virtualbox.org/"&gt;VirtualBox&lt;/a&gt;. If you havehomebrew you can install it with &lt;code&gt;brew cask install virtualbox&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Now you need to load and boot the virtual machine.&lt;/li&gt;
&lt;li&gt;Download and install &lt;a href="https://www.virtualbox.org/wiki/Downloads"&gt;VirtualBox extension pack&lt;/a&gt; intothe VM.&lt;/li&gt;
&lt;li&gt;Stop the VM.&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Alter the VM Settings and under the audio tab.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enable Audio&lt;/li&gt;
&lt;li&gt;Set the &lt;code&gt;Host Audio Driver&lt;/code&gt; to &lt;code&gt;CoreAudio&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Set the &lt;code&gt;Audio Controller&lt;/code&gt; to &lt;code&gt;Intel HD Audio&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Under extended features ensure that &lt;code&gt;Enable Audio Output&lt;/code&gt; is checked

&lt;ol&gt;
&lt;li&gt;Boot the VM and the audio should be working now. You can prove it by visiting YouTube or somethingsimilar.&lt;/li&gt;
&lt;li&gt;Now, within the VM &lt;a href="https://www.nvaccess.org/download/"&gt;download NVDA&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Install NVDA&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now you can use a browser and see how it is read by NVDA.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optional extra - Getting NVDA to read multiple languages correctly
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;With NVDA running you can right click on it running in the task bar and select &lt;code&gt;Preference&lt;/code&gt; &amp;gt;&lt;code&gt;Settings&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Under the &lt;code&gt;Speech&lt;/code&gt; section you need to set the &lt;code&gt;Synthesizer&lt;/code&gt; to &lt;code&gt;eSpeak NG&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Now it should respect the element and html language attribute to determine how to read the text.&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Zoomed images on iOS</title>
      <dc:creator>Tom Andrews</dc:creator>
      <pubDate>Fri, 28 Feb 2020 20:02:03 +0000</pubDate>
      <link>https://dev.to/tgandrews/zoomed-images-on-ios-1n75</link>
      <guid>https://dev.to/tgandrews/zoomed-images-on-ios-1n75</guid>
      <description>&lt;p&gt;I’ve been working on a wedding website for my upcoming wedding to my amazing fiancé Elina in August.The website is intended to be a place where we can share the details and the guests can RSVP easily. Not flying to far away fromthe current design trends we have made quite heavy use of parallax scroll. However it has been a fewyears since I’ve done this and I can see now you can do simple and even some more complex parallaxscrolling in pure CSS instead of JS listening to scroll events which unless you are careful can getjanky quite quickly.&lt;/p&gt;

&lt;p&gt;Everything was going smoothly. I picked up &lt;a href="https://sizzy.co/"&gt;Sizzy&lt;/a&gt; which is really amazing forseeing your site at multiple resolutions very easily. Now everything is done - the parallax is all niceand smooth even with a throttled CPU in dev tools. I push it to a PR and the &lt;a href="https://netlify.com"&gt;netlify&lt;/a&gt; preview loads.I confidently send the link to Elina and she goes&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Uh… what is with the images? Are they meant to look like this?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I load it up on my phone and see they do look crap - they are zoomed in awfully.&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/91f821f449de3f8b68880f578bc82828/1c72d/blurry-images.jpg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JV3k1u0y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://tomandrews.co.uk/static/91f821f449de3f8b68880f578bc82828/1c72d/blurry-images.jpg" alt="Blurry images" title="Blurry images"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I do think fire safety is important but I’m not sure it should be the first thingpeople can &lt;em&gt;kind of&lt;/em&gt; read on a wedding invitation website. That’s just not good UX. 💩&lt;/p&gt;

&lt;p&gt;So 10 minutes of googling later I find out that &lt;a href="https://caniuse.com/#search=background-attachment"&gt;iOS have issues with&lt;/a&gt; &lt;code&gt;background-attachment: fixed&lt;/code&gt; in combination with &lt;code&gt;background-size: cover&lt;/code&gt;. Which is a little annoying but I guess this is what web development is all about.&lt;/p&gt;

&lt;p&gt;So I decided to drop it on iOS and then once they have fixed the issue we can re-enable it.&lt;/p&gt;

&lt;p&gt;The quick fix to disable it was this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@supports (-webkit-touch-callout: none) {
  background-attachment: initial;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This media query targets only mobile safari devices and sets the &lt;code&gt;background-attachment&lt;/code&gt; as if none was set. This fixed the issue and now the wedding website can go out and collect RSVPs whilst Elina and I go back to debating more important things for the wedding.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Testing tokens</title>
      <dc:creator>Tom Andrews</dc:creator>
      <pubDate>Sat, 02 Nov 2019 20:44:03 +0000</pubDate>
      <link>https://dev.to/tgandrews/testing-tokens-15go</link>
      <guid>https://dev.to/tgandrews/testing-tokens-15go</guid>
      <description>&lt;p&gt;I’ve recently started working on a new project that makes heavy use of &lt;a href="https://jwt.io/"&gt;JWT&lt;/a&gt;. Thishas meant that I’ve been wrirting a decent number of tests to ensure that the token contains thecorrect contents and will expire at the correct time. A lot of the tests started looking like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { iat: _iat, exp, ...contents } = jwt.decode(token)
expect(contents).toMatchObject(expectedContents)
expect(exp).toEqual(Math.floor(Date.now() / 1000) + 60 * 60)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As you can see this is very verbose and hides the intention of the test. It would be great if we could write a much cleaner test. Like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;expect(token).toBeTokenContaining(expectedContents)
expect(token).toBeTokenExpiringIn("1h")
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As we using &lt;a href="https://jestjs.io"&gt;Jest&lt;/a&gt; there is a way of &lt;a href="https://jestjs.io/docs/en/expect#expectextendmatchers"&gt;extending&lt;/a&gt; it to add ourown matchers. So I created a new npm package that adds a couple of custom assertions for working with JWT. It is called &lt;a href="https://www.npmjs.com/package/jest-expect-jwt"&gt;jest-expect-jwt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was an overall great experience in extending jest by following the docs. The only complexity came from the integration with typescript and ensuring that the types for the new assertions were detected. When using it in a test it would execute successfully but would show an error in vscode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Property 'toBeTokenContaining' does not exist on type 'JestMatchersShape&amp;lt;Matchers&amp;lt;void, string&amp;gt;, Matchers&amp;lt;Promise&amp;lt;void&amp;gt;, string&amp;gt;&amp;gt;'.ts(2339)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I eventually found a solution by reading the docs for &lt;a href="https://github.com/jest-community/jest-extended#typescript"&gt;jest-extended&lt;/a&gt; and it should that you need to import the types into a &lt;code&gt;global.d.ts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But either way it will nice writing better tests. And you can too &lt;a href="https://www.npmjs.com/package/jest-expect-jwt"&gt;jest-expect-jwt&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
