きり丸の技術日記

技術検証したり、資格等をここに残していきます。

リンク先の目的の段落を開いたり、強調した状態のURLのパーツ(URIフラグメント)

URLに記述していてもサーバにデータは送らない箇所があり、それをURIフラグメントと呼びます。具体的には次のURLのうち、#以降の#:~:text=nainaistarを指します。

https://nainaistar.hatenablog.com/#:~:text=nainaistar

URIフラグメントは、リンク先のWebページの特定情報の場所を指定するために用いられます。さきほどのURLをChrome80以降のバージョンで開くと、「nainaistar」という文字列がハイライトされている状態で開くことが分かります。

今回の記事では、自分なりにURIフラグメントについて調べたことを残します。

環境

  • Chrome
    • 80以降

ユースケース

  • 巨大なヘルプページから目的の段落を開いた状態で遷移させる

母国語で書かれたページなら巨大なヘルプページでもすぐに調べられるのですが、基本的には英語で記載されていることが多いです。参考資料として共有されたリンクを渡されても、それが英語の場合に大事な箇所を即座に把握することは難しいです。

そのような時に、目的の記述を記載した状態でページを開ければ、共有後のコストが大きく減らせます。

前提

リンクを開いたタイミングでのリソースを検索しているようです。そのため、Twitterのタイムライン・SPA等々のリンクを開いてから後でレンダリングをするページでは、URIフラグメントがうまく効かないようです。

IDやName属性

HTMLのID属性を指定できます。こちらについては、RFC 5147に定義されています。

そのまま#の後にそのままID属性を付与してください。

※ 例示として適切なページが見つからなかったのでイメージです。
#kirimaru
#{ID属性}

一応、RFC 5147にはName属性も識別するとは記載されているのですが、ブラウザ側が対応しているかどうかまでは確認できませんでした。

テキスト(Chrome80以降)

Chrome80以降であれば#の後に:~:text=と記述すると、特に属性がついていない状態でもハイライトを付与した状態で目的の項目を開かせることができます。ただし、一番初めにヒットしたものだけです。複数ヒットするような文言で作成しないようにしましょう。

次のリンクを開くと、RFC 5147のどこにURIフラグメントの識別対象が記載しているかが分かるでしょう。

https://datatracker.ietf.org/doc/html/rfc5147#:~:text=identified%20by%20the%20value%20of%20a%20

prefixやsuffix等を使用して、さらに絞り込めるようにできるようです。

# 定義?
:~:text=[prefix-,]textStart[,textEnd][,-suffix]

Chrome拡張

この機能は便利ですが、毎回#の後に:~:text=と記述する手間があります。

「Link to Text Fragment」というChrome拡張があります。こちらを導入し、共有したいテキストを選択した状態で右クリックすると「Copy Link To Selected Text」のメニューが出現します。このメニューを選択すると自動で#:~:text={選択した文字}のリンクが付与できるので、非常に便利です。

その他

  • YouTubeでは#t=3m25sと付与すると、動画が3分25秒経過した状態で再生できます。
  • Google スプレッドシートでは、フィルタ設定でgidを設定したったり、セルに対してのリンクでrangeを付与できます。

その他でも便利になるようにURIフラグメントを拡張しているページはあるでしょうが、調査できておりませんので、コメントで教えていただけるとうれしいです。

終わりに

URIフラグメントは「フラグメント識別子」「アンカー」とも呼ばれるようです。

サーバにURIフラグメントが送られていないことはソースコードでも確認していたのですが、リダイレクトの際に無くなったりするんですかね…。はてなブログでhttpsからhttpにリダイレクトされているときには、URIフラグメントが無くなったりしていないので、この辺はブラウザ側でいい感じに保持しているのかもしれません。

かなり浅い知識で記載していますので、この記事をフックに詳細な内容を調べていただければと思います。

参考情報

文字列結合でも日付を数字ではなく目的のフォーマットで表示する(MM/DD)(Excelとスプレッドシート両方とも可)

Excelとスプレッドシートの両方でも活用できる方法です。


「04/18」と表示したい場合、セルの書式設定を変更して目的のフォーマットで表示するのが一般的だと思います。

しかし、「【日報】きり丸 04/18」のような固定文言 + 今日の日付をCONCAT関数を使用して作成したい時、「【日報】きり丸 44669」と数字で表示されてしまいます。セルで「04/18」と表示されているものを参照しても、同様の結果となってしまいます。

今回はそれを回避して、「【日報】きり丸 04/18」を表示できる方法を記載します。

環境

  • Excel
    • Microsoft® Excel® 2019 MSO (バージョン 2203 ビルド 16.0.15028.20178) 64 ビット
  • SpreadSheet
    • 2022/04/18 時点

対応

TEXT関数を使用します。

TEXT(値, フォーマット)と使用することで、期待するフォーマットに変換できます。

※ 画像は01(ゼロイチ)ではなく、セル番地のO1(オーのイチ)です。

動作確認をする際は次のコマンドで確認してみてください。

# うまくいく方法
=CONCATENATE("【日報】きり丸 ", TEXT(today(),"MM/DD"))

# うまくいかない方法
=CONCATENATE("【日報】きり丸 ", today())

備考

CONCATENATE関数は3つ以上結合するときに使用する関数です。

today()関数は実行日付となる値を返す関数です。

終わりに

MOSを持っている人にとっては当然の機能かもしれませんが、どうやっても日付が数字になってしまうので、非常に困っていました。

最近、勤怠をメールで送るようにしているのですが、スプレッドシートで送るようにしているので、このメールタイトルとなる「【日報】きり丸 04/18」が表示できずにハマっていました。

普段使わない機能だからこそ、ちょっと難しいですね。

参考情報

Node.jsで記述されたPlaywrightの実行環境をDockerで用意する

職場でE2EツールとしてPlaywrightを使用しており、ソースコードをPythonで書いています。そのときのPlaywrightの環境構築手順はこちら

ただ、Playwright単体はどの言語で書かれても問題ないものの、どうしてもテストライブラリ等のエコシステムは言語により得意不得意があります。フロントエンドはNode.jsで書かれることが多いのか、Playwrightの公式に記載されているテストの書き方はNode.jsが一番充足しています。

作りこめばどの言語でも同じことはできるとは分かっているものの、環境構築に勉強のコストを掛けたくないので、Node.jsで学ぶことにしました。

今回の記事では、Node.jsが動くPlaywrightのDocker環境を用意します。

環境

  • Node.js
    • v14.17.6
  • Playwright
    • 1.14.1
  • GitHub Codespaces
    • 2021/09/20時点

ゴール

  • Playwrightの実行環境をDockerで用意する
  • Node.jsで作成したシナリオを実行する
  • VS Codeの.devcontainerが動くようにする

書かないこと

  • GitHub Codespacesの使い方

手順

VS Codeのdevcontainerで動かす下準備をする

.devcontainerディレクトリを作成します。

.devcontainerディレクトリの配下に、devcontainer.jsonを作成します。

devcontainer.jsonに次の記述を追加して、指定のDockerfileを使用するようにします。

{
  "build": { "dockerfile": "Dockerfile" },
}

Dockerfileを準備する

.devcontainerディレクトリの配下にDockerfileを作成します。

WebDriver等が入っているDockerイメージをMicrosoftから提供されているので利用します。Node.jsで動く状態ではありません。

ですので、Dockerfile内でNode.jsを環境構築する必要があります。

ベースにMicrosoftから提供されているPlaywrightのDockerイメージのFROM mcr.microsoft.com/playwright:focalを使用します。次に、ベースにnpmをインストールします。現状のLTSは12, 14ですので、14に合わせています。環境構築時の最新のバージョンを指定するようにしてください。

なお、ホームディレクトリの修正やマウント設定等が面倒なため、DockerfileではPlaywrightをNode.jsで動かすためのパッケージはインストールしません。

FROM mcr.microsoft.com/playwright:focal
RUN apt-get -y update
RUN apt-get install -y \
    curl \
    gnupg
# 最新のLTSを確認すること
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash -
RUN apt-get install -y nodejs
RUN npm install npm@latest -g

DevContainerを再起動する

GitHub Codepacesで上の作業をしていない場合はスキップしてください。

DevContainerで使用するDockerfileを変更しているため、コンテナをリビルドする必要があります。

Ctrl + Shift + P(または、Shift + Command + P)でヘッダに入力欄が表示されるので、Codespaces: Rebuild Containerを実行します。

Node.jsでPlaywrightを動かすパッケージをインストールする

次のコマンドを実行することで、Node.jsでPlaywrightを動かすパッケージをインストールします。

コマンドを実行したディレクトリでしか実行できませんので注意してください。

npm install -D @playwright/test
npx playwright install

シナリオを準備する

あとは、Playwrightの標準的な使い方になります。

testディレクトリを作成し、sample.spec.tsファイルを作成します。中身はチュートリアルと同じです。

import { test, expect } from '@playwright/test';

test('basic test', async ({ page }) => {
  await page.goto('https://playwright.dev/');
  const title = page.locator('.navbar__inner .navbar__title');
  await expect(title).toHaveText('Playwright');
});

実行する

npx playwright testを実行すると、testsディレクトリのテストコードが実行されます。

ここで動作しない場合は何か問題が発生していますので、再度やり直してください。

ソースコード

終わりに

Pythonで作りこんでいましたが、スナップショットテスト等が面倒で結局Node.jsで作りこむことにしました。

正直、Pythonの場合はpipするだけで簡単に構築できたのですが、Node.jsがベースではないイメージでNode.jsを動かそうとすると面倒でした。ほかにも、Dockerfileでnpm installをしようとするとTracker "idealTree" already existsが発生してしまうので、回避したらセットアップが余計に面倒になったのでやめました。

本来であればすべての環境構築をDockerfileに詰め込んで、起動時にマウント設定等を行った方がいいですが、DevContainerの仕様がよく分からなかったので現状はこのように運用しています。

ぜひ、こちらで使ってみてください。

参考情報

類似記事